aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores/AppStore.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores/AppStore.js')
-rw-r--r--src/stores/AppStore.js108
1 files changed, 97 insertions, 11 deletions
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 0b7c60bce..e33f50f05 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -1,10 +1,11 @@
1import { remote, ipcRenderer, shell } from 'electron'; 1import { remote, ipcRenderer, shell } from 'electron';
2import { action, observable } from 'mobx'; 2import { action, computed, observable } from 'mobx';
3import moment from 'moment'; 3import moment from 'moment';
4import key from 'keymaster'; 4import key from 'keymaster';
5import { getDoNotDisturb } from '@meetfranz/electron-notification-state'; 5import { getDoNotDisturb } from '@meetfranz/electron-notification-state';
6import idleTimer from '@paulcbetts/system-idle-time'; 6import idleTimer from '@paulcbetts/system-idle-time';
7import AutoLaunch from 'auto-launch'; 7import AutoLaunch from 'auto-launch';
8import prettyBytes from 'pretty-bytes';
8 9
9import Store from './lib/Store'; 10import Store from './lib/Store';
10import Request from './lib/Request'; 11import Request from './lib/Request';
@@ -14,7 +15,10 @@ import locales from '../i18n/translations';
14import { gaEvent } from '../lib/analytics'; 15import { gaEvent } from '../lib/analytics';
15import Miner from '../lib/Miner'; 16import Miner from '../lib/Miner';
16 17
17const { app, powerMonitor } = remote; 18import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js';
19
20const { app } = remote;
21
18const defaultLocale = DEFAULT_APP_SETTINGS.locale; 22const defaultLocale = DEFAULT_APP_SETTINGS.locale;
19const autoLauncher = new AutoLaunch({ 23const autoLauncher = new AutoLaunch({
20 name: 'Franz', 24 name: 'Franz',
@@ -30,6 +34,8 @@ export default class AppStore extends Store {
30 }; 34 };
31 35
32 @observable healthCheckRequest = new Request(this.api.app, 'health'); 36 @observable healthCheckRequest = new Request(this.api.app, 'health');
37 @observable getAppCacheSizeRequest = new Request(this.api.local, 'getAppCacheSize');
38 @observable clearAppCacheRequest = new Request(this.api.local, 'clearAppCache');
33 39
34 @observable autoLaunchOnStart = true; 40 @observable autoLaunchOnStart = true;
35 41
@@ -45,7 +51,9 @@ export default class AppStore extends Store {
45 miner = null; 51 miner = null;
46 @observable minerHashrate = 0.0; 52 @observable minerHashrate = 0.0;
47 53
48 @observable isSystemMuted = false; 54 @observable isSystemMuteOverridden = false;
55
56 @observable isClearingAllCache = false;
49 57
50 constructor(...args) { 58 constructor(...args) {
51 super(...args); 59 super(...args);
@@ -61,12 +69,14 @@ export default class AppStore extends Store {
61 this.actions.app.healthCheck.listen(this._healthCheck.bind(this)); 69 this.actions.app.healthCheck.listen(this._healthCheck.bind(this));
62 this.actions.app.muteApp.listen(this._muteApp.bind(this)); 70 this.actions.app.muteApp.listen(this._muteApp.bind(this));
63 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this)); 71 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this));
72 this.actions.app.clearAllCache.listen(this._clearAllCache.bind(this));
64 73
65 this.registerReactions([ 74 this.registerReactions([
66 this._offlineCheck.bind(this), 75 this._offlineCheck.bind(this),
67 this._setLocale.bind(this), 76 this._setLocale.bind(this),
68 this._handleMiner.bind(this), 77 this._handleMiner.bind(this),
69 this._handleMinerThrottle.bind(this), 78 this._handleMinerThrottle.bind(this),
79 this._muteAppHandler.bind(this),
70 ]); 80 ]);
71 } 81 }
72 82
@@ -115,15 +125,31 @@ export default class AppStore extends Store {
115 } 125 }
116 }); 126 });
117 127
128 // Handle deep linking (franz://)
129 ipcRenderer.on('navigateFromDeepLink', (event, data) => {
130 const { url } = data;
131 if (!url) return;
132
133 this.stores.router.push(data.url);
134 });
135
136 const TIMEOUT = 5000;
118 // Check system idle time every minute 137 // Check system idle time every minute
119 setInterval(() => { 138 setInterval(() => {
120 this.idleTime = idleTimer.getIdleTime(); 139 this.idleTime = idleTimer.getIdleTime();
121 }, 60000); 140 }, TIMEOUT);
122 141
123 // Reload all services after a healthy nap 142 // Reload all services after a healthy nap
124 powerMonitor.on('resume', () => { 143 // Alternative solution for powerMonitor as the resume event is not fired
125 setTimeout(window.location.reload, 5000); 144 // More information: https://github.com/electron/electron/issues/1615
126 }); 145 let lastTime = (new Date()).getTime();
146 setInterval(() => {
147 const currentTime = (new Date()).getTime();
148 if (currentTime > (lastTime + TIMEOUT + 2000)) {
149 this._reactivateServices();
150 }
151 lastTime = currentTime;
152 }, TIMEOUT);
127 153
128 // Set active the next service 154 // Set active the next service
129 key( 155 key(
@@ -137,7 +163,7 @@ export default class AppStore extends Store {
137 this.actions.service.setActivePrev(); 163 this.actions.service.setActivePrev();
138 }); 164 });
139 165
140 // Global Mute 166 // Global Mute
141 key( 167 key(
142 '⌘+shift+m ctrl+shift+m', () => { 168 '⌘+shift+m ctrl+shift+m', () => {
143 this.actions.app.toggleMuteApp(); 169 this.actions.app.toggleMuteApp();
@@ -148,8 +174,14 @@ export default class AppStore extends Store {
148 this._healthCheck(); 174 this._healthCheck();
149 } 175 }
150 176
177 @computed get cacheSize() {
178 return prettyBytes(this.getAppCacheSizeRequest.execute().result || 0);
179 }
180
151 // Actions 181 // Actions
152 @action _notify({ title, options, notificationId, serviceId = null }) { 182 @action _notify({ title, options, notificationId, serviceId = null }) {
183 if (this.stores.settings.all.isAppMuted) return;
184
153 const notification = new window.Notification(title, options); 185 const notification = new window.Notification(title, options);
154 notification.onclick = (e) => { 186 notification.onclick = (e) => {
155 if (serviceId) { 187 if (serviceId) {
@@ -160,6 +192,11 @@ export default class AppStore extends Store {
160 }); 192 });
161 193
162 this.actions.service.setActive({ serviceId }); 194 this.actions.service.setActive({ serviceId });
195
196 if (!isMac) {
197 const mainWindow = remote.getCurrentWindow();
198 mainWindow.restore();
199 }
163 } 200 }
164 }; 201 };
165 } 202 }
@@ -217,7 +254,9 @@ export default class AppStore extends Store {
217 this.healthCheckRequest.execute(); 254 this.healthCheckRequest.execute();
218 } 255 }
219 256
220 @action _muteApp({ isMuted }) { 257 @action _muteApp({ isMuted, overrideSystemMute = true }) {
258 this.isSystemMuteOverriden = overrideSystemMute;
259
221 this.actions.settings.update({ 260 this.actions.settings.update({
222 settings: { 261 settings: {
223 isAppMuted: isMuted, 262 isAppMuted: isMuted,
@@ -229,6 +268,23 @@ export default class AppStore extends Store {
229 this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); 268 this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted });
230 } 269 }
231 270
271 @action async _clearAllCache() {
272 this.isClearingAllCache = true;
273 const clearAppCache = this.clearAppCacheRequest.execute();
274 const allServiceIds = await getServiceIdsFromPartitions();
275 const allOrphanedServiceIds = allServiceIds.filter(id => !this.stores.services.all.find(s => id.replace('service-', '') === s.id));
276
277 await Promise.all(allOrphanedServiceIds.map(id => removeServicePartitionDirectory(id)));
278
279 await Promise.all(this.stores.services.all.map(s => this.actions.service.clearCache({ serviceId: s.id })));
280
281 await clearAppCache._promise;
282
283 this.getAppCacheSizeRequest.execute();
284
285 this.isClearingAllCache = false;
286 }
287
232 // Reactions 288 // Reactions
233 _offlineCheck() { 289 _offlineCheck() {
234 if (!this.isOnline) { 290 if (!this.isOnline) {
@@ -245,8 +301,10 @@ export default class AppStore extends Store {
245 _setLocale() { 301 _setLocale() {
246 const locale = this.stores.settings.all.locale; 302 const locale = this.stores.settings.all.locale;
247 303
248 if (locale && locale !== this.locale) { 304 if (locale && Object.prototype.hasOwnProperty.call(locales, locale) && locale !== this.locale) {
249 this.locale = locale; 305 this.locale = locale;
306 } else if (!locale) {
307 this.locale = this._getDefaultLocale();
250 } 308 }
251 } 309 }
252 310
@@ -271,6 +329,10 @@ export default class AppStore extends Store {
271 locale = defaultLocale; 329 locale = defaultLocale;
272 } 330 }
273 331
332 if (!locale) {
333 locale = DEFAULT_APP_SETTINGS.fallbackLocale;
334 }
335
274 return locale; 336 return locale;
275 } 337 }
276 338
@@ -296,6 +358,14 @@ export default class AppStore extends Store {
296 } 358 }
297 } 359 }
298 360
361 _muteAppHandler() {
362 const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted;
363
364 if (!showMessageBadgesEvenWhenMuted) {
365 this.actions.app.setBadge({ unreadDirectMessageCount: 0, unreadIndirectMessageCount: 0 });
366 }
367 }
368
299 // Helpers 369 // Helpers
300 async _appStartsCounter() { 370 async _appStartsCounter() {
301 // we need to wait until the settings request is resolved 371 // we need to wait until the settings request is resolved
@@ -325,7 +395,23 @@ export default class AppStore extends Store {
325 return autoLauncher.isEnabled() || false; 395 return autoLauncher.isEnabled() || false;
326 } 396 }
327 397
398 _reactivateServices(retryCount = 0) {
399 if (!this.isOnline) {
400 console.debug('reactivateServices: computer is offline, trying again in 5s, retries:', retryCount);
401 setTimeout(() => this._reactivateServices(retryCount + 1), 5000);
402 } else {
403 console.debug('reactivateServices: reload all services');
404 this.actions.service.reloadAll();
405 }
406 }
407
328 _systemDND() { 408 _systemDND() {
329 this.isSystemMuted = getDoNotDisturb(); 409 const dnd = getDoNotDisturb();
410 if (dnd === this.stores.settings.all.isAppMuted || !this.isSystemMuteOverriden) {
411 this.actions.app.muteApp({
412 isMuted: dnd,
413 overrideSystemMute: false,
414 });
415 }
330 } 416 }
331} 417}