diff options
Diffstat (limited to 'src/stores')
-rw-r--r-- | src/stores/AppStore.js | 60 | ||||
-rw-r--r-- | src/stores/ServicesStore.js | 18 |
2 files changed, 70 insertions, 8 deletions
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js index 5a6c12ee1..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 | ||
@@ -47,6 +53,8 @@ export default class AppStore extends Store { | |||
47 | 53 | ||
48 | @observable isSystemMuteOverridden = false; | 54 | @observable isSystemMuteOverridden = false; |
49 | 55 | ||
56 | @observable isClearingAllCache = false; | ||
57 | |||
50 | constructor(...args) { | 58 | constructor(...args) { |
51 | super(...args); | 59 | super(...args); |
52 | 60 | ||
@@ -61,6 +69,7 @@ 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), |
@@ -124,15 +133,23 @@ export default class AppStore extends Store { | |||
124 | this.stores.router.push(data.url); | 133 | this.stores.router.push(data.url); |
125 | }); | 134 | }); |
126 | 135 | ||
136 | const TIMEOUT = 5000; | ||
127 | // Check system idle time every minute | 137 | // Check system idle time every minute |
128 | setInterval(() => { | 138 | setInterval(() => { |
129 | this.idleTime = idleTimer.getIdleTime(); | 139 | this.idleTime = idleTimer.getIdleTime(); |
130 | }, 60000); | 140 | }, TIMEOUT); |
131 | 141 | ||
132 | // Reload all services after a healthy nap | 142 | // Reload all services after a healthy nap |
133 | powerMonitor.on('resume', () => { | 143 | // Alternative solution for powerMonitor as the resume event is not fired |
134 | setTimeout(window.location.reload, 5000); | 144 | // More information: https://github.com/electron/electron/issues/1615 |
135 | }); | 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); | ||
136 | 153 | ||
137 | // Set active the next service | 154 | // Set active the next service |
138 | key( | 155 | key( |
@@ -157,6 +174,10 @@ export default class AppStore extends Store { | |||
157 | this._healthCheck(); | 174 | this._healthCheck(); |
158 | } | 175 | } |
159 | 176 | ||
177 | @computed get cacheSize() { | ||
178 | return prettyBytes(this.getAppCacheSizeRequest.execute().result || 0); | ||
179 | } | ||
180 | |||
160 | // Actions | 181 | // Actions |
161 | @action _notify({ title, options, notificationId, serviceId = null }) { | 182 | @action _notify({ title, options, notificationId, serviceId = null }) { |
162 | if (this.stores.settings.all.isAppMuted) return; | 183 | if (this.stores.settings.all.isAppMuted) return; |
@@ -247,6 +268,23 @@ export default class AppStore extends Store { | |||
247 | this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); | 268 | this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); |
248 | } | 269 | } |
249 | 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 | |||
250 | // Reactions | 288 | // Reactions |
251 | _offlineCheck() { | 289 | _offlineCheck() { |
252 | if (!this.isOnline) { | 290 | if (!this.isOnline) { |
@@ -357,6 +395,16 @@ export default class AppStore extends Store { | |||
357 | return autoLauncher.isEnabled() || false; | 395 | return autoLauncher.isEnabled() || false; |
358 | } | 396 | } |
359 | 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 | |||
360 | _systemDND() { | 408 | _systemDND() { |
361 | const dnd = getDoNotDisturb(); | 409 | const dnd = getDoNotDisturb(); |
362 | if (dnd === this.stores.settings.all.isAppMuted || !this.isSystemMuteOverriden) { | 410 | if (dnd === this.stores.settings.all.isAppMuted || !this.isSystemMuteOverriden) { |
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index f2a8683ba..7300a76c8 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -16,6 +16,7 @@ export default class ServicesStore extends Store { | |||
16 | @observable updateServiceRequest = new Request(this.api.services, 'update'); | 16 | @observable updateServiceRequest = new Request(this.api.services, 'update'); |
17 | @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); | 17 | @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); |
18 | @observable deleteServiceRequest = new Request(this.api.services, 'delete'); | 18 | @observable deleteServiceRequest = new Request(this.api.services, 'delete'); |
19 | @observable clearCacheRequest = new Request(this.api.services, 'clearCache'); | ||
19 | 20 | ||
20 | @observable filterNeedle = null; | 21 | @observable filterNeedle = null; |
21 | 22 | ||
@@ -31,6 +32,7 @@ export default class ServicesStore extends Store { | |||
31 | this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); | 32 | this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); |
32 | this.actions.service.updateService.listen(this._updateService.bind(this)); | 33 | this.actions.service.updateService.listen(this._updateService.bind(this)); |
33 | this.actions.service.deleteService.listen(this._deleteService.bind(this)); | 34 | this.actions.service.deleteService.listen(this._deleteService.bind(this)); |
35 | this.actions.service.clearCache.listen(this._clearCache.bind(this)); | ||
34 | this.actions.service.setWebviewReference.listen(this._setWebviewReference.bind(this)); | 36 | this.actions.service.setWebviewReference.listen(this._setWebviewReference.bind(this)); |
35 | this.actions.service.focusService.listen(this._focusService.bind(this)); | 37 | this.actions.service.focusService.listen(this._focusService.bind(this)); |
36 | this.actions.service.focusActiveService.listen(this._focusActiveService.bind(this)); | 38 | this.actions.service.focusActiveService.listen(this._focusActiveService.bind(this)); |
@@ -225,6 +227,13 @@ export default class ServicesStore extends Store { | |||
225 | gaEvent('Service', 'delete', service.recipe.id); | 227 | gaEvent('Service', 'delete', service.recipe.id); |
226 | } | 228 | } |
227 | 229 | ||
230 | @action async _clearCache({ serviceId }) { | ||
231 | this.clearCacheRequest.reset(); | ||
232 | const request = this.clearCacheRequest.execute(serviceId); | ||
233 | await request._promise; | ||
234 | gaEvent('Service', 'clear cache'); | ||
235 | } | ||
236 | |||
228 | @action _setActive({ serviceId }) { | 237 | @action _setActive({ serviceId }) { |
229 | const service = this.one(serviceId); | 238 | const service = this.one(serviceId); |
230 | 239 | ||
@@ -347,6 +356,10 @@ export default class ServicesStore extends Store { | |||
347 | redirect: false, | 356 | redirect: false, |
348 | }); | 357 | }); |
349 | } | 358 | } |
359 | } else if (channel === 'new-window') { | ||
360 | const url = args[0]; | ||
361 | |||
362 | this.actions.app.openExternalUrl({ url }); | ||
350 | } | 363 | } |
351 | } | 364 | } |
352 | 365 | ||
@@ -388,7 +401,7 @@ export default class ServicesStore extends Store { | |||
388 | const service = this.one(serviceId); | 401 | const service = this.one(serviceId); |
389 | service.resetMessageCount(); | 402 | service.resetMessageCount(); |
390 | 403 | ||
391 | service.webview.reload(); | 404 | service.webview.loadURL(service.url); |
392 | } | 405 | } |
393 | 406 | ||
394 | @action _reloadActive() { | 407 | @action _reloadActive() { |
@@ -517,12 +530,13 @@ export default class ServicesStore extends Store { | |||
517 | .reduce((a, b) => a + b, 0); | 530 | .reduce((a, b) => a + b, 0); |
518 | 531 | ||
519 | const unreadIndirectMessageCount = this.allDisplayed | 532 | const unreadIndirectMessageCount = this.allDisplayed |
520 | .filter(s => (showMessageBadgeWhenMuted || s.isIndirectMessageBadgeEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) | 533 | .filter(s => (showMessageBadgeWhenMuted && showMessageBadgesEvenWhenMuted) && (s.isBadgeEnabled && s.isIndirectMessageBadgeEnabled)) |
521 | .map(s => s.unreadIndirectMessageCount) | 534 | .map(s => s.unreadIndirectMessageCount) |
522 | .reduce((a, b) => a + b, 0); | 535 | .reduce((a, b) => a + b, 0); |
523 | 536 | ||
524 | // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases | 537 | // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases |
525 | if (showMessageBadgesEvenWhenMuted) { | 538 | if (showMessageBadgesEvenWhenMuted) { |
539 | console.log('set badge', unreadDirectMessageCount, unreadIndirectMessageCount); | ||
526 | this.actions.app.setBadge({ | 540 | this.actions.app.setBadge({ |
527 | unreadDirectMessageCount, | 541 | unreadDirectMessageCount, |
528 | unreadIndirectMessageCount, | 542 | unreadIndirectMessageCount, |