aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2018-01-17 10:34:22 +0400
committerLibravatar GitHub <noreply@github.com>2018-01-17 10:34:22 +0400
commit81b49fba430959ec4e0946f905dc182d2733831c (patch)
treea1979dafda41ac804986ef57a68912a868cb5ac7 /src/stores
parentRemove idle timer dependency (diff)
parentMerge branch 'develop' of github.com:meetfranz/franz into develop (diff)
downloadferdium-app-81b49fba430959ec4e0946f905dc182d2733831c.tar.gz
ferdium-app-81b49fba430959ec4e0946f905dc182d2733831c.tar.zst
ferdium-app-81b49fba430959ec4e0946f905dc182d2733831c.zip
Merge branch 'develop' into feature/remove-miner
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/AppStore.js57
-rw-r--r--src/stores/ServicesStore.js42
2 files changed, 90 insertions, 9 deletions
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index 3eddff5ed..772b33c67 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -1,9 +1,10 @@
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 AutoLaunch from 'auto-launch'; 6import AutoLaunch from 'auto-launch';
7import prettyBytes from 'pretty-bytes';
7 8
8import Store from './lib/Store'; 9import Store from './lib/Store';
9import Request from './lib/Request'; 10import Request from './lib/Request';
@@ -12,7 +13,10 @@ import { isMac } from '../environment';
12import locales from '../i18n/translations'; 13import locales from '../i18n/translations';
13import { gaEvent } from '../lib/analytics'; 14import { gaEvent } from '../lib/analytics';
14 15
15const { app, powerMonitor } = remote; 16import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js';
17
18const { app } = remote;
19
16const defaultLocale = DEFAULT_APP_SETTINGS.locale; 20const defaultLocale = DEFAULT_APP_SETTINGS.locale;
17const autoLauncher = new AutoLaunch({ 21const autoLauncher = new AutoLaunch({
18 name: 'Franz', 22 name: 'Franz',
@@ -28,6 +32,8 @@ export default class AppStore extends Store {
28 }; 32 };
29 33
30 @observable healthCheckRequest = new Request(this.api.app, 'health'); 34 @observable healthCheckRequest = new Request(this.api.app, 'health');
35 @observable getAppCacheSizeRequest = new Request(this.api.local, 'getAppCacheSize');
36 @observable clearAppCacheRequest = new Request(this.api.local, 'clearAppCache');
31 37
32 @observable autoLaunchOnStart = true; 38 @observable autoLaunchOnStart = true;
33 39
@@ -40,6 +46,8 @@ export default class AppStore extends Store {
40 46
41 @observable isSystemMuteOverridden = false; 47 @observable isSystemMuteOverridden = false;
42 48
49 @observable isClearingAllCache = false;
50
43 constructor(...args) { 51 constructor(...args) {
44 super(...args); 52 super(...args);
45 53
@@ -54,6 +62,7 @@ export default class AppStore extends Store {
54 this.actions.app.healthCheck.listen(this._healthCheck.bind(this)); 62 this.actions.app.healthCheck.listen(this._healthCheck.bind(this));
55 this.actions.app.muteApp.listen(this._muteApp.bind(this)); 63 this.actions.app.muteApp.listen(this._muteApp.bind(this));
56 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this)); 64 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this));
65 this.actions.app.clearAllCache.listen(this._clearAllCache.bind(this));
57 66
58 this.registerReactions([ 67 this.registerReactions([
59 this._offlineCheck.bind(this), 68 this._offlineCheck.bind(this),
@@ -116,9 +125,16 @@ export default class AppStore extends Store {
116 }); 125 });
117 126
118 // Reload all services after a healthy nap 127 // Reload all services after a healthy nap
119 powerMonitor.on('resume', () => { 128 // Alternative solution for powerMonitor as the resume event is not fired
120 setTimeout(window.location.reload, 5000); 129 // More information: https://github.com/electron/electron/issues/1615
121 }); 130 let lastTime = (new Date()).getTime();
131 setInterval(() => {
132 const currentTime = (new Date()).getTime();
133 if (currentTime > (lastTime + TIMEOUT + 2000)) {
134 this._reactivateServices();
135 }
136 lastTime = currentTime;
137 }, TIMEOUT);
122 138
123 // Set active the next service 139 // Set active the next service
124 key( 140 key(
@@ -143,6 +159,10 @@ export default class AppStore extends Store {
143 this._healthCheck(); 159 this._healthCheck();
144 } 160 }
145 161
162 @computed get cacheSize() {
163 return prettyBytes(this.getAppCacheSizeRequest.execute().result || 0);
164 }
165
146 // Actions 166 // Actions
147 @action _notify({ title, options, notificationId, serviceId = null }) { 167 @action _notify({ title, options, notificationId, serviceId = null }) {
148 if (this.stores.settings.all.isAppMuted) return; 168 if (this.stores.settings.all.isAppMuted) return;
@@ -233,6 +253,23 @@ export default class AppStore extends Store {
233 this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted }); 253 this._muteApp({ isMuted: !this.stores.settings.all.isAppMuted });
234 } 254 }
235 255
256 @action async _clearAllCache() {
257 this.isClearingAllCache = true;
258 const clearAppCache = this.clearAppCacheRequest.execute();
259 const allServiceIds = await getServiceIdsFromPartitions();
260 const allOrphanedServiceIds = allServiceIds.filter(id => !this.stores.services.all.find(s => id.replace('service-', '') === s.id));
261
262 await Promise.all(allOrphanedServiceIds.map(id => removeServicePartitionDirectory(id)));
263
264 await Promise.all(this.stores.services.all.map(s => this.actions.service.clearCache({ serviceId: s.id })));
265
266 await clearAppCache._promise;
267
268 this.getAppCacheSizeRequest.execute();
269
270 this.isClearingAllCache = false;
271 }
272
236 // Reactions 273 // Reactions
237 _offlineCheck() { 274 _offlineCheck() {
238 if (!this.isOnline) { 275 if (!this.isOnline) {
@@ -321,6 +358,16 @@ export default class AppStore extends Store {
321 return autoLauncher.isEnabled() || false; 358 return autoLauncher.isEnabled() || false;
322 } 359 }
323 360
361 _reactivateServices(retryCount = 0) {
362 if (!this.isOnline) {
363 console.debug('reactivateServices: computer is offline, trying again in 5s, retries:', retryCount);
364 setTimeout(() => this._reactivateServices(retryCount + 1), 5000);
365 } else {
366 console.debug('reactivateServices: reload all services');
367 this.actions.service.reloadAll();
368 }
369 }
370
324 _systemDND() { 371 _systemDND() {
325 const dnd = getDoNotDisturb(); 372 const dnd = getDoNotDisturb();
326 if (dnd === this.stores.settings.all.isAppMuted || !this.isSystemMuteOverriden) { 373 if (dnd === this.stores.settings.all.isAppMuted || !this.isSystemMuteOverriden) {
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 66f37af26..20e07e540 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));
@@ -172,9 +174,29 @@ export default class ServicesStore extends Store {
172 const data = this._cleanUpTeamIdAndCustomUrl(service.recipe.id, serviceData); 174 const data = this._cleanUpTeamIdAndCustomUrl(service.recipe.id, serviceData);
173 const request = this.updateServiceRequest.execute(serviceId, data); 175 const request = this.updateServiceRequest.execute(serviceId, data);
174 176
177 const newData = serviceData;
178 if (serviceData.iconFile) {
179 await request._promise;
180
181 newData.iconUrl = request.result.data.iconUrl;
182 newData.hasCustomUploadedIcon = true;
183 }
184
175 this.allServicesRequest.patch((result) => { 185 this.allServicesRequest.patch((result) => {
176 if (!result) return; 186 if (!result) return;
177 Object.assign(result.find(c => c.id === serviceId), serviceData); 187
188 // patch custom icon deletion
189 if (data.customIcon === 'delete') {
190 newData.iconUrl = '';
191 newData.hasCustomUploadedIcon = false;
192 }
193
194 // patch custom icon url
195 if (data.customIconUrl) {
196 newData.iconUrl = data.customIconUrl;
197 }
198
199 Object.assign(result.find(c => c.id === serviceId), newData);
178 }); 200 });
179 201
180 await request._promise; 202 await request._promise;
@@ -205,6 +227,13 @@ export default class ServicesStore extends Store {
205 gaEvent('Service', 'delete', service.recipe.id); 227 gaEvent('Service', 'delete', service.recipe.id);
206 } 228 }
207 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
208 @action _setActive({ serviceId }) { 237 @action _setActive({ serviceId }) {
209 const service = this.one(serviceId); 238 const service = this.one(serviceId);
210 239
@@ -316,7 +345,7 @@ export default class ServicesStore extends Store {
316 } 345 }
317 } else if (channel === 'avatar') { 346 } else if (channel === 'avatar') {
318 const url = args[0]; 347 const url = args[0];
319 if (service.customIconUrl !== url) { 348 if (service.iconUrl !== url && !service.hasCustomUploadedIcon) {
320 service.customIconUrl = url; 349 service.customIconUrl = url;
321 350
322 this.actions.service.updateService({ 351 this.actions.service.updateService({
@@ -327,6 +356,10 @@ export default class ServicesStore extends Store {
327 redirect: false, 356 redirect: false,
328 }); 357 });
329 } 358 }
359 } else if (channel === 'new-window') {
360 const url = args[0];
361
362 this.actions.app.openExternalUrl({ url });
330 } 363 }
331 } 364 }
332 365
@@ -368,7 +401,7 @@ export default class ServicesStore extends Store {
368 const service = this.one(serviceId); 401 const service = this.one(serviceId);
369 service.resetMessageCount(); 402 service.resetMessageCount();
370 403
371 service.webview.reload(); 404 service.webview.loadURL(service.url);
372 } 405 }
373 406
374 @action _reloadActive() { 407 @action _reloadActive() {
@@ -497,12 +530,13 @@ export default class ServicesStore extends Store {
497 .reduce((a, b) => a + b, 0); 530 .reduce((a, b) => a + b, 0);
498 531
499 const unreadIndirectMessageCount = this.allDisplayed 532 const unreadIndirectMessageCount = this.allDisplayed
500 .filter(s => (showMessageBadgeWhenMuted || s.isIndirectMessageBadgeEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) 533 .filter(s => (showMessageBadgeWhenMuted && showMessageBadgesEvenWhenMuted) && (s.isBadgeEnabled && s.isIndirectMessageBadgeEnabled))
501 .map(s => s.unreadIndirectMessageCount) 534 .map(s => s.unreadIndirectMessageCount)
502 .reduce((a, b) => a + b, 0); 535 .reduce((a, b) => a + b, 0);
503 536
504 // 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
505 if (showMessageBadgesEvenWhenMuted) { 538 if (showMessageBadgesEvenWhenMuted) {
539 console.log('set badge', unreadDirectMessageCount, unreadIndirectMessageCount);
506 this.actions.app.setBadge({ 540 this.actions.app.setBadge({
507 unreadDirectMessageCount, 541 unreadDirectMessageCount,
508 unreadIndirectMessageCount, 542 unreadIndirectMessageCount,