aboutsummaryrefslogtreecommitdiffstats
path: root/packages/main/src
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/main/src
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/main/src')
-rw-r--r--packages/main/src/stores/GlobalSettings.ts12
-rw-r--r--packages/main/src/stores/Profile.ts7
-rw-r--r--packages/main/src/stores/ProfileSettings.ts30
-rw-r--r--packages/main/src/stores/Service.ts7
-rw-r--r--packages/main/src/stores/ServiceSettings.ts10
-rw-r--r--packages/main/src/stores/SharedStore.ts14
-rw-r--r--packages/main/src/stores/config/loadConfig.ts2
-rw-r--r--packages/main/src/utils/overrideProps.ts62
8 files changed, 13 insertions, 131 deletions
diff --git a/packages/main/src/stores/GlobalSettings.ts b/packages/main/src/stores/GlobalSettings.ts
index 2af9da2..31b7e12 100644
--- a/packages/main/src/stores/GlobalSettings.ts
+++ b/packages/main/src/stores/GlobalSettings.ts
@@ -18,22 +18,16 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { 21import { defineGlobalSettingsModel, ThemeSource } from '@sophie/shared';
22 GlobalSettings as GlobalSettingsBase, 22import { Instance, resolveIdentifier } from 'mobx-state-tree';
23 ThemeSource,
24} from '@sophie/shared';
25import { Instance, resolveIdentifier, types } from 'mobx-state-tree';
26 23
27import { getLogger } from '../utils/log'; 24import { getLogger } from '../utils/log';
28import overrideProps from '../utils/overrideProps';
29 25
30import Service from './Service'; 26import Service from './Service';
31 27
32const log = getLogger('sharedStore'); 28const log = getLogger('sharedStore');
33 29
34const GlobalSettings = overrideProps(GlobalSettingsBase, { 30const GlobalSettings = defineGlobalSettingsModel(Service).actions((self) => ({
35 selectedService: types.safeReference(Service),
36}).actions((self) => ({
37 setThemeSource(mode: ThemeSource): void { 31 setThemeSource(mode: ThemeSource): void {
38 self.themeSource = mode; 32 self.themeSource = mode;
39 }, 33 },
diff --git a/packages/main/src/stores/Profile.ts b/packages/main/src/stores/Profile.ts
index 0fd486e..836f4a8 100644
--- a/packages/main/src/stores/Profile.ts
+++ b/packages/main/src/stores/Profile.ts
@@ -21,14 +21,9 @@
21import { Profile as ProfileBase } from '@sophie/shared'; 21import { Profile as ProfileBase } from '@sophie/shared';
22import { getSnapshot, Instance } from 'mobx-state-tree'; 22import { getSnapshot, Instance } from 'mobx-state-tree';
23 23
24import overrideProps from '../utils/overrideProps';
25
26import ProfileSettings from './ProfileSettings';
27import type ProfileConfig from './config/ProfileConfig'; 24import type ProfileConfig from './config/ProfileConfig';
28 25
29const Profile = overrideProps(ProfileBase, { 26const Profile = ProfileBase.views((self) => ({
30 settings: ProfileSettings,
31}).views((self) => ({
32 get config(): ProfileConfig { 27 get config(): ProfileConfig {
33 const { id, settings } = self; 28 const { id, settings } = self;
34 return { ...getSnapshot(settings), id }; 29 return { ...getSnapshot(settings), id };
diff --git a/packages/main/src/stores/ProfileSettings.ts b/packages/main/src/stores/ProfileSettings.ts
deleted file mode 100644
index eed51e3..0000000
--- a/packages/main/src/stores/ProfileSettings.ts
+++ /dev/null
@@ -1,30 +0,0 @@
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 { ProfileSettings } from '@sophie/shared';
22
23// TODO Export a modified ProfileSettings once we need to add actions to it.
24// eslint-disable-next-line unicorn/prefer-export-from -- Can't export from default.
25export default ProfileSettings;
26
27export type {
28 ProfileSettingsSnapshotIn,
29 ProfileSettingsSnapshotOut,
30} from '@sophie/shared';
diff --git a/packages/main/src/stores/Service.ts b/packages/main/src/stores/Service.ts
index 5302dd4..abef7c2 100644
--- a/packages/main/src/stores/Service.ts
+++ b/packages/main/src/stores/Service.ts
@@ -19,18 +19,15 @@
19 */ 19 */
20 20
21import type { UnreadCount } from '@sophie/service-shared'; 21import type { UnreadCount } from '@sophie/service-shared';
22import { Service as ServiceBase } from '@sophie/shared'; 22import { defineServiceModel } from '@sophie/shared';
23import { Instance, getSnapshot } from 'mobx-state-tree'; 23import { Instance, getSnapshot } from 'mobx-state-tree';
24 24
25import type { ServiceView } from '../infrastructure/electron/types'; 25import type { ServiceView } from '../infrastructure/electron/types';
26import overrideProps from '../utils/overrideProps';
27 26
28import ServiceSettings from './ServiceSettings'; 27import ServiceSettings from './ServiceSettings';
29import type ServiceConfig from './config/ServiceConfig'; 28import type ServiceConfig from './config/ServiceConfig';
30 29
31const Service = overrideProps(ServiceBase, { 30const Service = defineServiceModel(ServiceSettings)
32 settings: ServiceSettings,
33})
34 .views((self) => ({ 31 .views((self) => ({
35 get config(): ServiceConfig { 32 get config(): ServiceConfig {
36 const { id, settings } = self; 33 const { id, settings } = self;
diff --git a/packages/main/src/stores/ServiceSettings.ts b/packages/main/src/stores/ServiceSettings.ts
index e6f48c6..5d37347 100644
--- a/packages/main/src/stores/ServiceSettings.ts
+++ b/packages/main/src/stores/ServiceSettings.ts
@@ -18,16 +18,12 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { ServiceSettings as ServiceSettingsBase } from '@sophie/shared'; 21import { defineServiceSettingsModel } from '@sophie/shared';
22import { Instance, types } from 'mobx-state-tree'; 22import { Instance } from 'mobx-state-tree';
23
24import overrideProps from '../utils/overrideProps';
25 23
26import Profile from './Profile'; 24import Profile from './Profile';
27 25
28const ServiceSettings = overrideProps(ServiceSettingsBase, { 26const ServiceSettings = defineServiceSettingsModel(Profile);
29 profile: types.reference(Profile),
30});
31 27
32/* 28/*
33 eslint-disable-next-line @typescript-eslint/no-redeclare -- 29 eslint-disable-next-line @typescript-eslint/no-redeclare --
diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts
index 182b693..d72c532 100644
--- a/packages/main/src/stores/SharedStore.ts
+++ b/packages/main/src/stores/SharedStore.ts
@@ -18,10 +18,8 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { SharedStore as SharedStoreBase } from '@sophie/shared'; 21import { defineSharedStoreModel } from '@sophie/shared';
22import { getSnapshot, Instance, types } from 'mobx-state-tree'; 22import { getSnapshot, Instance } from 'mobx-state-tree';
23
24import overrideProps from '../utils/overrideProps';
25 23
26import GlobalSettings from './GlobalSettings'; 24import GlobalSettings from './GlobalSettings';
27import Profile from './Profile'; 25import Profile from './Profile';
@@ -33,13 +31,7 @@ function getConfigs<T>(models: { config: T }[]): T[] | undefined {
33 return models.length === 0 ? undefined : models.map((model) => model.config); 31 return models.length === 0 ? undefined : models.map((model) => model.config);
34} 32}
35 33
36const SharedStore = overrideProps(SharedStoreBase, { 34const SharedStore = defineSharedStoreModel(GlobalSettings, Profile, Service)
37 settings: types.optional(GlobalSettings, {}),
38 profilesById: types.map(Profile),
39 profiles: types.array(types.reference(Profile)),
40 servicesById: types.map(Service),
41 services: types.array(types.reference(Service)),
42})
43 .views((self) => ({ 35 .views((self) => ({
44 get config(): Config { 36 get config(): Config {
45 const { settings, profiles, services } = self; 37 const { settings, profiles, services } = self;
diff --git a/packages/main/src/stores/config/loadConfig.ts b/packages/main/src/stores/config/loadConfig.ts
index 55d15c8..2463084 100644
--- a/packages/main/src/stores/config/loadConfig.ts
+++ b/packages/main/src/stores/config/loadConfig.ts
@@ -18,6 +18,7 @@
18 * SPDX-License-Identifier: AGPL-3.0-only 18 * SPDX-License-Identifier: AGPL-3.0-only
19 */ 19 */
20 20
21import { ProfileSettingsSnapshotIn } from '@sophie/shared';
21import { 22import {
22 applySnapshot, 23 applySnapshot,
23 IMSTArray, 24 IMSTArray,
@@ -31,7 +32,6 @@ import slug from 'slug';
31 32
32import GlobalSettings from '../GlobalSettings'; 33import GlobalSettings from '../GlobalSettings';
33import type Profile from '../Profile'; 34import type Profile from '../Profile';
34import type { ProfileSettingsSnapshotIn } from '../ProfileSettings';
35import type Service from '../Service'; 35import type Service from '../Service';
36import type { ServiceSettingsSnapshotIn } from '../ServiceSettings'; 36import type { ServiceSettingsSnapshotIn } from '../ServiceSettings';
37 37
diff --git a/packages/main/src/utils/overrideProps.ts b/packages/main/src/utils/overrideProps.ts
deleted file mode 100644
index c626408..0000000
--- a/packages/main/src/utils/overrideProps.ts
+++ /dev/null
@@ -1,62 +0,0 @@
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
21/**
22 * @file This file implements a technique to force-override properties of a model.
23 *
24 * The overridden properties must conform to the SnapshotIt and SnapshotOut format
25 * of the original model. Essentially, this means that only views and actions can
26 * be added safely.
27 *
28 * @see https://github.com/mobxjs/mobx-state-tree/issues/1403#issuecomment-940843087
29 */
30
31import {
32 IAnyModelType,
33 IModelType,
34 ModelProperties,
35 SnapshotIn,
36 SnapshotOut,
37} from 'mobx-state-tree';
38
39export type IUnsafeOverriddenModelType<
40 BASE extends IAnyModelType,
41 PROPS extends ModelProperties,
42> = BASE extends IModelType<infer P, infer O, infer CC, infer CS>
43 ? IModelType<Omit<P, keyof PROPS> & PROPS, O, CC, CS>
44 : never;
45
46export type IOverriddenModelType<
47 BASE extends IAnyModelType,
48 PROPS extends ModelProperties,
49> = SnapshotIn<BASE> extends SnapshotIn<IUnsafeOverriddenModelType<BASE, PROPS>>
50 ? SnapshotOut<
51 IUnsafeOverriddenModelType<BASE, PROPS>
52 > extends SnapshotOut<BASE>
53 ? IUnsafeOverriddenModelType<BASE, PROPS>
54 : never
55 : never;
56
57export default function overrideProps<
58 BASE extends IAnyModelType,
59 PROPS extends ModelProperties,
60>(base: BASE, props: PROPS): IOverriddenModelType<BASE, PROPS> {
61 return base.props(props) as IOverriddenModelType<BASE, PROPS>;
62}