diff options
Diffstat (limited to 'src/stores/ServicesStore.js')
-rw-r--r-- | src/stores/ServicesStore.js | 90 |
1 files changed, 65 insertions, 25 deletions
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js index 70b775503..076ecc204 100644 --- a/src/stores/ServicesStore.js +++ b/src/stores/ServicesStore.js | |||
@@ -4,19 +4,20 @@ import { | |||
4 | computed, | 4 | computed, |
5 | observable, | 5 | observable, |
6 | } from 'mobx'; | 6 | } from 'mobx'; |
7 | import { debounce, remove } from 'lodash'; | 7 | import { remove } from 'lodash'; |
8 | import ms from 'ms'; | 8 | import ms from 'ms'; |
9 | 9 | ||
10 | import Store from './lib/Store'; | 10 | import Store from './lib/Store'; |
11 | import Request from './lib/Request'; | 11 | import Request from './lib/Request'; |
12 | import CachedRequest from './lib/CachedRequest'; | 12 | import CachedRequest from './lib/CachedRequest'; |
13 | import { matchRoute } from '../helpers/routing-helpers'; | 13 | import { matchRoute } from '../helpers/routing-helpers'; |
14 | import { gaEvent, statsEvent } from '../lib/analytics'; | 14 | import { isInTimeframe } from '../helpers/schedule-helpers'; |
15 | import { workspaceStore } from '../features/workspaces'; | 15 | import { workspaceStore } from '../features/workspaces'; |
16 | import { serviceLimitStore } from '../features/serviceLimit'; | 16 | import { serviceLimitStore } from '../features/serviceLimit'; |
17 | import { RESTRICTION_TYPES } from '../models/Service'; | 17 | import { RESTRICTION_TYPES } from '../models/Service'; |
18 | import { KEEP_WS_LOADED_USID } from '../config'; | ||
18 | 19 | ||
19 | const debug = require('debug')('Franz:ServiceStore'); | 20 | const debug = require('debug')('Ferdi:ServiceStore'); |
20 | 21 | ||
21 | export default class ServicesStore extends Store { | 22 | export default class ServicesStore extends Store { |
22 | @observable allServicesRequest = new CachedRequest(this.api.services, 'all'); | 23 | @observable allServicesRequest = new CachedRequest(this.api.services, 'all'); |
@@ -95,6 +96,11 @@ export default class ServicesStore extends Store { | |||
95 | () => this.stores.settings.app.spellcheckerLanguage, | 96 | () => this.stores.settings.app.spellcheckerLanguage, |
96 | () => this._shareSettingsWithServiceProcess(), | 97 | () => this._shareSettingsWithServiceProcess(), |
97 | ); | 98 | ); |
99 | |||
100 | reaction( | ||
101 | () => this.stores.settings.app.darkMode, | ||
102 | () => this._shareSettingsWithServiceProcess(), | ||
103 | ); | ||
98 | } | 104 | } |
99 | 105 | ||
100 | @computed get all() { | 106 | @computed get all() { |
@@ -125,7 +131,35 @@ export default class ServicesStore extends Store { | |||
125 | const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings; | 131 | const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings; |
126 | const services = this.allServicesRequest.execute().result || []; | 132 | const services = this.allServicesRequest.execute().result || []; |
127 | const filteredServices = showDisabledServices ? services : services.filter(service => service.isEnabled); | 133 | const filteredServices = showDisabledServices ? services : services.filter(service => service.isEnabled); |
128 | return keepAllWorkspacesLoaded ? filteredServices : workspaceStore.filterServicesByActiveWorkspace(filteredServices); | 134 | |
135 | let displayedServices; | ||
136 | if (keepAllWorkspacesLoaded) { | ||
137 | // Keep all enabled services loaded | ||
138 | displayedServices = filteredServices; | ||
139 | } else { | ||
140 | // Keep all services in current workspace loaded | ||
141 | displayedServices = workspaceStore.filterServicesByActiveWorkspace(filteredServices); | ||
142 | |||
143 | // Keep all services active in workspaces that should be kept loaded | ||
144 | for (const workspace of this.stores.workspaces.workspaces) { | ||
145 | // Check if workspace needs to be kept loaded | ||
146 | if (workspace.services.includes(KEEP_WS_LOADED_USID)) { | ||
147 | // Get services for workspace | ||
148 | const serviceIDs = workspace.services.filter(i => i !== KEEP_WS_LOADED_USID); | ||
149 | const wsServices = filteredServices.filter(service => serviceIDs.includes(service.id)); | ||
150 | |||
151 | displayedServices = [ | ||
152 | ...displayedServices, | ||
153 | ...wsServices, | ||
154 | ]; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | // Make sure every service is in the list only once | ||
159 | displayedServices = displayedServices.filter((v, i, a) => a.indexOf(v) === i); | ||
160 | } | ||
161 | |||
162 | return displayedServices; | ||
129 | } | 163 | } |
130 | 164 | ||
131 | @computed get filtered() { | 165 | @computed get filtered() { |
@@ -182,7 +216,6 @@ export default class ServicesStore extends Store { | |||
182 | 216 | ||
183 | if (redirect) { | 217 | if (redirect) { |
184 | this.stores.router.push('/settings/recipes'); | 218 | this.stores.router.push('/settings/recipes'); |
185 | gaEvent('Service', 'create', recipeId); | ||
186 | } | 219 | } |
187 | } | 220 | } |
188 | 221 | ||
@@ -259,7 +292,6 @@ export default class ServicesStore extends Store { | |||
259 | 292 | ||
260 | if (redirect) { | 293 | if (redirect) { |
261 | this.stores.router.push('/settings/services'); | 294 | this.stores.router.push('/settings/services'); |
262 | gaEvent('Service', 'update', service.recipe.id); | ||
263 | } | 295 | } |
264 | } | 296 | } |
265 | 297 | ||
@@ -274,19 +306,14 @@ export default class ServicesStore extends Store { | |||
274 | remove(result, c => c.id === serviceId); | 306 | remove(result, c => c.id === serviceId); |
275 | }); | 307 | }); |
276 | 308 | ||
277 | const service = this.one(serviceId); | ||
278 | |||
279 | await request._promise; | 309 | await request._promise; |
280 | this.actionStatus = request.result.status; | 310 | this.actionStatus = request.result.status; |
281 | |||
282 | gaEvent('Service', 'delete', service.recipe.id); | ||
283 | } | 311 | } |
284 | 312 | ||
285 | @action async _clearCache({ serviceId }) { | 313 | @action async _clearCache({ serviceId }) { |
286 | this.clearCacheRequest.reset(); | 314 | this.clearCacheRequest.reset(); |
287 | const request = this.clearCacheRequest.execute(serviceId); | 315 | const request = this.clearCacheRequest.execute(serviceId); |
288 | await request._promise; | 316 | await request._promise; |
289 | gaEvent('Service', 'clear cache'); | ||
290 | } | 317 | } |
291 | 318 | ||
292 | @action _setActive({ serviceId, keepActiveRoute }) { | 319 | @action _setActive({ serviceId, keepActiveRoute }) { |
@@ -298,8 +325,6 @@ export default class ServicesStore extends Store { | |||
298 | }); | 325 | }); |
299 | service.isActive = true; | 326 | service.isActive = true; |
300 | 327 | ||
301 | statsEvent('activate-service', service.recipe.id); | ||
302 | |||
303 | this._focusActiveService(); | 328 | this._focusActiveService(); |
304 | } | 329 | } |
305 | 330 | ||
@@ -403,7 +428,19 @@ export default class ServicesStore extends Store { | |||
403 | }, | 428 | }, |
404 | }); | 429 | }); |
405 | } else if (channel === 'notification') { | 430 | } else if (channel === 'notification') { |
406 | const options = args[0].options; | 431 | const { options } = args[0]; |
432 | |||
433 | // Check if we are in scheduled Do-not-Disturb time | ||
434 | const { | ||
435 | scheduledDNDEnabled, | ||
436 | scheduledDNDStart, | ||
437 | scheduledDNDEnd, | ||
438 | } = this.stores.settings.all.app; | ||
439 | |||
440 | if (scheduledDNDEnabled && isInTimeframe(scheduledDNDStart, scheduledDNDEnd)) { | ||
441 | return; | ||
442 | } | ||
443 | |||
407 | if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.app.isAppMuted) { | 444 | if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.app.isAppMuted) { |
408 | Object.assign(options, { | 445 | Object.assign(options, { |
409 | silent: true, | 446 | silent: true, |
@@ -411,8 +448,17 @@ export default class ServicesStore extends Store { | |||
411 | } | 448 | } |
412 | 449 | ||
413 | if (service.isNotificationEnabled) { | 450 | if (service.isNotificationEnabled) { |
414 | const title = typeof args[0].title === 'string' ? args[0].title : service.name; | 451 | let title = `Notification from ${service.name}`; |
415 | options.body = typeof options.body === 'string' ? options.body : ''; | 452 | if (!this.stores.settings.all.app.privateNotifications) { |
453 | options.body = typeof options.body === 'string' ? options.body : ''; | ||
454 | title = typeof args[0].title === 'string' ? args[0].title : service.name; | ||
455 | } else { | ||
456 | // Remove message data from notification in private mode | ||
457 | options.body = ''; | ||
458 | options.icon = '/assets/img/notification-badge.gif'; | ||
459 | } | ||
460 | |||
461 | console.log(title, options); | ||
416 | 462 | ||
417 | this.actions.app.notify({ | 463 | this.actions.app.notify({ |
418 | notificationId: args[0].notificationId, | 464 | notificationId: args[0].notificationId, |
@@ -530,7 +576,7 @@ export default class ServicesStore extends Store { | |||
530 | } | 576 | } |
531 | 577 | ||
532 | @action _reorderService({ oldIndex, newIndex }) { | 578 | @action _reorderService({ oldIndex, newIndex }) { |
533 | const showDisabledServices = this.stores.settings.all.app.showDisabledServices; | 579 | const { showDisabledServices } = this.stores.settings.all.app; |
534 | const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]); | 580 | const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]); |
535 | const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]); | 581 | const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]); |
536 | 582 | ||
@@ -549,8 +595,6 @@ export default class ServicesStore extends Store { | |||
549 | service.order = services[s.id]; | 595 | service.order = services[s.id]; |
550 | }); | 596 | }); |
551 | }); | 597 | }); |
552 | |||
553 | this._reorderAnalytics(); | ||
554 | } | 598 | } |
555 | 599 | ||
556 | @action _toggleNotifications({ serviceId }) { | 600 | @action _toggleNotifications({ serviceId }) { |
@@ -626,8 +670,8 @@ export default class ServicesStore extends Store { | |||
626 | } | 670 | } |
627 | 671 | ||
628 | _getUnreadMessageCountReaction() { | 672 | _getUnreadMessageCountReaction() { |
629 | const showMessageBadgeWhenMuted = this.stores.settings.all.app.showMessageBadgeWhenMuted; | 673 | const { showMessageBadgeWhenMuted } = this.stores.settings.all.app; |
630 | const showMessageBadgesEvenWhenMuted = this.stores.ui.showMessageBadgesEvenWhenMuted; | 674 | const { showMessageBadgesEvenWhenMuted } = this.stores.ui; |
631 | 675 | ||
632 | const unreadDirectMessageCount = this.allDisplayed | 676 | const unreadDirectMessageCount = this.allDisplayed |
633 | .filter(s => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) | 677 | .filter(s => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) |
@@ -754,10 +798,6 @@ export default class ServicesStore extends Store { | |||
754 | } | 798 | } |
755 | } | 799 | } |
756 | 800 | ||
757 | _reorderAnalytics = debounce(() => { | ||
758 | gaEvent('Service', 'order'); | ||
759 | }, ms('5s')); | ||
760 | |||
761 | _wrapIndex(index, delta, size) { | 801 | _wrapIndex(index, delta, size) { |
762 | return (((index + delta) % size) + size) % size; | 802 | return (((index + delta) % size) + size) % size; |
763 | } | 803 | } |