diff options
Diffstat (limited to 'src/stores/AppStore.js')
-rw-r--r-- | src/stores/AppStore.js | 108 |
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 @@ | |||
1 | import { remote, ipcRenderer, shell } from 'electron'; | 1 | import { remote, ipcRenderer, shell } from 'electron'; |
2 | import { action, observable } from 'mobx'; | 2 | import { action, computed, observable } from 'mobx'; |
3 | import moment from 'moment'; | 3 | import moment from 'moment'; |
4 | import key from 'keymaster'; | 4 | import key from 'keymaster'; |
5 | import { getDoNotDisturb } from '@meetfranz/electron-notification-state'; | 5 | import { getDoNotDisturb } from '@meetfranz/electron-notification-state'; |
6 | import idleTimer from '@paulcbetts/system-idle-time'; | 6 | import idleTimer from '@paulcbetts/system-idle-time'; |
7 | import AutoLaunch from 'auto-launch'; | 7 | import AutoLaunch from 'auto-launch'; |
8 | import prettyBytes from 'pretty-bytes'; | ||
8 | 9 | ||
9 | import Store from './lib/Store'; | 10 | import Store from './lib/Store'; |
10 | import Request from './lib/Request'; | 11 | import Request from './lib/Request'; |
@@ -14,7 +15,10 @@ import locales from '../i18n/translations'; | |||
14 | import { gaEvent } from '../lib/analytics'; | 15 | import { gaEvent } from '../lib/analytics'; |
15 | import Miner from '../lib/Miner'; | 16 | import Miner from '../lib/Miner'; |
16 | 17 | ||
17 | const { app, powerMonitor } = remote; | 18 | import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js'; |
19 | |||
20 | const { app } = remote; | ||
21 | |||
18 | const defaultLocale = DEFAULT_APP_SETTINGS.locale; | 22 | const defaultLocale = DEFAULT_APP_SETTINGS.locale; |
19 | const autoLauncher = new AutoLaunch({ | 23 | const 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 | } |