aboutsummaryrefslogtreecommitdiffstats
path: root/packages/renderer
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-02-27 00:57:44 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-03-06 18:56:46 +0100
commitf05d54406c9bc4b69609a4935132ff17b8e28824 (patch)
treee7ffde8f8b3433e004932a6e068dedbb4f2196da /packages/renderer
parentdesign: Simpler message count indicators (diff)
downloadsophie-f05d54406c9bc4b69609a4935132ff17b8e28824.tar.gz
sophie-f05d54406c9bc4b69609a4935132ff17b8e28824.tar.zst
sophie-f05d54406c9bc4b69609a4935132ff17b8e28824.zip
refactor: Shared model type factories
Allows customization of stores both in the renderer and in the main process. Instead of exposing a basic model type from the shared module (which was be overwritted with more specific props in the main package), we expose factory function that can create specific model types in both the renderer and the main process. Using these package-specific customization to stores, the renderer package can attach IPC calls directly to store objects, which the main package can attach the handlers for IPC calls and other internal actions. Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/renderer')
-rw-r--r--packages/renderer/src/components/locationBar/LocationTextField.tsx3
-rw-r--r--packages/renderer/src/components/locationBar/NavigationButtons.tsx3
-rw-r--r--packages/renderer/src/components/sidebar/ServiceIcon.tsx3
-rw-r--r--packages/renderer/src/components/sidebar/ServiceSwitcher.tsx9
-rw-r--r--packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx8
-rw-r--r--packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx8
-rw-r--r--packages/renderer/src/stores/GlobalSettings.ts63
-rw-r--r--packages/renderer/src/stores/Profile.ts32
-rw-r--r--packages/renderer/src/stores/RendererStore.ts41
-rw-r--r--packages/renderer/src/stores/Service.ts34
-rw-r--r--packages/renderer/src/stores/ServiceSettings.ts39
-rw-r--r--packages/renderer/src/stores/SharedStore.ts53
12 files changed, 241 insertions, 55 deletions
diff --git a/packages/renderer/src/components/locationBar/LocationTextField.tsx b/packages/renderer/src/components/locationBar/LocationTextField.tsx
index f436bf0..e6da59f 100644
--- a/packages/renderer/src/components/locationBar/LocationTextField.tsx
+++ b/packages/renderer/src/components/locationBar/LocationTextField.tsx
@@ -20,11 +20,12 @@
20 20
21import FilledInput from '@mui/material/FilledInput'; 21import FilledInput from '@mui/material/FilledInput';
22import { styled } from '@mui/material/styles'; 22import { styled } from '@mui/material/styles';
23import { Service } from '@sophie/shared';
24import { autorun } from 'mobx'; 23import { autorun } from 'mobx';
25import { observer } from 'mobx-react-lite'; 24import { observer } from 'mobx-react-lite';
26import React, { useCallback, useEffect, useState } from 'react'; 25import React, { useCallback, useEffect, useState } from 'react';
27 26
27import Service from '../../stores/Service';
28
28import GoAdornment from './GoAdornment'; 29import GoAdornment from './GoAdornment';
29import LocationOverlayInput from './LocationOverlayInput'; 30import LocationOverlayInput from './LocationOverlayInput';
30import UrlAdornment from './UrlAdornment'; 31import UrlAdornment from './UrlAdornment';
diff --git a/packages/renderer/src/components/locationBar/NavigationButtons.tsx b/packages/renderer/src/components/locationBar/NavigationButtons.tsx
index 77b02b6..ce59692 100644
--- a/packages/renderer/src/components/locationBar/NavigationButtons.tsx
+++ b/packages/renderer/src/components/locationBar/NavigationButtons.tsx
@@ -26,10 +26,11 @@ import IconRefresh from '@mui/icons-material/Refresh';
26import { useTheme } from '@mui/material'; 26import { useTheme } from '@mui/material';
27import Box from '@mui/material/Box'; 27import Box from '@mui/material/Box';
28import IconButton from '@mui/material/IconButton'; 28import IconButton from '@mui/material/IconButton';
29import { Service } from '@sophie/shared';
30import { observer } from 'mobx-react-lite'; 29import { observer } from 'mobx-react-lite';
31import React from 'react'; 30import React from 'react';
32 31
32import Service from '../../stores/Service';
33
33function NavigationButtons({ 34function NavigationButtons({
34 service, 35 service,
35}: { 36}: {
diff --git a/packages/renderer/src/components/sidebar/ServiceIcon.tsx b/packages/renderer/src/components/sidebar/ServiceIcon.tsx
index 144f860..5db8a0c 100644
--- a/packages/renderer/src/components/sidebar/ServiceIcon.tsx
+++ b/packages/renderer/src/components/sidebar/ServiceIcon.tsx
@@ -20,10 +20,11 @@
20 20
21import Badge from '@mui/material/Badge'; 21import Badge from '@mui/material/Badge';
22import { styled, useTheme } from '@mui/material/styles'; 22import { styled, useTheme } from '@mui/material/styles';
23import { Service } from '@sophie/shared';
24import { observer } from 'mobx-react-lite'; 23import { observer } from 'mobx-react-lite';
25import React, { useEffect, useState } from 'react'; 24import React, { useEffect, useState } from 'react';
26 25
26import type Service from '../../stores/Service';
27
27const ServiceIconRoot = styled('div', { 28const ServiceIconRoot = styled('div', {
28 name: 'ServiceIcon', 29 name: 'ServiceIcon',
29 slot: 'Root', 30 slot: 'Root',
diff --git a/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx b/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx
index 2241476..eba21b5 100644
--- a/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx
+++ b/packages/renderer/src/components/sidebar/ServiceSwitcher.tsx
@@ -65,11 +65,8 @@ const ServiceSwitcherTab = styled(Tab, {
65})); 65}));
66 66
67function ServiceSwitcher(): JSX.Element { 67function ServiceSwitcher(): JSX.Element {
68 const store = useStore(); 68 const { settings, services } = useStore();
69 const { 69 const { selectedService } = settings;
70 settings: { selectedService },
71 services,
72 } = store;
73 70
74 return ( 71 return (
75 <ServiceSwitcherRoot 72 <ServiceSwitcherRoot
@@ -77,7 +74,7 @@ function ServiceSwitcher(): JSX.Element {
77 orientation="vertical" 74 orientation="vertical"
78 value={selectedService === undefined ? false : selectedService.id} 75 value={selectedService === undefined ? false : selectedService.id}
79 onChange={(_event, newValue: string) => 76 onChange={(_event, newValue: string) =>
80 store.setSelectedServiceId(newValue) 77 settings.setSelectedServiceId(newValue)
81 } 78 }
82 > 79 >
83 {services.map((service) => ( 80 {services.map((service) => (
diff --git a/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx b/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx
index 164b066..bacbf07 100644
--- a/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx
+++ b/packages/renderer/src/components/sidebar/ToggleDarkModeButton.tsx
@@ -27,15 +27,13 @@ import React from 'react';
27import { useStore } from '../StoreProvider'; 27import { useStore } from '../StoreProvider';
28 28
29export default observer(() => { 29export default observer(() => {
30 const store = useStore(); 30 const { shared } = useStore();
31 const { 31 const { shouldUseDarkColors } = shared;
32 shared: { shouldUseDarkColors },
33 } = store;
34 32
35 return ( 33 return (
36 <IconButton 34 <IconButton
37 aria-label="Toggle dark mode" 35 aria-label="Toggle dark mode"
38 onClick={() => store.toggleDarkMode()} 36 onClick={() => shared.toggleDarkMode()}
39 > 37 >
40 {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />} 38 {shouldUseDarkColors ? <LightModeIcon /> : <DarkModeIcon />}
41 </IconButton> 39 </IconButton>
diff --git a/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx b/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx
index 60033b0..d2f0745 100644
--- a/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx
+++ b/packages/renderer/src/components/sidebar/ToggleLocationBarButton.tsx
@@ -45,17 +45,15 @@ function ToggleLocationBarIcon({
45} 45}
46 46
47function ToggleLocationBarButton(): JSX.Element { 47function ToggleLocationBarButton(): JSX.Element {
48 const store = useStore(); 48 const { settings } = useStore();
49 const { 49 const { selectedService, showLocationBar } = settings;
50 settings: { selectedService, showLocationBar },
51 } = store;
52 50
53 return ( 51 return (
54 <IconButton 52 <IconButton
55 aria-pressed={showLocationBar} 53 aria-pressed={showLocationBar}
56 aria-controls={LOCATION_BAR_ID} 54 aria-controls={LOCATION_BAR_ID}
57 aria-label="Show location bar" 55 aria-label="Show location bar"
58 onClick={() => store.toggleLocationBar()} 56 onClick={() => settings.toggleLocationBar()}
59 > 57 >
60 <ToggleLocationBarIcon 58 <ToggleLocationBarIcon
61 loading={selectedService?.state === 'loading'} 59 loading={selectedService?.state === 'loading'}
diff --git a/packages/renderer/src/stores/GlobalSettings.ts b/packages/renderer/src/stores/GlobalSettings.ts
new file mode 100644
index 0000000..79815ba
--- /dev/null
+++ b/packages/renderer/src/stores/GlobalSettings.ts
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 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 { defineGlobalSettingsModel, ThemeSource } from '@sophie/shared';
22import { Instance } from 'mobx-state-tree';
23
24import getEnv from '../env/getEnv';
25
26import Service from './Service';
27
28const GlobalSettings = defineGlobalSettingsModel(Service).actions((self) => ({
29 setSelectedServiceId(serviceId: string): void {
30 getEnv(self).dispatchMainAction({
31 action: 'set-selected-service-id',
32 serviceId,
33 });
34 },
35 setThemeSource(themeSource: ThemeSource): void {
36 getEnv(self).dispatchMainAction({
37 action: 'set-theme-source',
38 themeSource,
39 });
40 },
41 setShowLocationBar(showLocationBar: boolean): void {
42 getEnv(self).dispatchMainAction({
43 action: 'set-show-location-bar',
44 showLocationBar,
45 });
46 },
47 toggleLocationBar(): void {
48 this.setShowLocationBar(!self.showLocationBar);
49 },
50}));
51
52/*
53 eslint-disable-next-line @typescript-eslint/no-redeclare --
54 Intentionally naming the type the same as the store definition.
55*/
56interface GlobalSettings extends Instance<typeof GlobalSettings> {}
57
58export default GlobalSettings;
59
60export type {
61 GlobalSettingsSnapshotIn,
62 GlobalSettingsSnapshotOut,
63} from '@sophie/shared';
diff --git a/packages/renderer/src/stores/Profile.ts b/packages/renderer/src/stores/Profile.ts
new file mode 100644
index 0000000..20a3a17
--- /dev/null
+++ b/packages/renderer/src/stores/Profile.ts
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 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 { Profile as ProfileBase } from '@sophie/shared';
22import { Instance } from 'mobx-state-tree';
23
24const Profile = ProfileBase;
25
26/*
27 eslint-disable-next-line @typescript-eslint/no-redeclare --
28 Intentionally naming the type the same as the store definition.
29*/
30interface Profile extends Instance<typeof Profile> {}
31
32export default Profile;
diff --git a/packages/renderer/src/stores/RendererStore.ts b/packages/renderer/src/stores/RendererStore.ts
index 1acc605..8f424f6 100644
--- a/packages/renderer/src/stores/RendererStore.ts
+++ b/packages/renderer/src/stores/RendererStore.ts
@@ -18,20 +18,17 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { 21import { BrowserViewBounds, SophieRenderer } from '@sophie/shared';
22 BrowserViewBounds,
23 SharedStore,
24 Service,
25 SophieRenderer,
26 ThemeSource,
27 GlobalSettings,
28} from '@sophie/shared';
29import { applySnapshot, applyPatch, Instance, types } from 'mobx-state-tree'; 22import { applySnapshot, applyPatch, Instance, types } from 'mobx-state-tree';
30 23
31import RendererEnv from '../env/RendererEnv'; 24import RendererEnv from '../env/RendererEnv';
32import getEnv from '../env/getEnv'; 25import getEnv from '../env/getEnv';
33import { getLogger } from '../utils/log'; 26import { getLogger } from '../utils/log';
34 27
28import GlobalSettings from './GlobalSettings';
29import Service from './Service';
30import SharedStore from './SharedStore';
31
35const log = getLogger('RendererStore'); 32const log = getLogger('RendererStore');
36 33
37const RendererStore = types 34const RendererStore = types
@@ -47,40 +44,12 @@ const RendererStore = types
47 }, 44 },
48 })) 45 }))
49 .actions((self) => ({ 46 .actions((self) => ({
50 setSelectedServiceId(serviceId: string): void {
51 getEnv(self).dispatchMainAction({
52 action: 'set-selected-service-id',
53 serviceId,
54 });
55 },
56 setBrowserViewBounds(browserViewBounds: BrowserViewBounds): void { 47 setBrowserViewBounds(browserViewBounds: BrowserViewBounds): void {
57 getEnv(self).dispatchMainAction({ 48 getEnv(self).dispatchMainAction({
58 action: 'set-browser-view-bounds', 49 action: 'set-browser-view-bounds',
59 browserViewBounds, 50 browserViewBounds,
60 }); 51 });
61 }, 52 },
62 setThemeSource(themeSource: ThemeSource): void {
63 getEnv(self).dispatchMainAction({
64 action: 'set-theme-source',
65 themeSource,
66 });
67 },
68 toggleDarkMode(): void {
69 if (self.shared.shouldUseDarkColors) {
70 this.setThemeSource('light');
71 } else {
72 this.setThemeSource('dark');
73 }
74 },
75 setShowLocationBar(showLocationBar: boolean): void {
76 getEnv(self).dispatchMainAction({
77 action: 'set-show-location-bar',
78 showLocationBar,
79 });
80 },
81 toggleLocationBar(): void {
82 this.setShowLocationBar(!self.settings.showLocationBar);
83 },
84 })); 53 }));
85 54
86/* 55/*
diff --git a/packages/renderer/src/stores/Service.ts b/packages/renderer/src/stores/Service.ts
new file mode 100644
index 0000000..c2c938a
--- /dev/null
+++ b/packages/renderer/src/stores/Service.ts
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 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 { defineServiceModel } from '@sophie/shared';
22import { Instance } from 'mobx-state-tree';
23
24import ServiceSettings from './ServiceSettings';
25
26const Service = defineServiceModel(ServiceSettings);
27
28/*
29 eslint-disable-next-line @typescript-eslint/no-redeclare --
30 Intentionally naming the type the same as the store definition.
31*/
32interface Service extends Instance<typeof Service> {}
33
34export default Service;
diff --git a/packages/renderer/src/stores/ServiceSettings.ts b/packages/renderer/src/stores/ServiceSettings.ts
new file mode 100644
index 0000000..5d37347
--- /dev/null
+++ b/packages/renderer/src/stores/ServiceSettings.ts
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 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 { defineServiceSettingsModel } from '@sophie/shared';
22import { Instance } from 'mobx-state-tree';
23
24import Profile from './Profile';
25
26const ServiceSettings = defineServiceSettingsModel(Profile);
27
28/*
29 eslint-disable-next-line @typescript-eslint/no-redeclare --
30 Intentionally naming the type the same as the store definition.
31*/
32interface ServiceSettings extends Instance<typeof ServiceSettings> {}
33
34export default ServiceSettings;
35
36export type {
37 ServiceSettingsSnapshotIn,
38 ServiceSettingsSnapshotOut,
39} from '@sophie/shared';
diff --git a/packages/renderer/src/stores/SharedStore.ts b/packages/renderer/src/stores/SharedStore.ts
new file mode 100644
index 0000000..062479d
--- /dev/null
+++ b/packages/renderer/src/stores/SharedStore.ts
@@ -0,0 +1,53 @@
1/*
2 * Copyright (C) 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 { defineSharedStoreModel } from '@sophie/shared';
22import { Instance } from 'mobx-state-tree';
23
24import GlobalSettings from './GlobalSettings';
25import Profile from './Profile';
26import Service from './Service';
27
28const SharedStore = defineSharedStoreModel(
29 GlobalSettings,
30 Profile,
31 Service,
32).actions((self) => ({
33 toggleDarkMode(): void {
34 if (self.shouldUseDarkColors) {
35 self.settings.setThemeSource('light');
36 } else {
37 self.settings.setThemeSource('dark');
38 }
39 },
40}));
41
42/*
43 eslint-disable-next-line @typescript-eslint/no-redeclare --
44 Intentionally naming the type the same as the store definition.
45*/
46interface SharedStore extends Instance<typeof SharedStore> {}
47
48export default SharedStore;
49
50export type {
51 SharedStoreSnapshotIn,
52 SharedStoreSnapshotOut,
53} from '@sophie/shared';