aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2018-03-27 21:25:56 +0200
committerLibravatar Stefan Malzner <stefan@adlk.io>2018-03-27 21:25:56 +0200
commit8aab8699e02ed9ec736bb6dfab0edd3fe9156c8d (patch)
tree9b853e0d343f4bf2f60625431275bdc2dd08e027
parentMove "locale" to user data (diff)
downloadferdium-app-8aab8699e02ed9ec736bb6dfab0edd3fe9156c8d.tar.gz
ferdium-app-8aab8699e02ed9ec736bb6dfab0edd3fe9156c8d.tar.zst
ferdium-app-8aab8699e02ed9ec736bb6dfab0edd3fe9156c8d.zip
Split settings into multiple stores; app specific settings are now stored in config file
-rw-r--r--src/actions/settings.js4
-rw-r--r--src/api/LocalApi.js8
-rw-r--r--src/api/server/LocalApi.js19
-rw-r--r--src/config.js8
-rw-r--r--src/containers/layout/AppLayoutContainer.js6
-rw-r--r--src/containers/settings/EditSettingsScreen.js32
-rw-r--r--src/electron/Settings.js34
-rw-r--r--src/electron/ipc-api/settings.js8
-rw-r--r--src/models/Settings.js43
-rw-r--r--src/stores/AppStore.js17
-rw-r--r--src/stores/ServicesStore.js15
-rw-r--r--src/stores/SettingsStore.js41
-rw-r--r--src/stores/UIStore.js2
13 files changed, 164 insertions, 73 deletions
diff --git a/src/actions/settings.js b/src/actions/settings.js
index 3d53cd674..fd29b798b 100644
--- a/src/actions/settings.js
+++ b/src/actions/settings.js
@@ -2,9 +2,11 @@ import PropTypes from 'prop-types';
2 2
3export default { 3export default {
4 update: { 4 update: {
5 settings: PropTypes.object.isRequired, 5 type: PropTypes.string.isRequired,
6 data: PropTypes.object.isRequired,
6 }, 7 },
7 remove: { 8 remove: {
9 type: PropTypes.string.isRequired,
8 key: PropTypes.string.isRequired, 10 key: PropTypes.string.isRequired,
9 }, 11 },
10}; 12};
diff --git a/src/api/LocalApi.js b/src/api/LocalApi.js
index 59d7d8fa2..741917104 100644
--- a/src/api/LocalApi.js
+++ b/src/api/LocalApi.js
@@ -4,6 +4,14 @@ export default class LocalApi {
4 this.local = local; 4 this.local = local;
5 } 5 }
6 6
7 getAppSettings() {
8 return this.local.getAppSettings();
9 }
10
11 updateAppSettings(data) {
12 return this.local.updateAppSettings(data);
13 }
14
7 getAppCacheSize() { 15 getAppCacheSize() {
8 return this.local.getAppCacheSize(); 16 return this.local.getAppCacheSize();
9 } 17 }
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js
index 4d2497c61..78deb7aa5 100644
--- a/src/api/server/LocalApi.js
+++ b/src/api/server/LocalApi.js
@@ -1,4 +1,4 @@
1import { remote } from 'electron'; 1import { ipcRenderer, remote } from 'electron';
2import du from 'du'; 2import du from 'du';
3 3
4import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js'; 4import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js';
@@ -8,6 +8,23 @@ const debug = require('debug')('LocalApi');
8const { session } = remote; 8const { session } = remote;
9 9
10export default class LocalApi { 10export default class LocalApi {
11 // Settings
12 getAppSettings() {
13 return new Promise((resolve) => {
14 ipcRenderer.once('appSettings', (event, data) => {
15 debug('LocalApi::getAppSettings resolves', data);
16 resolve(data);
17 });
18
19 ipcRenderer.send('getAppSettings');
20 });
21 }
22
23 async updateAppSettings(data) {
24 debug('LocalApi::updateAppSettings resolves', data);
25 ipcRenderer.send('updateAppSettings', data);
26 }
27
11 // Services 28 // Services
12 async getAppCacheSize() { 29 async getAppCacheSize() {
13 const partitionsDir = getServicePartitionsDirectory(); 30 const partitionsDir = getServicePartitionsDirectory();
diff --git a/src/config.js b/src/config.js
index e66594c59..366231f79 100644
--- a/src/config.js
+++ b/src/config.js
@@ -1,3 +1,8 @@
1import electron from 'electron';
2import path from 'path';
3
4const app = process.type === 'renderer' ? electron.remote.app : electron.app;
5
1export const CHECK_INTERVAL = 1000 * 3600; // How often should we perform checks 6export const CHECK_INTERVAL = 1000 * 3600; // How often should we perform checks
2export const LOCAL_API = 'http://localhost:3000'; 7export const LOCAL_API = 'http://localhost:3000';
3export const DEV_API = 'https://dev.franzinfra.com'; 8export const DEV_API = 'https://dev.franzinfra.com';
@@ -13,7 +18,6 @@ export const DEFAULT_APP_SETTINGS = {
13 showDisabledServices: true, 18 showDisabledServices: true,
14 showMessageBadgeWhenMuted: true, 19 showMessageBadgeWhenMuted: true,
15 enableSpellchecking: true, 20 enableSpellchecking: true,
16 // spellcheckingLanguage: 'auto',
17 locale: '', 21 locale: '',
18 fallbackLocale: 'en-US', 22 fallbackLocale: 'en-US',
19 beta: false, 23 beta: false,
@@ -22,3 +26,5 @@ export const DEFAULT_APP_SETTINGS = {
22 26
23export const FRANZ_SERVICE_REQUEST = 'http://bit.ly/franz-service-request'; 27export const FRANZ_SERVICE_REQUEST = 'http://bit.ly/franz-service-request';
24export const FRANZ_TRANSLATION = 'http://bit.ly/franz-translate'; 28export const FRANZ_TRANSLATION = 'http://bit.ly/franz-translate';
29
30export const SETTINGS_PATH = path.join(app.getPath('userData'), 'config', 'settings.json');
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 075bd5e34..0931738fd 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -77,7 +77,7 @@ export default class AppLayoutContainer extends Component {
77 <Sidebar 77 <Sidebar
78 services={services.allDisplayed} 78 services={services.allDisplayed}
79 setActive={setActive} 79 setActive={setActive}
80 isAppMuted={settings.all.isAppMuted} 80 isAppMuted={settings.all.app.isAppMuted}
81 openSettings={openSettings} 81 openSettings={openSettings}
82 closeSettings={closeSettings} 82 closeSettings={closeSettings}
83 reorder={reorder} 83 reorder={reorder}
@@ -87,7 +87,7 @@ export default class AppLayoutContainer extends Component {
87 deleteService={deleteService} 87 deleteService={deleteService}
88 updateService={updateService} 88 updateService={updateService}
89 toggleMuteApp={toggleMuteApp} 89 toggleMuteApp={toggleMuteApp}
90 showMessageBadgeWhenMutedSetting={settings.all.showMessageBadgeWhenMuted} 90 showMessageBadgeWhenMutedSetting={settings.all.app.showMessageBadgeWhenMuted}
91 showMessageBadgesEvenWhenMuted={ui.showMessageBadgesEvenWhenMuted} 91 showMessageBadgesEvenWhenMuted={ui.showMessageBadgesEvenWhenMuted}
92 /> 92 />
93 ); 93 );
@@ -99,7 +99,7 @@ export default class AppLayoutContainer extends Component {
99 setWebviewReference={setWebviewReference} 99 setWebviewReference={setWebviewReference}
100 openWindow={openWindow} 100 openWindow={openWindow}
101 reload={reload} 101 reload={reload}
102 isAppMuted={settings.all.isAppMuted} 102 isAppMuted={settings.all.app.isAppMuted}
103 update={updateService} 103 update={updateService}
104 /> 104 />
105 ); 105 );
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index e67c2964b..1bd147099 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -55,10 +55,6 @@ const messages = defineMessages({
55 id: 'settings.app.form.spellcheckingLanguage', 55 id: 'settings.app.form.spellcheckingLanguage',
56 defaultMessage: '!!!Language for spell checking', 56 defaultMessage: '!!!Language for spell checking',
57 }, 57 },
58 // spellcheckingAutomaticDetection: {
59 // id: 'settings.app.form.spellcheckingAutomaticDetection',
60 // defaultMessage: '!!!Detect language automatically',
61 // },
62 beta: { 58 beta: {
63 id: 'settings.app.form.beta', 59 id: 'settings.app.form.beta',
64 defaultMessage: '!!!Include beta versions', 60 defaultMessage: '!!!Include beta versions',
@@ -84,13 +80,16 @@ export default class EditSettingsScreen extends Component {
84 }); 80 });
85 81
86 settings.update({ 82 settings.update({
87 settings: { 83 type: 'app',
84 data: {
88 runInBackground: settingsData.runInBackground, 85 runInBackground: settingsData.runInBackground,
89 enableSystemTray: settingsData.enableSystemTray, 86 enableSystemTray: settingsData.enableSystemTray,
90 minimizeToSystemTray: settingsData.minimizeToSystemTray, 87 minimizeToSystemTray: settingsData.minimizeToSystemTray,
91 showDisabledServices: settingsData.showDisabledServices, 88 showDisabledServices: settingsData.showDisabledServices,
92 showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted, 89 showMessageBadgeWhenMuted: settingsData.showMessageBadgeWhenMuted,
93 enableSpellchecking: settingsData.enableSpellchecking, 90 enableSpellchecking: settingsData.enableSpellchecking,
91 beta: settingsData.beta, // we need this info in the main process as well
92 locale: settingsData.locale, // we need this info in the main process as well
94 }, 93 },
95 }); 94 });
96 95
@@ -114,17 +113,6 @@ export default class EditSettingsScreen extends Component {
114 }); 113 });
115 }); 114 });
116 115
117 // const spellcheckerLocales = [{
118 // value: 'auto',
119 // label: intl.formatMessage(messages.spellcheckingAutomaticDetection),
120 // }];
121 // Object.keys(SPELLCHECKER_LOCALES).forEach((key) => {
122 // spellcheckerLocales.push({
123 // value: key,
124 // label: SPELLCHECKER_LOCALES[key],
125 // });
126 // });
127
128 const config = { 116 const config = {
129 fields: { 117 fields: {
130 autoLaunchOnStart: { 118 autoLaunchOnStart: {
@@ -139,32 +127,32 @@ export default class EditSettingsScreen extends Component {
139 }, 127 },
140 runInBackground: { 128 runInBackground: {
141 label: intl.formatMessage(messages.runInBackground), 129 label: intl.formatMessage(messages.runInBackground),
142 value: settings.all.runInBackground, 130 value: settings.all.app.runInBackground,
143 default: DEFAULT_APP_SETTINGS.runInBackground, 131 default: DEFAULT_APP_SETTINGS.runInBackground,
144 }, 132 },
145 enableSystemTray: { 133 enableSystemTray: {
146 label: intl.formatMessage(messages.enableSystemTray), 134 label: intl.formatMessage(messages.enableSystemTray),
147 value: settings.all.enableSystemTray, 135 value: settings.all.app.enableSystemTray,
148 default: DEFAULT_APP_SETTINGS.enableSystemTray, 136 default: DEFAULT_APP_SETTINGS.enableSystemTray,
149 }, 137 },
150 minimizeToSystemTray: { 138 minimizeToSystemTray: {
151 label: intl.formatMessage(messages.minimizeToSystemTray), 139 label: intl.formatMessage(messages.minimizeToSystemTray),
152 value: settings.all.minimizeToSystemTray, 140 value: settings.all.app.minimizeToSystemTray,
153 default: DEFAULT_APP_SETTINGS.minimizeToSystemTray, 141 default: DEFAULT_APP_SETTINGS.minimizeToSystemTray,
154 }, 142 },
155 showDisabledServices: { 143 showDisabledServices: {
156 label: intl.formatMessage(messages.showDisabledServices), 144 label: intl.formatMessage(messages.showDisabledServices),
157 value: settings.all.showDisabledServices, 145 value: settings.all.app.showDisabledServices,
158 default: DEFAULT_APP_SETTINGS.showDisabledServices, 146 default: DEFAULT_APP_SETTINGS.showDisabledServices,
159 }, 147 },
160 showMessageBadgeWhenMuted: { 148 showMessageBadgeWhenMuted: {
161 label: intl.formatMessage(messages.showMessageBadgeWhenMuted), 149 label: intl.formatMessage(messages.showMessageBadgeWhenMuted),
162 value: settings.all.showMessageBadgeWhenMuted, 150 value: settings.all.app.showMessageBadgeWhenMuted,
163 default: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted, 151 default: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted,
164 }, 152 },
165 enableSpellchecking: { 153 enableSpellchecking: {
166 label: intl.formatMessage(messages.enableSpellchecking), 154 label: intl.formatMessage(messages.enableSpellchecking),
167 value: settings.all.enableSpellchecking, 155 value: settings.all.app.enableSpellchecking,
168 default: DEFAULT_APP_SETTINGS.enableSpellchecking, 156 default: DEFAULT_APP_SETTINGS.enableSpellchecking,
169 }, 157 },
170 locale: { 158 locale: {
diff --git a/src/electron/Settings.js b/src/electron/Settings.js
index 824b4c20c..e24aefdbb 100644
--- a/src/electron/Settings.js
+++ b/src/electron/Settings.js
@@ -1,27 +1,53 @@
1import { observable } from 'mobx'; 1import { observable, toJS } from 'mobx';
2import { pathExistsSync, outputJsonSync, readJsonSync } from 'fs-extra';
2 3
3import { DEFAULT_APP_SETTINGS } from '../config'; 4import { SETTINGS_PATH, DEFAULT_APP_SETTINGS } from '../config';
5
6const debug = require('debug')('Settings');
4 7
5export default class Settings { 8export default class Settings {
6 @observable store = { 9 @observable store = {
7 autoLaunchOnStart: DEFAULT_APP_SETTINGS.autoLaunchOnStart,
8 autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground, 10 autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground,
9 runInBackground: DEFAULT_APP_SETTINGS.runInBackground, 11 runInBackground: DEFAULT_APP_SETTINGS.runInBackground,
10 enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray, 12 enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray,
11 minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray, 13 minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray,
12 locale: DEFAULT_APP_SETTINGS.locale, 14 locale: DEFAULT_APP_SETTINGS.locale,
13 beta: DEFAULT_APP_SETTINGS.beta, 15 beta: DEFAULT_APP_SETTINGS.beta,
16 isAppMuted: DEFAULT_APP_SETTINGS.isAppMuted,
17 showMessageBadgeWhenMuted: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted,
18 showDisabledServices: DEFAULT_APP_SETTINGS.showDisabledServices,
19 enableSpellchecking: DEFAULT_APP_SETTINGS.enableSpellchecking,
14 }; 20 };
15 21
22 constructor() {
23 if (!pathExistsSync(SETTINGS_PATH)) {
24 this._writeFile();
25 } else {
26 this._hydrate();
27 }
28 }
29
16 set(settings) { 30 set(settings) {
17 this.store = Object.assign(this.store, settings); 31 this.store = Object.assign(this.store, settings);
32
33 this._writeFile();
18 } 34 }
19 35
20 all() { 36 get all() {
21 return this.store; 37 return this.store;
22 } 38 }
23 39
24 get(key) { 40 get(key) {
25 return this.store[key]; 41 return this.store[key];
26 } 42 }
43
44 _hydrate() {
45 this.store = readJsonSync(SETTINGS_PATH);
46 debug('Hydrate store', toJS(this.store));
47 }
48
49 _writeFile() {
50 outputJsonSync(SETTINGS_PATH, this.store);
51 debug('Write settings file', toJS(this.store));
52 }
27} 53}
diff --git a/src/electron/ipc-api/settings.js b/src/electron/ipc-api/settings.js
index 995b28fbd..00bdc0113 100644
--- a/src/electron/ipc-api/settings.js
+++ b/src/electron/ipc-api/settings.js
@@ -4,4 +4,12 @@ export default (params) => {
4 ipcMain.on('settings', (event, args) => { 4 ipcMain.on('settings', (event, args) => {
5 params.settings.set(args); 5 params.settings.set(args);
6 }); 6 });
7
8 ipcMain.on('getAppSettings', () => {
9 params.mainWindow.webContents.send('appSettings', params.settings.all);
10 });
11
12 ipcMain.on('updateAppSettings', (event, args) => {
13 params.settings.set(args);
14 });
7}; 15};
diff --git a/src/models/Settings.js b/src/models/Settings.js
index e39b63087..f58c05b38 100644
--- a/src/models/Settings.js
+++ b/src/models/Settings.js
@@ -2,19 +2,38 @@ import { observable, extendObservable } from 'mobx';
2import { DEFAULT_APP_SETTINGS } from '../config'; 2import { DEFAULT_APP_SETTINGS } from '../config';
3 3
4export default class Settings { 4export default class Settings {
5 @observable autoLaunchInBackground = DEFAULT_APP_SETTINGS.autoLaunchInBackground; 5 @observable app = {
6 @observable runInBackground = DEFAULT_APP_SETTINGS.runInBackground; 6 autoLaunchInBackground: DEFAULT_APP_SETTINGS.autoLaunchInBackground,
7 @observable enableSystemTray = DEFAULT_APP_SETTINGS.enableSystemTray; 7 runInBackground: DEFAULT_APP_SETTINGS.runInBackground,
8 @observable minimizeToSystemTray = DEFAULT_APP_SETTINGS.minimizeToSystemTray; 8 enableSystemTray: DEFAULT_APP_SETTINGS.enableSystemTray,
9 @observable showDisabledServices = DEFAULT_APP_SETTINGS.showDisabledServices; 9 minimizeToSystemTray: DEFAULT_APP_SETTINGS.minimizeToSystemTray,
10 @observable showMessageBadgeWhenMuted = DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted; 10 isAppMuted: DEFAULT_APP_SETTINGS.isAppMuted,
11 @observable enableSpellchecking = DEFAULT_APP_SETTINGS.enableSpellchecking; 11 showMessageBadgeWhenMuted: DEFAULT_APP_SETTINGS.showMessageBadgeWhenMuted,
12 @observable locale = DEFAULT_APP_SETTINGS.locale; 12 showDisabledServices: DEFAULT_APP_SETTINGS.showDisabledServices,
13 @observable beta = DEFAULT_APP_SETTINGS.beta; 13 enableSpellchecking: DEFAULT_APP_SETTINGS.enableSpellchecking,
14 @observable isAppMuted = DEFAULT_APP_SETTINGS.isAppMuted; 14 locale: DEFAULT_APP_SETTINGS.locale,
15 beta: DEFAULT_APP_SETTINGS.beta,
15 16
16 constructor(data) { 17 }
17 Object.assign(this, data); 18
19 @observable service = {
20 activeService: DEFAULT_APP_SETTINGS.autoLaunchInBackground,
21 }
22
23 @observable group = {
24 collapsed: [],
25 disabled: [],
26 }
27
28 @observable stats = {
29 appStarts: 0,
30 }
31
32 constructor({ app, service, group, stats }) {
33 Object.assign(this.app, app);
34 Object.assign(this.service, service);
35 Object.assign(this.group, group);
36 Object.assign(this.stats, stats);
18 } 37 }
19 38
20 update(data) { 39 update(data) {
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 94ed308f3..3c6c24b59 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -159,7 +159,7 @@ export default class AppStore extends Store {
159 159
160 // Actions 160 // Actions
161 @action _notify({ title, options, notificationId, serviceId = null }) { 161 @action _notify({ title, options, notificationId, serviceId = null }) {
162 if (this.stores.settings.all.isAppMuted) return; 162 if (this.stores.settings.all.app.isAppMuted) return;
163 163
164 const notification = new window.Notification(title, options); 164 const notification = new window.Notification(title, options);
165 notification.onclick = (e) => { 165 notification.onclick = (e) => {
@@ -240,14 +240,15 @@ export default class AppStore extends Store {
240 this.isSystemMuteOverridden = overrideSystemMute; 240 this.isSystemMuteOverridden = overrideSystemMute;
241 241
242 this.actions.settings.update({ 242 this.actions.settings.update({
243 settings: { 243 type: 'app',
244 data: {
244 isAppMuted: isMuted, 245 isAppMuted: isMuted,
245 }, 246 },
246 }); 247 });
247 } 248 }
248 249
249 @action _toggleMuteApp() { 250 @action _toggleMuteApp() {
250 this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); 251 this._muteApp({ isMuted: !this.stores.settings.all.app.isAppMuted });
251 } 252 }
252 253
253 @action async _clearAllCache() { 254 @action async _clearAllCache() {
@@ -331,8 +332,9 @@ export default class AppStore extends Store {
331 // Helpers 332 // Helpers
332 _appStartsCounter() { 333 _appStartsCounter() {
333 this.actions.settings.update({ 334 this.actions.settings.update({
334 settings: { 335 type: 'stats',
335 appStarts: (this.stores.settings.all.appStarts || 0) + 1, 336 data: {
337 appStarts: (this.stores.settings.all.stats.appStarts || 0) + 1,
336 }, 338 },
337 }); 339 });
338 } 340 }
@@ -340,7 +342,8 @@ export default class AppStore extends Store {
340 async _autoStart() { 342 async _autoStart() {
341 this.autoLaunchOnStart = await this._checkAutoStart(); 343 this.autoLaunchOnStart = await this._checkAutoStart();
342 344
343 if (this.stores.settings.all.appStarts === 1) { 345 if (this.stores.settings.all.stats.appStarts === 1) {
346 debug('Set app to launch on start');
344 this.actions.app.launchOnStartup({ 347 this.actions.app.launchOnStartup({
345 enable: true, 348 enable: true,
346 }); 349 });
@@ -353,7 +356,7 @@ export default class AppStore extends Store {
353 356
354 _systemDND() { 357 _systemDND() {
355 const dnd = getDoNotDisturb(); 358 const dnd = getDoNotDisturb();
356 if (dnd !== this.stores.settings.all.isAppMuted && !this.isSystemMuteOverridden) { 359 if (dnd !== this.stores.settings.all.app.isAppMuted && !this.isSystemMuteOverridden) {
357 this.actions.app.muteApp({ 360 this.actions.app.muteApp({
358 isMuted: dnd, 361 isMuted: dnd,
359 overrideSystemMute: false, 362 overrideSystemMute: false,
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index f7d92b1ff..b96bc506b 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -86,13 +86,13 @@ export default class ServicesStore extends Store {
86 } 86 }
87 87
88 @computed get allDisplayed() { 88 @computed get allDisplayed() {
89 return this.stores.settings.all.showDisabledServices ? this.all : this.enabled; 89 return this.stores.settings.all.service.showDisabledServices ? this.all : this.enabled;
90 } 90 }
91 91
92 // This is just used to avoid unnecessary rerendering of resource-heavy webviews 92 // This is just used to avoid unnecessary rerendering of resource-heavy webviews
93 @computed get allDisplayedUnordered() { 93 @computed get allDisplayedUnordered() {
94 const services = this.allServicesRequest.execute().result || []; 94 const services = this.allServicesRequest.execute().result || [];
95 return this.stores.settings.all.showDisabledServices ? services : services.filter(service => service.isEnabled); 95 return this.stores.settings.all.service.showDisabledServices ? services : services.filter(service => service.isEnabled);
96 } 96 }
97 97
98 @computed get filtered() { 98 @computed get filtered() {
@@ -334,7 +334,7 @@ export default class ServicesStore extends Store {
334 }); 334 });
335 } else if (channel === 'notification') { 335 } else if (channel === 'notification') {
336 const options = args[0].options; 336 const options = args[0].options;
337 if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.isAppMuted) { 337 if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.app.isAppMuted) {
338 Object.assign(options, { 338 Object.assign(options, {
339 silent: true, 339 silent: true,
340 }); 340 });
@@ -434,7 +434,7 @@ export default class ServicesStore extends Store {
434 } 434 }
435 435
436 @action _reorder({ oldIndex, newIndex }) { 436 @action _reorder({ oldIndex, newIndex }) {
437 const showDisabledServices = this.stores.settings.all.showDisabledServices; 437 const showDisabledServices = this.stores.settings.all.service.showDisabledServices;
438 const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]); 438 const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]);
439 const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]); 439 const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]);
440 440
@@ -512,7 +512,8 @@ export default class ServicesStore extends Store {
512 512
513 if (service) { 513 if (service) {
514 this.actions.settings.update({ 514 this.actions.settings.update({
515 settings: { 515 type: 'service',
516 data: {
516 activeService: service.id, 517 activeService: service.id,
517 }, 518 },
518 }); 519 });
@@ -520,7 +521,7 @@ export default class ServicesStore extends Store {
520 } 521 }
521 522
522 _mapActiveServiceToServiceModelReaction() { 523 _mapActiveServiceToServiceModelReaction() {
523 const { activeService } = this.stores.settings.all; 524 const { activeService } = this.stores.settings.all.service;
524 if (this.allDisplayed.length) { 525 if (this.allDisplayed.length) {
525 this.allDisplayed.map(service => Object.assign(service, { 526 this.allDisplayed.map(service => Object.assign(service, {
526 isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id, 527 isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id,
@@ -529,7 +530,7 @@ export default class ServicesStore extends Store {
529 } 530 }
530 531
531 _getUnreadMessageCountReaction() { 532 _getUnreadMessageCountReaction() {
532 const showMessageBadgeWhenMuted = this.stores.settings.all.showMessageBadgeWhenMuted; 533 const showMessageBadgeWhenMuted = this.stores.settings.all.app.showMessageBadgeWhenMuted;
533 const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted; 534 const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted;
534 535
535 const unreadDirectMessageCount = this.allDisplayed 536 const unreadDirectMessageCount = this.allDisplayed
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js
index b7d803398..b3f5d3eaf 100644
--- a/src/stores/SettingsStore.js
+++ b/src/stores/SettingsStore.js
@@ -1,12 +1,18 @@
1import { ipcRenderer } from 'electron'; 1import { ipcRenderer } from 'electron';
2import { action, computed } from 'mobx'; 2import { action, computed, observable } from 'mobx';
3import localStorage from 'mobx-localstorage'; 3import localStorage from 'mobx-localstorage';
4 4
5import Store from './lib/Store'; 5import Store from './lib/Store';
6import { gaEvent } from '../lib/analytics';
7import SettingsModel from '../models/Settings'; 6import SettingsModel from '../models/Settings';
7import Request from './lib/Request';
8import CachedRequest from './lib/CachedRequest';
9
10const debug = require('debug')('SettingsStore');
8 11
9export default class SettingsStore extends Store { 12export default class SettingsStore extends Store {
13 @observable appSettingsRequest = new CachedRequest(this.api.local, 'getAppSettings');
14 @observable updateAppSettingsRequest = new Request(this.api.local, 'updateAppSettings');
15
10 constructor(...args) { 16 constructor(...args) {
11 super(...args); 17 super(...args);
12 18
@@ -15,22 +21,29 @@ export default class SettingsStore extends Store {
15 this.actions.settings.remove.listen(this._remove.bind(this)); 21 this.actions.settings.remove.listen(this._remove.bind(this));
16 } 22 }
17 23
18 setup() {
19 this._shareSettingsWithMainProcess();
20 }
21
22 @computed get all() { 24 @computed get all() {
23 return new SettingsModel(localStorage.getItem('app') || {}); 25 return new SettingsModel({
26 app: this.appSettingsRequest.execute().result || {},
27 service: localStorage.getItem('service') || {},
28 group: localStorage.getItem('group') || {},
29 stats: localStorage.getItem('stats') || {},
30 });
24 } 31 }
25 32
26 @action async _update({ settings }) { 33 @action async _update({ type, data }) {
34 debug('Update settings', type, data, this.all);
27 const appSettings = this.all; 35 const appSettings = this.all;
28 localStorage.setItem('app', Object.assign(appSettings, settings)); 36 if (type !== 'app') {
29 37 localStorage.setItem(type, Object.assign(appSettings[type], data));
30 // We need a little hack to wait until everything is patched 38 } else {
31 setTimeout(() => this._shareSettingsWithMainProcess(), 0); 39 debug('Store app settings on file system', type, data);
32 40 this.updateAppSettingsRequest.execute(data);
33 gaEvent('Settings', 'update'); 41
42 this.appSettingsRequest.patch((result) => {
43 if (!result) return;
44 Object.assign(result, data);
45 });
46 }
34 } 47 }
35 48
36 @action async _remove({ key }) { 49 @action async _remove({ key }) {
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js
index 5e9cc9ba7..b391bdcae 100644
--- a/src/stores/UIStore.js
+++ b/src/stores/UIStore.js
@@ -17,7 +17,7 @@ export default class UIStore extends Store {
17 @computed get showMessageBadgesEvenWhenMuted() { 17 @computed get showMessageBadgesEvenWhenMuted() {
18 const settings = this.stores.settings.all; 18 const settings = this.stores.settings.all;
19 19
20 return (settings.isAppMuted && settings.showMessageBadgeWhenMuted) || !settings.isAppMuted; 20 return (settings.app.isAppMuted && settings.app.showMessageBadgeWhenMuted) || !settings.isAppMuted;
21 } 21 }
22 22
23 // Actions 23 // Actions