aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-26 01:59:17 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-12-26 01:59:17 +0100
commitcce40ab1d2ad8cc1b60fabb4cc8281ea0490a123 (patch)
treebb96df2676934a9cd4ef2bc5a48957e8b32fb646
parentrefactor: Simplify browserViewBounds handling (diff)
downloadsophie-cce40ab1d2ad8cc1b60fabb4cc8281ea0490a123.tar.gz
sophie-cce40ab1d2ad8cc1b60fabb4cc8281ea0490a123.tar.zst
sophie-cce40ab1d2ad8cc1b60fabb4cc8281ea0490a123.zip
feat: Set nativeTheme theme source on dark mode
-rw-r--r--packages/main/src/index.ts16
-rw-r--r--packages/main/src/stores/Config.ts32
-rw-r--r--packages/main/src/stores/RootStore.ts21
-rw-r--r--packages/main/src/stores/SharedStore.ts32
-rw-r--r--packages/preload/src/SophieRendererImpl.ts12
-rw-r--r--packages/renderer/src/stores/RootStore.ts10
-rw-r--r--packages/shared/src/contextBridge/SophieRenderer.ts4
-rw-r--r--packages/shared/src/index.ts7
-rw-r--r--packages/shared/src/ipc.ts2
-rw-r--r--packages/shared/src/schemas.ts4
-rw-r--r--packages/shared/src/stores/Config.ts42
-rw-r--r--packages/shared/src/stores/SharedStore.ts4
12 files changed, 157 insertions, 29 deletions
diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts
index a135902..6a8a74e 100644
--- a/packages/main/src/index.ts
+++ b/packages/main/src/index.ts
@@ -23,6 +23,7 @@ import {
23 BrowserView, 23 BrowserView,
24 BrowserWindow, 24 BrowserWindow,
25 ipcMain, 25 ipcMain,
26 nativeTheme,
26} from 'electron'; 27} from 'electron';
27import { readFile, readFileSync } from 'fs'; 28import { readFile, readFileSync } from 'fs';
28import { autorun } from 'mobx'; 29import { autorun } from 'mobx';
@@ -36,7 +37,7 @@ import {
36import { 37import {
37 browserViewBounds, 38 browserViewBounds,
38 MainToRendererIpcMessage, 39 MainToRendererIpcMessage,
39 paletteMode, 40 themeSource,
40 RendererToMainIpcMessage, 41 RendererToMainIpcMessage,
41} from '@sophie/shared'; 42} from '@sophie/shared';
42import { URL } from 'url'; 43import { URL } from 'url';
@@ -104,6 +105,15 @@ let mainWindow: BrowserWindow | null = null;
104 105
105const store = createRootStore(); 106const store = createRootStore();
106 107
108autorun(() => {
109 nativeTheme.themeSource = store.config.themeSource;
110});
111
112store.setShouldUseDarkColors(nativeTheme.shouldUseDarkColors);
113nativeTheme.on('updated', () => {
114 store.setShouldUseDarkColors(nativeTheme.shouldUseDarkColors);
115});
116
107const rendererBaseUrl = getResourceUrl('../renderer/'); 117const rendererBaseUrl = getResourceUrl('../renderer/');
108function shouldCancelMainWindowRequest(url: string, method: string): boolean { 118function shouldCancelMainWindowRequest(url: string, method: string): boolean {
109 if (method !== 'GET') { 119 if (method !== 'GET') {
@@ -191,8 +201,8 @@ function createWindow(): Promise<unknown> {
191 case RendererToMainIpcMessage.SetBrowserViewBounds: 201 case RendererToMainIpcMessage.SetBrowserViewBounds:
192 store.setBrowserViewBounds(browserViewBounds.parse(args[0])); 202 store.setBrowserViewBounds(browserViewBounds.parse(args[0]));
193 break; 203 break;
194 case RendererToMainIpcMessage.SetPaletteMode: 204 case RendererToMainIpcMessage.SetThemeSource:
195 store.setPaletteMode(paletteMode.parse(args[0])) 205 store.config.setThemeSource(themeSource.parse(args[0]))
196 break; 206 break;
197 case RendererToMainIpcMessage.ReloadAllServices: 207 case RendererToMainIpcMessage.ReloadAllServices:
198 readFile(serviceInjectPath, 'utf8', (err, data) => { 208 readFile(serviceInjectPath, 'utf8', (err, data) => {
diff --git a/packages/main/src/stores/Config.ts b/packages/main/src/stores/Config.ts
new file mode 100644
index 0000000..483a491
--- /dev/null
+++ b/packages/main/src/stores/Config.ts
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import type { Instance } from 'mobx-state-tree';
22import { config as originalConfig, ThemeSource } from '@sophie/shared';
23
24export type { ConfigSnapshotIn, ConfigSnapshotOut } from '@sophie/shared';
25
26export const config = originalConfig.actions((self) => ({
27 setThemeSource(mode: ThemeSource) {
28 self.themeSource = mode;
29 },
30}));
31
32export interface Config extends Instance<typeof config> {}
diff --git a/packages/main/src/stores/RootStore.ts b/packages/main/src/stores/RootStore.ts
index c09cd4a..31e2b71 100644
--- a/packages/main/src/stores/RootStore.ts
+++ b/packages/main/src/stores/RootStore.ts
@@ -22,25 +22,30 @@ import { applySnapshot, Instance, types } from 'mobx-state-tree';
22import { 22import {
23 BrowserViewBounds, 23 BrowserViewBounds,
24 emptySharedStore, 24 emptySharedStore,
25 PaletteMode,
26 sharedStore,
27} from '@sophie/shared'; 25} from '@sophie/shared';
28 26
27import type { Config } from './Config';
28import { sharedStore } from './SharedStore';
29
29export const rootStore = types.model('RootStore', { 30export const rootStore = types.model('RootStore', {
30 browserViewBounds: types.model("BrowserViewBoundsStore", { 31 browserViewBounds: types.model('BrowserViewBounds', {
31 x: 0, 32 x: 0,
32 y: 0, 33 y: 0,
33 width: 0, 34 width: 0,
34 height: 0, 35 height: 0,
35 }), 36 }),
36 shared: sharedStore, 37 shared: sharedStore,
37}).actions((self) => ({ 38}).views((self) => ({
38 setBrowserViewBounds(bounds: BrowserViewBounds) { 39 get config(): Config {
39 applySnapshot(self.browserViewBounds, bounds); 40 return self.shared.config;
40 }, 41 },
41 setPaletteMode(mode: PaletteMode) { 42})).actions((self) => ({
42 self.shared.shouldUseDarkColors = mode === 'dark'; 43 setBrowserViewBounds(bounds: BrowserViewBounds): void {
44 applySnapshot(self.browserViewBounds, bounds);
43 }, 45 },
46 setShouldUseDarkColors(shouldUseDarkColors: boolean): void {
47 self.shared.shouldUseDarkColors = shouldUseDarkColors;
48 }
44})); 49}));
45 50
46export interface RootStore extends Instance<typeof rootStore> {} 51export interface RootStore extends Instance<typeof rootStore> {}
diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts
new file mode 100644
index 0000000..04dda32
--- /dev/null
+++ b/packages/main/src/stores/SharedStore.ts
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import { Instance } from 'mobx-state-tree';
22import { sharedStore as originalSharedStore } from '@sophie/shared';
23
24import { config } from './Config';
25
26export type { SharedStoreSnapshotIn, SharedStoreSnapshotOut } from '@sophie/shared';
27
28export const sharedStore = originalSharedStore.props({
29 config,
30});
31
32export interface SharedStore extends Instance<typeof sharedStore> {}
diff --git a/packages/preload/src/SophieRendererImpl.ts b/packages/preload/src/SophieRendererImpl.ts
index bd0f6cb..a06433f 100644
--- a/packages/preload/src/SophieRendererImpl.ts
+++ b/packages/preload/src/SophieRendererImpl.ts
@@ -24,13 +24,13 @@ import {
24 BrowserViewBounds, 24 BrowserViewBounds,
25 browserViewBounds, 25 browserViewBounds,
26 MainToRendererIpcMessage, 26 MainToRendererIpcMessage,
27 PaletteMode,
28 paletteMode,
29 RendererToMainIpcMessage, 27 RendererToMainIpcMessage,
30 sharedStore, 28 sharedStore,
31 SharedStoreListener, 29 SharedStoreListener,
32 SharedStoreSnapshotIn, 30 SharedStoreSnapshotIn,
33 SophieRenderer, 31 SophieRenderer,
32 themeSource,
33 ThemeSource,
34} from '@sophie/shared'; 34} from '@sophie/shared';
35 35
36export type MessageSender = (channel: RendererToMainIpcMessage, ...args: unknown[]) => void; 36export type MessageSender = (channel: RendererToMainIpcMessage, ...args: unknown[]) => void;
@@ -81,9 +81,9 @@ export class SophieRendererImpl implements SophieRenderer {
81 } 81 }
82 } 82 }
83 83
84 setPaletteMode(mode: PaletteMode): void { 84 setThemeSource(mode: ThemeSource): void {
85 if (paletteMode.safeParse(mode).success) { 85 if (themeSource.safeParse(mode).success) {
86 this.#send(RendererToMainIpcMessage.SetPaletteMode, mode); 86 this.#send(RendererToMainIpcMessage.SetThemeSource, mode);
87 } 87 }
88 } 88 }
89 89
@@ -106,7 +106,7 @@ export function createSophieRenderer(): SophieRenderer {
106 return { 106 return {
107 setSharedStoreListener: impl.setSharedStoreListener.bind(impl), 107 setSharedStoreListener: impl.setSharedStoreListener.bind(impl),
108 setBrowserViewBounds: impl.setBrowserViewBounds.bind(impl), 108 setBrowserViewBounds: impl.setBrowserViewBounds.bind(impl),
109 setPaletteMode: impl.setPaletteMode.bind(impl), 109 setThemeSource: impl.setThemeSource.bind(impl),
110 reloadAllServices: impl.reloadAllServices.bind(impl), 110 reloadAllServices: impl.reloadAllServices.bind(impl),
111 }; 111 };
112} 112}
diff --git a/packages/renderer/src/stores/RootStore.ts b/packages/renderer/src/stores/RootStore.ts
index c6533ba..20e0afa 100644
--- a/packages/renderer/src/stores/RootStore.ts
+++ b/packages/renderer/src/stores/RootStore.ts
@@ -29,9 +29,9 @@ import {
29import { 29import {
30 BrowserViewBounds, 30 BrowserViewBounds,
31 emptySharedStore, 31 emptySharedStore,
32 PaletteMode,
33 sharedStore, 32 sharedStore,
34 SophieRenderer, 33 SophieRenderer,
34 ThemeSource,
35} from '@sophie/shared'; 35} from '@sophie/shared';
36 36
37export interface RootEnv { 37export interface RootEnv {
@@ -55,14 +55,14 @@ export const rootStore = types.model('RootStore', {
55 setBrowserViewBounds(bounds: BrowserViewBounds) { 55 setBrowserViewBounds(bounds: BrowserViewBounds) {
56 getEnv(self).ipc.setBrowserViewBounds(bounds); 56 getEnv(self).ipc.setBrowserViewBounds(bounds);
57 }, 57 },
58 setPaletteMode(mode: PaletteMode) { 58 setThemeSource(mode: ThemeSource) {
59 getEnv(self).ipc.setPaletteMode(mode); 59 getEnv(self).ipc.setThemeSource(mode);
60 }, 60 },
61 toggleDarkMode() { 61 toggleDarkMode() {
62 if (self.shared.shouldUseDarkColors) { 62 if (self.shared.shouldUseDarkColors) {
63 this.setPaletteMode('light'); 63 this.setThemeSource('light');
64 } else { 64 } else {
65 this.setPaletteMode('dark'); 65 this.setThemeSource('dark');
66 } 66 }
67 }, 67 },
68})); 68}));
diff --git a/packages/shared/src/contextBridge/SophieRenderer.ts b/packages/shared/src/contextBridge/SophieRenderer.ts
index e310829..6a2e432 100644
--- a/packages/shared/src/contextBridge/SophieRenderer.ts
+++ b/packages/shared/src/contextBridge/SophieRenderer.ts
@@ -20,14 +20,14 @@
20 20
21import { SharedStoreListener } from '../stores/SharedStore'; 21import { SharedStoreListener } from '../stores/SharedStore';
22 22
23import { BrowserViewBounds, PaletteMode } from '../schemas'; 23import { BrowserViewBounds, ThemeSource } from '../schemas';
24 24
25export interface SophieRenderer { 25export interface SophieRenderer {
26 setSharedStoreListener(listener: SharedStoreListener): void; 26 setSharedStoreListener(listener: SharedStoreListener): void;
27 27
28 setBrowserViewBounds(bounds: BrowserViewBounds): void; 28 setBrowserViewBounds(bounds: BrowserViewBounds): void;
29 29
30 setPaletteMode(mode: PaletteMode): void; 30 setThemeSource(mode: ThemeSource): void;
31 31
32 reloadAllServices(): void; 32 reloadAllServices(): void;
33} 33}
diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts
index f054571..046d28d 100644
--- a/packages/shared/src/index.ts
+++ b/packages/shared/src/index.ts
@@ -27,13 +27,16 @@ export {
27 27
28export type { 28export type {
29 BrowserViewBounds, 29 BrowserViewBounds,
30 PaletteMode, 30 ThemeSource,
31} from './schemas'; 31} from './schemas';
32export { 32export {
33 browserViewBounds, 33 browserViewBounds,
34 paletteMode 34 themeSource,
35} from './schemas'; 35} from './schemas';
36 36
37export type { Config, ConfigSnapshotIn, ConfigSnapshotOut } from './stores/Config';
38export { config, defaultConfig } from './stores/Config';
39
37export type { 40export type {
38 SharedStore, 41 SharedStore,
39 SharedStoreListener, 42 SharedStoreListener,
diff --git a/packages/shared/src/ipc.ts b/packages/shared/src/ipc.ts
index 2e35d7a..d2f65f7 100644
--- a/packages/shared/src/ipc.ts
+++ b/packages/shared/src/ipc.ts
@@ -26,6 +26,6 @@ export enum MainToRendererIpcMessage {
26export enum RendererToMainIpcMessage { 26export enum RendererToMainIpcMessage {
27 SharedStoreSnapshotRequest = 'sophie-renderer-to-main:shared-store-snapshot-request', 27 SharedStoreSnapshotRequest = 'sophie-renderer-to-main:shared-store-snapshot-request',
28 SetBrowserViewBounds = 'sophie-renderer-to-main:set-browser-view-bounds', 28 SetBrowserViewBounds = 'sophie-renderer-to-main:set-browser-view-bounds',
29 SetPaletteMode = 'sophie-renderer-to-main:set-palette-mode', 29 SetThemeSource = 'sophie-renderer-to-main:set-theme-source',
30 ReloadAllServices = 'sophie-renderer-to-main:reload-all-services', 30 ReloadAllServices = 'sophie-renderer-to-main:reload-all-services',
31} 31}
diff --git a/packages/shared/src/schemas.ts b/packages/shared/src/schemas.ts
index 8827467..0eff581 100644
--- a/packages/shared/src/schemas.ts
+++ b/packages/shared/src/schemas.ts
@@ -29,6 +29,6 @@ export const browserViewBounds = z.object({
29 29
30export type BrowserViewBounds = z.infer<typeof browserViewBounds>; 30export type BrowserViewBounds = z.infer<typeof browserViewBounds>;
31 31
32export const paletteMode = z.enum(['light', 'dark']); 32export const themeSource = z.enum(['system', 'light', 'dark']);
33 33
34export type PaletteMode = z.infer<typeof paletteMode>; 34export type ThemeSource = z.infer<typeof themeSource>;
diff --git a/packages/shared/src/stores/Config.ts b/packages/shared/src/stores/Config.ts
new file mode 100644
index 0000000..1a9f924
--- /dev/null
+++ b/packages/shared/src/stores/Config.ts
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2021-2022 Kristóf Marussy <kristof@marussy.com>
3 *
4 * This file is part of Sophie.
5 *
6 * Sophie is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as
8 * published by the Free Software Foundation, version 3.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: AGPL-3.0-only
19 */
20
21import {
22 Instance,
23 types,
24 SnapshotIn,
25 SnapshotOut,
26} from 'mobx-state-tree';
27
28import { themeSource } from '../schemas';
29
30export const config = types.model("Config", {
31 themeSource: types.enumeration(themeSource.options),
32});
33
34export const defaultConfig: ConfigSnapshotIn = {
35 themeSource: 'system',
36};
37
38export interface Config extends Instance<typeof config> {}
39
40export interface ConfigSnapshotIn extends SnapshotIn<typeof config> {}
41
42export interface ConfigSnapshotOut extends SnapshotOut<typeof config> {}
diff --git a/packages/shared/src/stores/SharedStore.ts b/packages/shared/src/stores/SharedStore.ts
index 9c7d5ad..9f0afb1 100644
--- a/packages/shared/src/stores/SharedStore.ts
+++ b/packages/shared/src/stores/SharedStore.ts
@@ -26,11 +26,15 @@ import {
26 SnapshotOut, 26 SnapshotOut,
27} from 'mobx-state-tree'; 27} from 'mobx-state-tree';
28 28
29import { config, defaultConfig } from './Config';
30
29export const sharedStore = types.model("SharedStore", { 31export const sharedStore = types.model("SharedStore", {
32 config,
30 shouldUseDarkColors: true, 33 shouldUseDarkColors: true,
31}); 34});
32 35
33export const emptySharedStore: SharedStoreSnapshotIn = { 36export const emptySharedStore: SharedStoreSnapshotIn = {
37 config: defaultConfig,
34}; 38};
35 39
36export interface SharedStore extends Instance<typeof sharedStore> {} 40export interface SharedStore extends Instance<typeof sharedStore> {}