diff options
Diffstat (limited to 'packages/main')
-rw-r--r-- | packages/main/package.json | 6 | ||||
-rw-r--r-- | packages/main/src/devTools.ts | 49 | ||||
-rw-r--r-- | packages/main/src/index.ts | 66 | ||||
-rw-r--r-- | packages/main/src/stores/RootStore.ts | 12 |
4 files changed, 97 insertions, 36 deletions
diff --git a/packages/main/package.json b/packages/main/package.json index 63da432..22afafa 100644 --- a/packages/main/package.json +++ b/packages/main/package.json | |||
@@ -9,11 +9,13 @@ | |||
9 | }, | 9 | }, |
10 | "dependencies": { | 10 | "dependencies": { |
11 | "@sophie/shared": "workspace:*", | 11 | "@sophie/shared": "workspace:*", |
12 | "electron": "^16.0.5" | 12 | "electron": "^16.0.5", |
13 | "mobx": "^6.3.10", | ||
14 | "mobx-state-tree": "^5.1.0" | ||
13 | }, | 15 | }, |
14 | "devDependencies": { | 16 | "devDependencies": { |
15 | "@types/electron-devtools-installer": "^2.2.0", | 17 | "@types/electron-devtools-installer": "^2.2.0", |
16 | "@types/node": "^16.11.15", | 18 | "@types/node": "^16.11.17", |
17 | "electron-devtools-installer": "^3.2.0", | 19 | "electron-devtools-installer": "^3.2.0", |
18 | "typescript": "^4.5.4", | 20 | "typescript": "^4.5.4", |
19 | "vite": "^2.7.6" | 21 | "vite": "^2.7.6" |
diff --git a/packages/main/src/devTools.ts b/packages/main/src/devTools.ts new file mode 100644 index 0000000..d02bfbf --- /dev/null +++ b/packages/main/src/devTools.ts | |||
@@ -0,0 +1,49 @@ | |||
1 | import type { App, BrowserWindow } from 'electron'; | ||
2 | |||
3 | /** | ||
4 | * Installs the react and redux developer tools extensions. | ||
5 | * | ||
6 | * We use the redux devtools and connect the mobx store to it with `mst-middlewares`, | ||
7 | * because the mobx-state-tree devtools are currently unmaintained. | ||
8 | * | ||
9 | * @param app The electron application instance. | ||
10 | */ | ||
11 | export function installDevToolsExtensions(app: App): void { | ||
12 | app.whenReady().then(async () => { | ||
13 | const { | ||
14 | default: installExtension, | ||
15 | REACT_DEVELOPER_TOOLS, | ||
16 | REDUX_DEVTOOLS, | ||
17 | } = await import('electron-devtools-installer'); | ||
18 | installExtension( | ||
19 | [ | ||
20 | REACT_DEVELOPER_TOOLS, | ||
21 | REDUX_DEVTOOLS, | ||
22 | ], | ||
23 | { | ||
24 | forceDownload: false, | ||
25 | loadExtensionOptions: { | ||
26 | allowFileAccess: true, | ||
27 | }, | ||
28 | }, | ||
29 | ); | ||
30 | }).catch((err) => { | ||
31 | console.error('Failed to install devtools extension', err); | ||
32 | }); | ||
33 | } | ||
34 | |||
35 | /** | ||
36 | * Opens the developer tools while applying a workaround to enable the redux devtools. | ||
37 | * | ||
38 | * @param browserWindow The browser window to open the devtools in. | ||
39 | * @see https://github.com/MarshallOfSound/electron-devtools-installer/issues/195#issuecomment-998872878 | ||
40 | */ | ||
41 | export function openDevToolsWhenReady(browserWindow: BrowserWindow): void { | ||
42 | const { webContents } = browserWindow; | ||
43 | webContents.once('dom-ready', () => { | ||
44 | webContents.once('devtools-opened', () => { | ||
45 | browserWindow?.focus(); | ||
46 | }); | ||
47 | webContents.openDevTools(); | ||
48 | }); | ||
49 | } | ||
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index cd04276..dbe6890 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts | |||
@@ -1,8 +1,18 @@ | |||
1 | import { app, BrowserWindow } from 'electron'; | 1 | import { app, BrowserWindow } from 'electron'; |
2 | import { getSnapshot, onPatch } from 'mobx-state-tree'; | ||
2 | import { join } from 'path'; | 3 | import { join } from 'path'; |
3 | import { RendererIpcMessage } from '@sophie/shared'; | 4 | import { |
5 | MainToRendererIpcMessage, | ||
6 | RendererToMainIpcMessage, | ||
7 | } from '@sophie/shared'; | ||
4 | import { URL } from 'url'; | 8 | import { URL } from 'url'; |
5 | 9 | ||
10 | import { | ||
11 | installDevToolsExtensions, | ||
12 | openDevToolsWhenReady, | ||
13 | } from './devTools'; | ||
14 | import { rootStore } from './stores/RootStore'; | ||
15 | |||
6 | const isSingleInstance = app.requestSingleInstanceLock(); | 16 | const isSingleInstance = app.requestSingleInstanceLock(); |
7 | const isDevelopment = import.meta.env.MODE === 'development'; | 17 | const isDevelopment = import.meta.env.MODE === 'development'; |
8 | 18 | ||
@@ -14,62 +24,46 @@ if (!isSingleInstance) { | |||
14 | app.enableSandbox(); | 24 | app.enableSandbox(); |
15 | 25 | ||
16 | if (isDevelopment) { | 26 | if (isDevelopment) { |
17 | app.whenReady().then(async () => { | 27 | installDevToolsExtensions(app); |
18 | const { | ||
19 | default: installExtension, | ||
20 | MOBX_DEVTOOLS, | ||
21 | REACT_DEVELOPER_TOOLS, | ||
22 | } = await import('electron-devtools-installer'); | ||
23 | installExtension( | ||
24 | [ | ||
25 | MOBX_DEVTOOLS, | ||
26 | REACT_DEVELOPER_TOOLS, | ||
27 | ], | ||
28 | { | ||
29 | forceDownload: false, | ||
30 | loadExtensionOptions: { | ||
31 | allowFileAccess: true, | ||
32 | }, | ||
33 | }, | ||
34 | ); | ||
35 | }).catch((err) => { | ||
36 | console.error('Failed to install devtools extension', err); | ||
37 | }); | ||
38 | } | 28 | } |
39 | 29 | ||
40 | let mainWindow: BrowserWindow | null = null; | 30 | let mainWindow: BrowserWindow | null = null; |
41 | 31 | ||
32 | const store = rootStore.create({ | ||
33 | shared: { | ||
34 | clickCount: 1, | ||
35 | }, | ||
36 | }); | ||
37 | |||
42 | function createWindow(): Promise<void> { | 38 | function createWindow(): Promise<void> { |
43 | mainWindow = new BrowserWindow({ | 39 | mainWindow = new BrowserWindow({ |
44 | show: false, | 40 | show: false, |
41 | autoHideMenuBar: true, | ||
45 | webPreferences: { | 42 | webPreferences: { |
46 | nativeWindowOpen: true, | 43 | nativeWindowOpen: true, |
47 | webviewTag: false, | 44 | webviewTag: false, |
48 | sandbox: true, | 45 | sandbox: true, |
49 | preload: join(__dirname, '../../preload/dist/index.cjs'), | 46 | preload: join(__dirname, '../../preload/dist/index.cjs'), |
50 | } | 47 | }, |
51 | }); | 48 | }); |
52 | 49 | ||
53 | const { webContents } = mainWindow; | ||
54 | |||
55 | // See https://github.com/MarshallOfSound/electron-devtools-installer/issues/195#issuecomment-998872878 | ||
56 | if (isDevelopment) { | 50 | if (isDevelopment) { |
57 | webContents.once('dom-ready', () => { | 51 | openDevToolsWhenReady(mainWindow); |
58 | webContents.once('devtools-opened', () => { | ||
59 | mainWindow?.focus(); | ||
60 | }); | ||
61 | webContents.openDevTools(); | ||
62 | }); | ||
63 | } | 52 | } |
64 | 53 | ||
65 | mainWindow.on('ready-to-show', () => { | 54 | mainWindow.on('ready-to-show', () => { |
66 | mainWindow?.show(); | 55 | mainWindow?.show(); |
67 | }); | 56 | }); |
68 | 57 | ||
58 | const { webContents } = mainWindow; | ||
59 | |||
69 | webContents.on('ipc-message', (_event, channel, ...args) => { | 60 | webContents.on('ipc-message', (_event, channel, ...args) => { |
70 | switch (channel) { | 61 | switch (channel) { |
71 | case RendererIpcMessage.ButtonClicked: | 62 | case RendererToMainIpcMessage.SharedStoreSnapshotRequest: |
72 | console.log('Button clicked'); | 63 | webContents.send(MainToRendererIpcMessage.SharedStoreSnapshot, getSnapshot(store.shared)); |
64 | break; | ||
65 | case RendererToMainIpcMessage.ButtonClick: | ||
66 | store.buttonClick(); | ||
73 | break; | 67 | break; |
74 | default: | 68 | default: |
75 | console.warn('Unknown IPC message:', channel, args); | 69 | console.warn('Unknown IPC message:', channel, args); |
@@ -77,6 +71,10 @@ function createWindow(): Promise<void> { | |||
77 | } | 71 | } |
78 | }); | 72 | }); |
79 | 73 | ||
74 | onPatch(store.shared, (patch) => { | ||
75 | webContents.send(MainToRendererIpcMessage.SharedStorePatch, patch); | ||
76 | }); | ||
77 | |||
80 | const pageUrl = (isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined) | 78 | const pageUrl = (isDevelopment && import.meta.env.VITE_DEV_SERVER_URL !== undefined) |
81 | ? import.meta.env.VITE_DEV_SERVER_URL | 79 | ? import.meta.env.VITE_DEV_SERVER_URL |
82 | : new URL('../renderer/dist/index.html', `file://${__dirname}`).toString(); | 80 | : new URL('../renderer/dist/index.html', `file://${__dirname}`).toString(); |
diff --git a/packages/main/src/stores/RootStore.ts b/packages/main/src/stores/RootStore.ts new file mode 100644 index 0000000..a9c1290 --- /dev/null +++ b/packages/main/src/stores/RootStore.ts | |||
@@ -0,0 +1,12 @@ | |||
1 | import { Instance, types } from 'mobx-state-tree'; | ||
2 | import { sharedStore } from '@sophie/shared'; | ||
3 | |||
4 | export const rootStore = types.model('RootStore', { | ||
5 | shared: sharedStore, | ||
6 | }).actions((self) => ({ | ||
7 | buttonClick() { | ||
8 | self.shared.clickCount += 1; | ||
9 | }, | ||
10 | })); | ||
11 | |||
12 | export interface RootStore extends Instance<typeof rootStore> {} | ||