diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-03-29 18:19:39 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-05-16 00:54:56 +0200 |
commit | a35d560f8d1ca414e3ba387b50731ca099e2da47 (patch) | |
tree | 5a8a90345c04eb0b69ea3fca8185641e26905b5d /packages/main/src/stores/SharedStore.ts | |
parent | feat: New window banner (diff) | |
download | sophie-a35d560f8d1ca414e3ba387b50731ca099e2da47.tar.gz sophie-a35d560f8d1ca414e3ba387b50731ca099e2da47.tar.zst sophie-a35d560f8d1ca414e3ba387b50731ca099e2da47.zip |
feat: Add custom menubar
The menu is populated reactive from the store with no caching.
This doesn't seem to cause any performance problems so far.
Currently the menu is electron-specific.
In the future, we'll need a more runtime-independent way to build the
menu.
Signed-off-by: Kristóf Marussy <kristof@marussy.com>
Diffstat (limited to 'packages/main/src/stores/SharedStore.ts')
-rw-r--r-- | packages/main/src/stores/SharedStore.ts | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/packages/main/src/stores/SharedStore.ts b/packages/main/src/stores/SharedStore.ts index d72c532..67d58d6 100644 --- a/packages/main/src/stores/SharedStore.ts +++ b/packages/main/src/stores/SharedStore.ts | |||
@@ -21,12 +21,16 @@ | |||
21 | import { defineSharedStoreModel } from '@sophie/shared'; | 21 | import { defineSharedStoreModel } from '@sophie/shared'; |
22 | import { getSnapshot, Instance } from 'mobx-state-tree'; | 22 | import { getSnapshot, Instance } from 'mobx-state-tree'; |
23 | 23 | ||
24 | import { getLogger } from '../utils/log'; | ||
25 | |||
24 | import GlobalSettings from './GlobalSettings'; | 26 | import GlobalSettings from './GlobalSettings'; |
25 | import Profile from './Profile'; | 27 | import Profile from './Profile'; |
26 | import Service from './Service'; | 28 | import Service from './Service'; |
27 | import type Config from './config/Config'; | 29 | import type Config from './config/Config'; |
28 | import loadConfig from './config/loadConfig'; | 30 | import loadConfig from './config/loadConfig'; |
29 | 31 | ||
32 | const log = getLogger('SharedStore'); | ||
33 | |||
30 | function getConfigs<T>(models: { config: T }[]): T[] | undefined { | 34 | function getConfigs<T>(models: { config: T }[]): T[] | undefined { |
31 | return models.length === 0 ? undefined : models.map((model) => model.config); | 35 | return models.length === 0 ? undefined : models.map((model) => model.config); |
32 | } | 36 | } |
@@ -42,6 +46,19 @@ const SharedStore = defineSharedStoreModel(GlobalSettings, Profile, Service) | |||
42 | services: getConfigs(services), | 46 | services: getConfigs(services), |
43 | }; | 47 | }; |
44 | }, | 48 | }, |
49 | get canSwitchServices(): boolean { | ||
50 | return self.services.length >= 2; | ||
51 | }, | ||
52 | get selectedServiceIndex(): number { | ||
53 | const { | ||
54 | services, | ||
55 | settings: { selectedService }, | ||
56 | } = self; | ||
57 | if (selectedService === undefined) { | ||
58 | return -1; | ||
59 | } | ||
60 | return services.indexOf(selectedService); | ||
61 | }, | ||
45 | })) | 62 | })) |
46 | .actions((self) => ({ | 63 | .actions((self) => ({ |
47 | loadConfig(config: Config): void { | 64 | loadConfig(config: Config): void { |
@@ -50,6 +67,42 @@ const SharedStore = defineSharedStoreModel(GlobalSettings, Profile, Service) | |||
50 | setShouldUseDarkColors(shouldUseDarkColors: boolean): void { | 67 | setShouldUseDarkColors(shouldUseDarkColors: boolean): void { |
51 | self.shouldUseDarkColors = shouldUseDarkColors; | 68 | self.shouldUseDarkColors = shouldUseDarkColors; |
52 | }, | 69 | }, |
70 | activateServiceByOffset(offset: number): void { | ||
71 | if (offset === 0) { | ||
72 | return; | ||
73 | } | ||
74 | const { selectedServiceIndex: index, services, settings } = self; | ||
75 | if (index < 0) { | ||
76 | log.warn('No selected service to offset'); | ||
77 | return; | ||
78 | } | ||
79 | const { length } = services; | ||
80 | const indexWithOffset = (index + offset) % length; | ||
81 | // Make sure that `newIndex` is positive even for large negative `offset`. | ||
82 | const newIndex = | ||
83 | indexWithOffset < 0 ? indexWithOffset + length : indexWithOffset; | ||
84 | const newService = services.at(newIndex); | ||
85 | if (newService === undefined) { | ||
86 | log.error( | ||
87 | 'Could not advance selected service index from', | ||
88 | index, | ||
89 | 'by', | ||
90 | offset, | ||
91 | 'to', | ||
92 | newIndex, | ||
93 | ); | ||
94 | return; | ||
95 | } | ||
96 | settings.setSelectedService(newService); | ||
97 | }, | ||
98 | })) | ||
99 | .actions((self) => ({ | ||
100 | activateNextService(): void { | ||
101 | self.activateServiceByOffset(1); | ||
102 | }, | ||
103 | activatePreviousService(): void { | ||
104 | self.activateServiceByOffset(-1); | ||
105 | }, | ||
53 | })); | 106 | })); |
54 | 107 | ||
55 | /* | 108 | /* |