aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/AppStore.js60
-rw-r--r--src/stores/ServicesStore.js18
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 @@
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
@@ -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,