aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores/UIStore.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores/UIStore.js')
-rw-r--r--src/stores/UIStore.js134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js
new file mode 100644
index 000000000..779f89b9f
--- /dev/null
+++ b/src/stores/UIStore.js
@@ -0,0 +1,134 @@
1import { action, observable, computed, reaction } from 'mobx';
2import { nativeTheme, systemPreferences } from '@electron/remote';
3
4import { theme, ThemeType } from '../themes';
5import Store from './lib/Store';
6import { isMac, isWindows } from '../environment';
7
8export default class UIStore extends Store {
9 @observable showServicesUpdatedInfoBar = false;
10
11 @observable isOsDarkThemeActive = nativeTheme.shouldUseDarkColors;
12
13 constructor(...args) {
14 super(...args);
15
16 // Register action handlers
17 this.actions.ui.openSettings.listen(this._openSettings.bind(this));
18 this.actions.ui.closeSettings.listen(this._closeSettings.bind(this));
19 this.actions.ui.toggleServiceUpdatedInfoBar.listen(
20 this._toggleServiceUpdatedInfoBar.bind(this),
21 );
22
23 // Listen for theme change on MacOS
24 if (isMac) {
25 systemPreferences.subscribeNotification(
26 'AppleInterfaceThemeChangedNotification',
27 () => {
28 this.isOsDarkThemeActive = nativeTheme.shouldUseDarkColors;
29 this.actions.service.shareSettingsWithServiceProcess();
30 },
31 );
32 }
33
34 if (isWindows) {
35 nativeTheme.on('updated', () => {
36 this.isOsDarkThemeActive = nativeTheme.shouldUseDarkColors;
37 this.actions.service.shareSettingsWithServiceProcess();
38 });
39 }
40 }
41
42 setup() {
43 reaction(
44 () => this.isDarkThemeActive,
45 () => {
46 this._setupThemeInDOM();
47 },
48 { fireImmediately: true },
49 );
50 reaction(
51 () => this.isSplitModeActive,
52 () => {
53 this._setupModeInDOM();
54 },
55 { fireImmediately: true },
56 );
57 }
58
59 @computed get showMessageBadgesEvenWhenMuted() {
60 const settings = this.stores.settings.all;
61
62 return (
63 (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) ||
64 !settings.app.isAppMuted
65 );
66 }
67
68 @computed get isDarkThemeActive() {
69 const isWithAdaptableInDarkMode =
70 this.stores.settings.all.app.adaptableDarkMode &&
71 this.isOsDarkThemeActive;
72 const isWithoutAdaptableInDarkMode =
73 this.stores.settings.all.app.darkMode &&
74 !this.stores.settings.all.app.adaptableDarkMode;
75 const isInDarkMode = this.stores.settings.all.app.darkMode;
76 return !!(
77 isWithAdaptableInDarkMode ||
78 isWithoutAdaptableInDarkMode ||
79 isInDarkMode
80 );
81 }
82
83 @computed get isSplitModeActive() {
84 return this.stores.settings.app.splitMode;
85 }
86
87 @computed get theme() {
88 const themeId =
89 this.isDarkThemeActive || this.stores.settings.app.darkMode
90 ? ThemeType.dark
91 : ThemeType.default;
92 const { accentColor } = this.stores.settings.app;
93 return theme(themeId, accentColor);
94 }
95
96 // Actions
97 @action _openSettings({ path = '/settings' }) {
98 const settingsPath = path !== '/settings' ? `/settings/${path}` : path;
99 this.stores.router.push(settingsPath);
100 }
101
102 @action _closeSettings() {
103 this.stores.router.push('/');
104 }
105
106 @action _toggleServiceUpdatedInfoBar({ visible }) {
107 let visibility = visible;
108 if (visibility === null) {
109 visibility = !this.showServicesUpdatedInfoBar;
110 }
111 this.showServicesUpdatedInfoBar = visibility;
112 }
113
114 // Reactions
115 _setupThemeInDOM() {
116 const body = document.querySelector('body');
117
118 if (!this.isDarkThemeActive) {
119 body?.classList.remove('theme__dark');
120 } else {
121 body?.classList.add('theme__dark');
122 }
123 }
124
125 _setupModeInDOM() {
126 const body = document.querySelector('body');
127
128 if (!this.isSplitModeActive) {
129 body?.classList.remove('mode__split');
130 } else {
131 body?.classList.add('mode__split');
132 }
133 }
134}