From 24bbe1f574ee6b0d6d0ebc8c29cbf014fc450584 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Fri, 28 Jan 2022 01:07:56 +0100 Subject: feat: Save selected service to file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sophie start off from the service that was selected when it was last open. Signed-off-by: Kristóf Marussy --- packages/main/src/index.ts | 2 +- .../src/infrastructure/config/impl/ConfigFile.ts | 4 ++-- packages/main/src/reactions/synchronizeConfig.ts | 5 +++- packages/main/src/stores/GlobalSettings.ts | 22 +++++++++++++++-- packages/main/src/stores/SharedStore.ts | 13 ---------- packages/main/src/stores/config/loadConfig.ts | 28 +++++++++------------- .../renderer/src/components/ServiceSwitcher.tsx | 5 +++- packages/renderer/src/stores/RendererStore.ts | 7 +++--- packages/shared/src/stores/GlobalSettings.ts | 3 +++ packages/shared/src/stores/SharedStore.ts | 1 - 10 files changed, 49 insertions(+), 41 deletions(-) diff --git a/packages/main/src/index.ts b/packages/main/src/index.ts index 2072017..f5f6be4 100644 --- a/packages/main/src/index.ts +++ b/packages/main/src/index.ts @@ -205,7 +205,7 @@ async function createWindow(): Promise { const actionToDispatch = Action.parse(rawAction); switch (actionToDispatch.action) { case 'set-selected-service-id': - store.shared.setSelectedServiceId(actionToDispatch.serviceId); + store.settings.setSelectedServiceId(actionToDispatch.serviceId); break; case 'set-browser-view-bounds': store.setBrowserViewBounds(actionToDispatch.browserViewBounds); diff --git a/packages/main/src/infrastructure/config/impl/ConfigFile.ts b/packages/main/src/infrastructure/config/impl/ConfigFile.ts index 90ee187..e8237b4 100644 --- a/packages/main/src/infrastructure/config/impl/ConfigFile.ts +++ b/packages/main/src/infrastructure/config/impl/ConfigFile.ts @@ -29,7 +29,7 @@ import type Config from '../../../stores/config/Config'; import type Disposer from '../../../utils/Disposer'; import { getLogger } from '../../../utils/log'; import type ConfigRepository from '../ConfigRepository'; -import type ReadConfigResult from '../ReadConfigResult'; +import type { ReadConfigResult } from '../ConfigRepository'; const log = getLogger('ConfigFile'); @@ -81,7 +81,7 @@ export default class ConfigFile implements ConfigRepository { } finally { this.#writingConfig = false; } - log.info('Wrote config file', this.#configFilePath); + log.debug('Wrote config file', this.#configFilePath); } watchConfig(callback: () => Promise, throttleMs: number): Disposer { diff --git a/packages/main/src/reactions/synchronizeConfig.ts b/packages/main/src/reactions/synchronizeConfig.ts index 4a9c24b..9436c16 100644 --- a/packages/main/src/reactions/synchronizeConfig.ts +++ b/packages/main/src/reactions/synchronizeConfig.ts @@ -58,6 +58,9 @@ export default async function synchronizeConfig( return true; } lastConfigOnDisk = sharedStore.config; + // We can't use `comparer.structural` from `mobx`, because + // it handles missing values and `undefined` values differently, + // but JSON5 is unable to distinguish them. if (!deepEqual(result.data, lastConfigOnDisk, { strict: true })) { await writeConfig(); } @@ -75,7 +78,7 @@ export default async function synchronizeConfig( () => sharedStore.config, debounce((config) => { // We can compare snapshots by reference, since it is only recreated on store changes. - if (lastConfigOnDisk !== config) { + if (!deepEqual(config, lastConfigOnDisk, { strict: true })) { writeConfig().catch((error) => { log.error('Failed to write config on config change', error); }); diff --git a/packages/main/src/stores/GlobalSettings.ts b/packages/main/src/stores/GlobalSettings.ts index 0a54aa3..7bbc089 100644 --- a/packages/main/src/stores/GlobalSettings.ts +++ b/packages/main/src/stores/GlobalSettings.ts @@ -22,12 +22,30 @@ import { GlobalSettings as GlobalSettingsBase, ThemeSource, } from '@sophie/shared'; -import { Instance } from 'mobx-state-tree'; +import { Instance, resolveIdentifier, types } from 'mobx-state-tree'; -const GlobalSettings = GlobalSettingsBase.actions((self) => ({ +import { getLogger } from '../utils/log'; +import overrideProps from '../utils/overrideProps'; + +import Service from './Service'; + +const log = getLogger('sharedStore'); + +const GlobalSettings = overrideProps(GlobalSettingsBase, { + selectedService: types.safeReference(Service), +}).actions((self) => ({ setThemeSource(mode: ThemeSource): void { self.themeSource = mode; }, + setSelectedServiceId(serviceId: string): void { + const serviceInstance = resolveIdentifier(Service, self, serviceId); + if (serviceInstance === undefined) { + log.warn('Trying to select unknown service', serviceId); + return; + } + self.selectedService = serviceInstance; + log.debug('Selected service', serviceId); + }, })); /* diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts index b9983f6..182b693 100644 --- a/packages/main/src/stores/SharedStore.ts +++ b/packages/main/src/stores/SharedStore.ts @@ -21,7 +21,6 @@ import { SharedStore as SharedStoreBase } from '@sophie/shared'; import { getSnapshot, Instance, types } from 'mobx-state-tree'; -import { getLogger } from '../utils/log'; import overrideProps from '../utils/overrideProps'; import GlobalSettings from './GlobalSettings'; @@ -30,8 +29,6 @@ import Service from './Service'; import type Config from './config/Config'; import loadConfig from './config/loadConfig'; -const log = getLogger('sharedStore'); - function getConfigs(models: { config: T }[]): T[] | undefined { return models.length === 0 ? undefined : models.map((model) => model.config); } @@ -42,7 +39,6 @@ const SharedStore = overrideProps(SharedStoreBase, { profiles: types.array(types.reference(Profile)), servicesById: types.map(Service), services: types.array(types.reference(Service)), - selectedService: types.safeReference(Service), }) .views((self) => ({ get config(): Config { @@ -62,15 +58,6 @@ const SharedStore = overrideProps(SharedStoreBase, { setShouldUseDarkColors(shouldUseDarkColors: boolean): void { self.shouldUseDarkColors = shouldUseDarkColors; }, - setSelectedServiceId(serviceId: string): void { - const serviceInstance = self.servicesById.get(serviceId); - if (serviceInstance === undefined) { - log.warn('Trying to select unknown service', serviceId); - return; - } - self.selectedService = serviceInstance; - log.debug('Selected service', serviceId); - }, })); /* diff --git a/packages/main/src/stores/config/loadConfig.ts b/packages/main/src/stores/config/loadConfig.ts index 770d675..55d15c8 100644 --- a/packages/main/src/stores/config/loadConfig.ts +++ b/packages/main/src/stores/config/loadConfig.ts @@ -106,22 +106,13 @@ export default function loadConfig( target: { readonly profiles: IMSTArray>; readonly profilesById: IMSTMap; - selectedService: Service | undefined; readonly services: IMSTArray>; readonly servicesById: IMSTMap; readonly settings: GlobalSettings; }, config: Config, ): void { - const { - profiles, - profilesById, - selectedService, - services, - servicesById, - settings, - } = target; - const { id: selectedServiceId } = selectedService ?? { id: undefined }; + const { profiles, profilesById, services, servicesById, settings } = target; const { profiles: profilesConfig, services: servicesConfig, @@ -134,13 +125,16 @@ export default function loadConfig( ); applySettings(profiles, profilesById, profilesToApply); applySettings(services, servicesById, servicesToApply); - applySnapshot(settings, settingsToApply); - let newSelectedService: Service | undefined; - if (selectedServiceId !== undefined) { - newSelectedService = servicesById.get(selectedServiceId); + const { selectedService } = settingsToApply; + // Be more robust against when a deleted service is selected. + if ( + typeof selectedService !== 'string' || + !servicesById.has(selectedService) + ) { + settingsToApply.selectedService = undefined; } - if (newSelectedService === undefined && services.length > 0) { - [newSelectedService] = services; + applySnapshot(settings, settingsToApply); + if (settings.selectedService === undefined && services.length > 0) { + [settings.selectedService] = services; } - target.selectedService = newSelectedService; } diff --git a/packages/renderer/src/components/ServiceSwitcher.tsx b/packages/renderer/src/components/ServiceSwitcher.tsx index 167153f..e4d371e 100644 --- a/packages/renderer/src/components/ServiceSwitcher.tsx +++ b/packages/renderer/src/components/ServiceSwitcher.tsx @@ -63,7 +63,10 @@ const ServiceSwitcherTab = styled(Tab, { export default observer(() => { const store = useStore(); - const { selectedService, services } = store; + const { + settings: { selectedService }, + services, + } = store; return ( ({ + get settings(): GlobalSettings { + return self.shared.settings; + }, get services(): Service[] { return self.shared.services; }, - get selectedService(): Service | undefined { - return self.shared.selectedService; - }, })) .actions((self) => ({ setSelectedServiceId(serviceId: string): void { diff --git a/packages/shared/src/stores/GlobalSettings.ts b/packages/shared/src/stores/GlobalSettings.ts index 1c6d7f3..7a2c334 100644 --- a/packages/shared/src/stores/GlobalSettings.ts +++ b/packages/shared/src/stores/GlobalSettings.ts @@ -22,12 +22,15 @@ import { Instance, types, SnapshotIn, SnapshotOut } from 'mobx-state-tree'; import { ThemeSource } from '../schemas'; +import Service from './Service'; + const GlobalSettings = /* @__PURE__ */ (() => types.model('GlobalSettings', { themeSource: types.optional( types.enumeration(ThemeSource.options), 'system', ), + selectedService: types.safeReference(Service), }))(); /* diff --git a/packages/shared/src/stores/SharedStore.ts b/packages/shared/src/stores/SharedStore.ts index 4e064c6..d81a3d3 100644 --- a/packages/shared/src/stores/SharedStore.ts +++ b/packages/shared/src/stores/SharedStore.ts @@ -37,7 +37,6 @@ const SharedStore = /* @__PURE__ */ (() => profiles: types.array(types.reference(Profile)), servicesById: types.map(Service), services: types.array(types.reference(Service)), - selectedService: types.safeReference(Service), shouldUseDarkColors: false, }))(); -- cgit v1.2.3-54-g00ecf