aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/main/src/index.ts')
-rw-r--r--packages/main/src/index.ts72
1 files changed, 41 insertions, 31 deletions
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts
index 1f80e44..02e6cda 100644
--- a/packages/main/src/index.ts
+++ b/packages/main/src/index.ts
@@ -19,9 +19,9 @@
19 * SPDX-License-Identifier: AGPL-3.0-only 19 * SPDX-License-Identifier: AGPL-3.0-only
20 */ 20 */
21 21
22import { arch } from 'os'; 22import { arch } from 'node:os';
23import { join } from 'path'; 23import path from 'node:path';
24import { URL } from 'url'; 24import { URL } from 'node:url';
25 25
26import { 26import {
27 ServiceToMainIpcMessage, 27 ServiceToMainIpcMessage,
@@ -101,11 +101,14 @@ app.setAboutPanelOptions({
101 version: '', 101 version: '',
102}); 102});
103 103
104// eslint-disable-next-line unicorn/prefer-module -- Electron apps run in a commonjs environment.
105const thisDir = __dirname;
106
104function getResourcePath(relativePath: string): string { 107function getResourcePath(relativePath: string): string {
105 return join(__dirname, relativePath); 108 return path.join(thisDir, relativePath);
106} 109}
107 110
108const baseUrl = `file://${__dirname}`; 111const baseUrl = `file://${thisDir}`;
109function getResourceUrl(relativePath: string): string { 112function getResourceUrl(relativePath: string): string {
110 return new URL(relativePath, baseUrl).toString(); 113 return new URL(relativePath, baseUrl).toString();
111} 114}
@@ -117,15 +120,15 @@ const serviceInject: WebSource = {
117 url: getResourceUrl(serviceInjectRelativePath), 120 url: getResourceUrl(serviceInjectRelativePath),
118}; 121};
119 122
120let mainWindow: BrowserWindow | null = null; 123let mainWindow: BrowserWindow | undefined;
121 124
122const store = createMainStore(); 125const store = createMainStore();
123init(store) 126init(store)
124 .then((disposeCompositionRoot) => { 127 .then((disposeCompositionRoot) => {
125 app.on('will-quit', disposeCompositionRoot); 128 app.on('will-quit', disposeCompositionRoot);
126 }) 129 })
127 .catch((err) => { 130 .catch((error) => {
128 log.log('Failed to initialize application', err); 131 log.log('Failed to initialize application', error);
129 }); 132 });
130 133
131const rendererBaseUrl = getResourceUrl('../renderer/'); 134const rendererBaseUrl = getResourceUrl('../renderer/');
@@ -136,7 +139,7 @@ function shouldCancelMainWindowRequest(url: string, method: string): boolean {
136 let normalizedUrl: string; 139 let normalizedUrl: string;
137 try { 140 try {
138 normalizedUrl = new URL(url).toString(); 141 normalizedUrl = new URL(url).toString();
139 } catch (_err) { 142 } catch {
140 return true; 143 return true;
141 } 144 }
142 if (isDevelopment) { 145 if (isDevelopment) {
@@ -233,7 +236,7 @@ async function createWindow(): Promise<unknown> {
233 'from webContents', 236 'from webContents',
234 event.sender.id, 237 event.sender.id,
235 ); 238 );
236 return null; 239 throw new Error('Invalid IPC call');
237 } 240 }
238 return getSnapshot(store.shared); 241 return getSnapshot(store.shared);
239 }); 242 });
@@ -262,22 +265,22 @@ async function createWindow(): Promise<unknown> {
262 .then((data) => { 265 .then((data) => {
263 serviceInject.code = data; 266 serviceInject.code = data;
264 }) 267 })
265 .catch((err) => { 268 .catch((error) => {
266 log.error('Error while reloading', serviceInjectPath, err); 269 log.error('Error while reloading', serviceInjectPath, error);
267 }) 270 })
268 .then(() => { 271 .then(() => {
269 browserView.webContents.reload(); 272 browserView.webContents.reload();
270 }) 273 })
271 .catch((err) => { 274 .catch((error) => {
272 log.error('Failed to reload browserView', err); 275 log.error('Failed to reload browserView', error);
273 }); 276 });
274 break; 277 break;
275 default: 278 default:
276 log.error('Unexpected action from UI renderer:', actionToDispatch); 279 log.error('Unexpected action from UI renderer:', actionToDispatch);
277 break; 280 break;
278 } 281 }
279 } catch (err) { 282 } catch (error) {
280 log.error('Error while dispatching renderer action', rawAction, err); 283 log.error('Error while dispatching renderer action', rawAction, error);
281 } 284 }
282 }); 285 });
283 286
@@ -285,9 +288,18 @@ async function createWindow(): Promise<unknown> {
285 webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch); 288 webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch);
286 }); 289 });
287 290
288 ipcMain.handle(ServiceToMainIpcMessage.ApiExposedInMainWorld, (event) => 291 ipcMain.handle(ServiceToMainIpcMessage.ApiExposedInMainWorld, (event) => {
289 event.sender.id === browserView.webContents.id ? serviceInject : null, 292 if (event.sender.id !== browserView.webContents.id) {
290 ); 293 log.warn(
294 'Unexpected',
295 ServiceToMainIpcMessage.ApiExposedInMainWorld,
296 'from webContents',
297 event.sender.id,
298 );
299 throw new Error('Invalid IPC call');
300 }
301 return serviceInject;
302 });
291 303
292 browserView.webContents.on('ipc-message', (_event, channel, ...args) => { 304 browserView.webContents.on('ipc-message', (_event, channel, ...args) => {
293 try { 305 try {
@@ -303,8 +315,8 @@ async function createWindow(): Promise<unknown> {
303 log.error('Unknown IPC message:', channel, args); 315 log.error('Unknown IPC message:', channel, args);
304 break; 316 break;
305 } 317 }
306 } catch (err) { 318 } catch (error) {
307 log.error('Error while processing IPC message:', channel, args, err); 319 log.error('Error while processing IPC message:', channel, args, error);
308 } 320 }
309 }); 321 });
310 322
@@ -316,9 +328,7 @@ async function createWindow(): Promise<unknown> {
316 328
317 browserView.webContents.session.webRequest.onBeforeSendHeaders( 329 browserView.webContents.session.webRequest.onBeforeSendHeaders(
318 ({ url, requestHeaders }, callback) => { 330 ({ url, requestHeaders }, callback) => {
319 const requestUserAgent = url.match( 331 const requestUserAgent = /^[^:]+:\/\/accounts\.google\.[^./]+\//.test(url)
320 /^[^:]+:\/\/accounts\.google\.[^./]+\//,
321 )
322 ? chromelessUserAgent 332 ? chromelessUserAgent
323 : userAgent; 333 : userAgent;
324 callback({ 334 callback({
@@ -332,15 +342,15 @@ async function createWindow(): Promise<unknown> {
332 342
333 browserView.webContents 343 browserView.webContents
334 .loadURL('https://gitlab.com/say-hi-to-sophie/sophie') 344 .loadURL('https://gitlab.com/say-hi-to-sophie/sophie')
335 .catch((err) => { 345 .catch((error) => {
336 log.error('Failed to load browser', err); 346 log.error('Failed to load browser', error);
337 }); 347 });
338 348
339 return mainWindow.loadURL(pageUrl); 349 return mainWindow.loadURL(pageUrl);
340} 350}
341 351
342app.on('second-instance', () => { 352app.on('second-instance', () => {
343 if (mainWindow !== null) { 353 if (mainWindow !== undefined) {
344 if (!mainWindow.isVisible()) { 354 if (!mainWindow.isVisible()) {
345 mainWindow.show(); 355 mainWindow.show();
346 } 356 }
@@ -363,14 +373,14 @@ app
363 if (isDevelopment) { 373 if (isDevelopment) {
364 try { 374 try {
365 await installDevToolsExtensions(); 375 await installDevToolsExtensions();
366 } catch (err) { 376 } catch (error) {
367 log.error('Failed to install devtools extensions', err); 377 log.error('Failed to install devtools extensions', error);
368 } 378 }
369 } 379 }
370 380
371 return createWindow(); 381 return createWindow();
372 }) 382 })
373 .catch((err) => { 383 .catch((error) => {
374 log.error('Failed to create window', err); 384 log.error('Failed to create window', error);
375 process.exit(1); 385 process.exit(1);
376 }); 386 });