aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
authorLibravatar mhatvan <markus_hatvan@aon.at>2021-08-05 08:58:28 +0200
committerLibravatar Vijay Raghavan Aravamudhan <vraravam@users.noreply.github.com>2021-08-05 08:05:49 +0000
commit305c2c5ecb49a1349be2efb1ef557d61da9a64dc (patch)
tree19a05ed4ddfc1e5b5bb7fc3ecc071ad562da820f /src/stores
parentrefactor: minor refactoring: solve name-clash of env vars vs vars in the program (diff)
downloadferdium-app-305c2c5ecb49a1349be2efb1ef557d61da9a64dc.tar.gz
ferdium-app-305c2c5ecb49a1349be2efb1ef557d61da9a64dc.tar.zst
ferdium-app-305c2c5ecb49a1349be2efb1ef557d61da9a64dc.zip
refactor: general code improvements
- replace deprecated fs.exists with fs.existsSync - replace console.log with debug - replace hardcoded FERDI_VERSION in start.js with dynamic one from package.json - correct JSDoc annotations in Handler.js - simplify macOSPermissions.js - updates to various eslint rules - add FileReader to known globals
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/ServicesStore.js378
1 files changed, 262 insertions, 116 deletions
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index fefcb5080..829797930 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -1,10 +1,5 @@
1import { shell } from 'electron'; 1import { shell } from 'electron';
2import { 2import { action, reaction, computed, observable } from 'mobx';
3 action,
4 reaction,
5 computed,
6 observable,
7} from 'mobx';
8import { debounce, remove } from 'lodash'; 3import { debounce, remove } from 'lodash';
9import ms from 'ms'; 4import ms from 'ms';
10import { app } from '@electron/remote'; 5import { app } from '@electron/remote';
@@ -16,7 +11,10 @@ import Request from './lib/Request';
16import CachedRequest from './lib/CachedRequest'; 11import CachedRequest from './lib/CachedRequest';
17import { matchRoute } from '../helpers/routing-helpers'; 12import { matchRoute } from '../helpers/routing-helpers';
18import { isInTimeframe } from '../helpers/schedule-helpers'; 13import { isInTimeframe } from '../helpers/schedule-helpers';
19import { getRecipeDirectory, getDevRecipeDirectory } from '../helpers/recipe-helpers'; 14import {
15 getRecipeDirectory,
16 getDevRecipeDirectory,
17} from '../helpers/recipe-helpers';
20import { workspaceStore } from '../features/workspaces'; 18import { workspaceStore } from '../features/workspaces';
21import { KEEP_WS_LOADED_USID } from '../config'; 19import { KEEP_WS_LOADED_USID } from '../config';
22import { SPELLCHECKER_LOCALES } from '../i18n/languages'; 20import { SPELLCHECKER_LOCALES } from '../i18n/languages';
@@ -30,7 +28,10 @@ export default class ServicesStore extends Store {
30 28
31 @observable updateServiceRequest = new Request(this.api.services, 'update'); 29 @observable updateServiceRequest = new Request(this.api.services, 'update');
32 30
33 @observable reorderServicesRequest = new Request(this.api.services, 'reorder'); 31 @observable reorderServicesRequest = new Request(
32 this.api.services,
33 'reorder',
34 );
34 35
35 @observable deleteServiceRequest = new Request(this.api.services, 'delete'); 36 @observable deleteServiceRequest = new Request(this.api.services, 'delete');
36 37
@@ -51,22 +52,36 @@ export default class ServicesStore extends Store {
51 this.actions.service.blurActive.listen(this._blurActive.bind(this)); 52 this.actions.service.blurActive.listen(this._blurActive.bind(this));
52 this.actions.service.setActiveNext.listen(this._setActiveNext.bind(this)); 53 this.actions.service.setActiveNext.listen(this._setActiveNext.bind(this));
53 this.actions.service.setActivePrev.listen(this._setActivePrev.bind(this)); 54 this.actions.service.setActivePrev.listen(this._setActivePrev.bind(this));
54 this.actions.service.showAddServiceInterface.listen(this._showAddServiceInterface.bind(this)); 55 this.actions.service.showAddServiceInterface.listen(
56 this._showAddServiceInterface.bind(this),
57 );
55 this.actions.service.createService.listen(this._createService.bind(this)); 58 this.actions.service.createService.listen(this._createService.bind(this));
56 this.actions.service.createFromLegacyService.listen(this._createFromLegacyService.bind(this)); 59 this.actions.service.createFromLegacyService.listen(
60 this._createFromLegacyService.bind(this),
61 );
57 this.actions.service.updateService.listen(this._updateService.bind(this)); 62 this.actions.service.updateService.listen(this._updateService.bind(this));
58 this.actions.service.deleteService.listen(this._deleteService.bind(this)); 63 this.actions.service.deleteService.listen(this._deleteService.bind(this));
59 this.actions.service.openRecipeFile.listen(this._openRecipeFile.bind(this)); 64 this.actions.service.openRecipeFile.listen(this._openRecipeFile.bind(this));
60 this.actions.service.clearCache.listen(this._clearCache.bind(this)); 65 this.actions.service.clearCache.listen(this._clearCache.bind(this));
61 this.actions.service.setWebviewReference.listen(this._setWebviewReference.bind(this)); 66 this.actions.service.setWebviewReference.listen(
67 this._setWebviewReference.bind(this),
68 );
62 this.actions.service.detachService.listen(this._detachService.bind(this)); 69 this.actions.service.detachService.listen(this._detachService.bind(this));
63 this.actions.service.focusService.listen(this._focusService.bind(this)); 70 this.actions.service.focusService.listen(this._focusService.bind(this));
64 this.actions.service.focusActiveService.listen(this._focusActiveService.bind(this)); 71 this.actions.service.focusActiveService.listen(
72 this._focusActiveService.bind(this),
73 );
65 this.actions.service.toggleService.listen(this._toggleService.bind(this)); 74 this.actions.service.toggleService.listen(this._toggleService.bind(this));
66 this.actions.service.handleIPCMessage.listen(this._handleIPCMessage.bind(this)); 75 this.actions.service.handleIPCMessage.listen(
76 this._handleIPCMessage.bind(this),
77 );
67 this.actions.service.sendIPCMessage.listen(this._sendIPCMessage.bind(this)); 78 this.actions.service.sendIPCMessage.listen(this._sendIPCMessage.bind(this));
68 this.actions.service.sendIPCMessageToAllServices.listen(this._sendIPCMessageToAllServices.bind(this)); 79 this.actions.service.sendIPCMessageToAllServices.listen(
69 this.actions.service.setUnreadMessageCount.listen(this._setUnreadMessageCount.bind(this)); 80 this._sendIPCMessageToAllServices.bind(this),
81 );
82 this.actions.service.setUnreadMessageCount.listen(
83 this._setUnreadMessageCount.bind(this),
84 );
70 this.actions.service.openWindow.listen(this._openWindow.bind(this)); 85 this.actions.service.openWindow.listen(this._openWindow.bind(this));
71 this.actions.service.filter.listen(this._filter.bind(this)); 86 this.actions.service.filter.listen(this._filter.bind(this));
72 this.actions.service.resetFilter.listen(this._resetFilter.bind(this)); 87 this.actions.service.resetFilter.listen(this._resetFilter.bind(this));
@@ -74,16 +89,26 @@ export default class ServicesStore extends Store {
74 this.actions.service.reload.listen(this._reload.bind(this)); 89 this.actions.service.reload.listen(this._reload.bind(this));
75 this.actions.service.reloadActive.listen(this._reloadActive.bind(this)); 90 this.actions.service.reloadActive.listen(this._reloadActive.bind(this));
76 this.actions.service.reloadAll.listen(this._reloadAll.bind(this)); 91 this.actions.service.reloadAll.listen(this._reloadAll.bind(this));
77 this.actions.service.reloadUpdatedServices.listen(this._reloadUpdatedServices.bind(this)); 92 this.actions.service.reloadUpdatedServices.listen(
93 this._reloadUpdatedServices.bind(this),
94 );
78 this.actions.service.reorder.listen(this._reorder.bind(this)); 95 this.actions.service.reorder.listen(this._reorder.bind(this));
79 this.actions.service.toggleNotifications.listen(this._toggleNotifications.bind(this)); 96 this.actions.service.toggleNotifications.listen(
97 this._toggleNotifications.bind(this),
98 );
80 this.actions.service.toggleAudio.listen(this._toggleAudio.bind(this)); 99 this.actions.service.toggleAudio.listen(this._toggleAudio.bind(this));
81 this.actions.service.openDevTools.listen(this._openDevTools.bind(this)); 100 this.actions.service.openDevTools.listen(this._openDevTools.bind(this));
82 this.actions.service.openDevToolsForActiveService.listen(this._openDevToolsForActiveService.bind(this)); 101 this.actions.service.openDevToolsForActiveService.listen(
102 this._openDevToolsForActiveService.bind(this),
103 );
83 this.actions.service.hibernate.listen(this._hibernate.bind(this)); 104 this.actions.service.hibernate.listen(this._hibernate.bind(this));
84 this.actions.service.awake.listen(this._awake.bind(this)); 105 this.actions.service.awake.listen(this._awake.bind(this));
85 this.actions.service.resetLastPollTimer.listen(this._resetLastPollTimer.bind(this)); 106 this.actions.service.resetLastPollTimer.listen(
86 this.actions.service.shareSettingsWithServiceProcess.listen(this._shareSettingsWithServiceProcess.bind(this)); 107 this._resetLastPollTimer.bind(this),
108 );
109 this.actions.service.shareSettingsWithServiceProcess.listen(
110 this._shareSettingsWithServiceProcess.bind(this),
111 );
87 112
88 this.registerReactions([ 113 this.registerReactions([
89 this._focusServiceReaction.bind(this), 114 this._focusServiceReaction.bind(this),
@@ -164,27 +189,42 @@ export default class ServicesStore extends Store {
164 * Run various maintenance tasks on services 189 * Run various maintenance tasks on services
165 */ 190 */
166 _serviceMaintenance() { 191 _serviceMaintenance() {
167 this.all.forEach((service) => { 192 this.all.forEach(service => {
168 // Defines which services should be hibernated or woken up 193 // Defines which services should be hibernated or woken up
169 if (!service.isActive) { 194 if (!service.isActive) {
170 if (!service.lastHibernated && (Date.now() - service.lastUsed > ms(`${this.stores.settings.all.app.hibernationStrategy}s`))) { 195 if (
196 !service.lastHibernated &&
197 Date.now() - service.lastUsed >
198 ms(`${this.stores.settings.all.app.hibernationStrategy}s`)
199 ) {
171 // If service is stale, hibernate it. 200 // If service is stale, hibernate it.
172 this._hibernate({ serviceId: service.id }); 201 this._hibernate({ serviceId: service.id });
173 } 202 }
174 203
175 if (service.lastHibernated && Number(this.stores.settings.all.app.wakeUpStrategy) > 0) { 204 if (
205 service.lastHibernated &&
206 Number(this.stores.settings.all.app.wakeUpStrategy) > 0
207 ) {
176 // If service is in hibernation and the wakeup time has elapsed, wake it. 208 // If service is in hibernation and the wakeup time has elapsed, wake it.
177 if ((Date.now() - service.lastHibernated > ms(`${this.stores.settings.all.app.wakeUpStrategy}s`))) { 209 if (
210 Date.now() - service.lastHibernated >
211 ms(`${this.stores.settings.all.app.wakeUpStrategy}s`)
212 ) {
178 this._awake({ serviceId: service.id }); 213 this._awake({ serviceId: service.id });
179 } 214 }
180 } 215 }
181 } 216 }
182 217
183 if (service.lastPoll && (service.lastPoll - service.lastPollAnswer > ms('1m'))) { 218 if (
219 service.lastPoll &&
220 service.lastPoll - service.lastPollAnswer > ms('1m')
221 ) {
184 // If service did not reply for more than 1m try to reload. 222 // If service did not reply for more than 1m try to reload.
185 if (!service.isActive) { 223 if (!service.isActive) {
186 if (this.stores.app.isOnline && service.lostRecipeReloadAttempt < 3) { 224 if (this.stores.app.isOnline && service.lostRecipeReloadAttempt < 3) {
187 debug(`Reloading service: ${service.name} (${service.id}). Attempt: ${service.lostRecipeReloadAttempt}`); 225 debug(
226 `Reloading service: ${service.name} (${service.id}). Attempt: ${service.lostRecipeReloadAttempt}`,
227 );
188 // service.webview.reload(); 228 // service.webview.reload();
189 service.lostRecipeReloadAttempt += 1; 229 service.lostRecipeReloadAttempt += 1;
190 230
@@ -206,21 +246,29 @@ export default class ServicesStore extends Store {
206 if (this.stores.user.isLoggedIn) { 246 if (this.stores.user.isLoggedIn) {
207 const services = this.allServicesRequest.execute().result; 247 const services = this.allServicesRequest.execute().result;
208 if (services) { 248 if (services) {
209 return observable(services.slice().slice().sort((a, b) => a.order - b.order).map((s, index) => { 249 return observable(
210 s.index = index; 250 services
211 return s; 251 .slice()
212 })); 252 .slice()
253 .sort((a, b) => a.order - b.order)
254 .map((s, index) => {
255 s.index = index;
256 return s;
257 }),
258 );
213 } 259 }
214 } 260 }
215 return []; 261 return [];
216 } 262 }
217 263
218 @computed get enabled() { 264 @computed get enabled() {
219 return this.all.filter((service) => service.isEnabled); 265 return this.all.filter(service => service.isEnabled);
220 } 266 }
221 267
222 @computed get allDisplayed() { 268 @computed get allDisplayed() {
223 const services = this.stores.settings.all.app.showDisabledServices ? this.all : this.enabled; 269 const services = this.stores.settings.all.app.showDisabledServices
270 ? this.all
271 : this.enabled;
224 return workspaceStore.filterServicesByActiveWorkspace(services); 272 return workspaceStore.filterServicesByActiveWorkspace(services);
225 } 273 }
226 274
@@ -229,7 +277,9 @@ export default class ServicesStore extends Store {
229 const { showDisabledServices } = this.stores.settings.all.app; 277 const { showDisabledServices } = this.stores.settings.all.app;
230 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings; 278 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings;
231 const services = this.allServicesRequest.execute().result || []; 279 const services = this.allServicesRequest.execute().result || [];
232 const filteredServices = showDisabledServices ? services : services.filter((service) => service.isEnabled); 280 const filteredServices = showDisabledServices
281 ? services
282 : services.filter(service => service.isEnabled);
233 283
234 let displayedServices; 284 let displayedServices;
235 if (keepAllWorkspacesLoaded) { 285 if (keepAllWorkspacesLoaded) {
@@ -237,40 +287,49 @@ export default class ServicesStore extends Store {
237 displayedServices = filteredServices; 287 displayedServices = filteredServices;
238 } else { 288 } else {
239 // Keep all services in current workspace loaded 289 // Keep all services in current workspace loaded
240 displayedServices = workspaceStore.filterServicesByActiveWorkspace(filteredServices); 290 displayedServices =
291 workspaceStore.filterServicesByActiveWorkspace(filteredServices);
241 292
242 // Keep all services active in workspaces that should be kept loaded 293 // Keep all services active in workspaces that should be kept loaded
243 for (const workspace of this.stores.workspaces.workspaces) { 294 for (const workspace of this.stores.workspaces.workspaces) {
244 // Check if workspace needs to be kept loaded 295 // Check if workspace needs to be kept loaded
245 if (workspace.services.includes(KEEP_WS_LOADED_USID)) { 296 if (workspace.services.includes(KEEP_WS_LOADED_USID)) {
246 // Get services for workspace 297 // Get services for workspace
247 const serviceIDs = workspace.services.filter((i) => i !== KEEP_WS_LOADED_USID); 298 const serviceIDs = workspace.services.filter(
248 const wsServices = filteredServices.filter((service) => serviceIDs.includes(service.id)); 299 i => i !== KEEP_WS_LOADED_USID,
249 300 );
250 displayedServices = [ 301 const wsServices = filteredServices.filter(service =>
251 ...displayedServices, 302 serviceIDs.includes(service.id),
252 ...wsServices, 303 );
253 ]; 304
305 displayedServices = [...displayedServices, ...wsServices];
254 } 306 }
255 } 307 }
256 308
257 // Make sure every service is in the list only once 309 // Make sure every service is in the list only once
258 displayedServices = displayedServices.filter((v, i, a) => a.indexOf(v) === i); 310 displayedServices = displayedServices.filter(
311 (v, i, a) => a.indexOf(v) === i,
312 );
259 } 313 }
260 314
261 return displayedServices; 315 return displayedServices;
262 } 316 }
263 317
264 @computed get filtered() { 318 @computed get filtered() {
265 return this.all.filter((service) => service.name.toLowerCase().includes(this.filterNeedle.toLowerCase())); 319 return this.all.filter(service =>
320 service.name.toLowerCase().includes(this.filterNeedle.toLowerCase()),
321 );
266 } 322 }
267 323
268 @computed get active() { 324 @computed get active() {
269 return this.all.find((service) => service.isActive); 325 return this.all.find(service => service.isActive);
270 } 326 }
271 327
272 @computed get activeSettings() { 328 @computed get activeSettings() {
273 const match = matchRoute('/settings/services/edit/:id', this.stores.router.location.pathname); 329 const match = matchRoute(
330 '/settings/services/edit/:id',
331 this.stores.router.location.pathname,
332 );
274 if (match) { 333 if (match) {
275 const activeService = this.one(match.id); 334 const activeService = this.one(match.id);
276 if (activeService) { 335 if (activeService) {
@@ -284,7 +343,11 @@ export default class ServicesStore extends Store {
284 } 343 }
285 344
286 @computed get isTodosServiceAdded() { 345 @computed get isTodosServiceAdded() {
287 return this.allDisplayed.find((service) => service.isTodosService && service.isEnabled) || false; 346 return (
347 this.allDisplayed.find(
348 service => service.isTodosService && service.isEnabled,
349 ) || false
350 );
288 } 351 }
289 352
290 @computed get isTodosServiceActive() { 353 @computed get isTodosServiceActive() {
@@ -292,7 +355,7 @@ export default class ServicesStore extends Store {
292 } 355 }
293 356
294 one(id) { 357 one(id) {
295 return this.all.find((service) => service.id === id); 358 return this.all.find(service => service.id === id);
296 } 359 }
297 360
298 async _showAddServiceInterface({ recipeId }) { 361 async _showAddServiceInterface({ recipeId }) {
@@ -301,7 +364,10 @@ export default class ServicesStore extends Store {
301 364
302 // Actions 365 // Actions
303 async _createService({ 366 async _createService({
304 recipeId, serviceData, redirect = true, skipCleanup = false, 367 recipeId,
368 serviceData,
369 redirect = true,
370 skipCleanup = false,
305 }) { 371 }) {
306 if (!this.stores.recipes.isInstalled(recipeId)) { 372 if (!this.stores.recipes.isInstalled(recipeId)) {
307 debug(`Recipe "${recipeId}" is not installed, installing recipe`); 373 debug(`Recipe "${recipeId}" is not installed, installing recipe`);
@@ -311,17 +377,21 @@ export default class ServicesStore extends Store {
311 377
312 // set default values for serviceData 378 // set default values for serviceData
313 // eslint-disable-next-line prefer-object-spread 379 // eslint-disable-next-line prefer-object-spread
314 Object.assign({ 380 Object.assign(
315 isEnabled: true, 381 {
316 isHibernationEnabled: false, 382 isEnabled: true,
317 isNotificationEnabled: true, 383 isHibernationEnabled: false,
318 isBadgeEnabled: true, 384 isNotificationEnabled: true,
319 isMuted: false, 385 isBadgeEnabled: true,
320 customIcon: false, 386 isMuted: false,
321 isDarkModeEnabled: false, 387 customIcon: false,
322 spellcheckerLanguage: SPELLCHECKER_LOCALES[this.stores.settings.app.spellcheckerLanguage], 388 isDarkModeEnabled: false,
323 userAgentPref: '', 389 spellcheckerLanguage:
324 }, serviceData); 390 SPELLCHECKER_LOCALES[this.stores.settings.app.spellcheckerLanguage],
391 userAgentPref: '',
392 },
393 serviceData,
394 );
325 395
326 let data = serviceData; 396 let data = serviceData;
327 397
@@ -329,9 +399,10 @@ export default class ServicesStore extends Store {
329 data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData); 399 data = this._cleanUpTeamIdAndCustomUrl(recipeId, serviceData);
330 } 400 }
331 401
332 const response = await this.createServiceRequest.execute(recipeId, data)._promise; 402 const response = await this.createServiceRequest.execute(recipeId, data)
403 ._promise;
333 404
334 this.allServicesRequest.patch((result) => { 405 this.allServicesRequest.patch(result => {
335 if (!result) return; 406 if (!result) return;
336 result.push(response.data); 407 result.push(response.data);
337 }); 408 });
@@ -375,7 +446,10 @@ export default class ServicesStore extends Store {
375 446
376 @action async _updateService({ serviceId, serviceData, redirect = true }) { 447 @action async _updateService({ serviceId, serviceData, redirect = true }) {
377 const service = this.one(serviceId); 448 const service = this.one(serviceId);
378 const data = this._cleanUpTeamIdAndCustomUrl(service.recipe.id, serviceData); 449 const data = this._cleanUpTeamIdAndCustomUrl(
450 service.recipe.id,
451 serviceData,
452 );
379 const request = this.updateServiceRequest.execute(serviceId, data); 453 const request = this.updateServiceRequest.execute(serviceId, data);
380 454
381 const newData = serviceData; 455 const newData = serviceData;
@@ -386,7 +460,7 @@ export default class ServicesStore extends Store {
386 newData.hasCustomUploadedIcon = true; 460 newData.hasCustomUploadedIcon = true;
387 } 461 }
388 462
389 this.allServicesRequest.patch((result) => { 463 this.allServicesRequest.patch(result => {
390 if (!result) return; 464 if (!result) return;
391 465
392 // patch custom icon deletion 466 // patch custom icon deletion
@@ -400,7 +474,10 @@ export default class ServicesStore extends Store {
400 newData.iconUrl = data.customIconUrl; 474 newData.iconUrl = data.customIconUrl;
401 } 475 }
402 476
403 Object.assign(result.find((c) => c.id === serviceId), newData); 477 Object.assign(
478 result.find(c => c.id === serviceId),
479 newData,
480 );
404 }); 481 });
405 482
406 await request._promise; 483 await request._promise;
@@ -433,8 +510,8 @@ export default class ServicesStore extends Store {
433 this.stores.router.push(redirect); 510 this.stores.router.push(redirect);
434 } 511 }
435 512
436 this.allServicesRequest.patch((result) => { 513 this.allServicesRequest.patch(result => {
437 remove(result, (c) => c.id === serviceId); 514 remove(result, c => c.id === serviceId);
438 }); 515 });
439 516
440 await request._promise; 517 await request._promise;
@@ -459,12 +536,15 @@ export default class ServicesStore extends Store {
459 // Create and open file 536 // Create and open file
460 const filePath = path.join(directory, file); 537 const filePath = path.join(directory, file);
461 if (file === 'user.js') { 538 if (file === 'user.js') {
462 if (!await fs.exists(filePath)) { 539 if (!fs.existsSync(filePath)) {
463 await fs.writeFile(filePath, `module.exports = (config, Ferdi) => { 540 await fs.writeFile(
541 filePath,
542 `module.exports = (config, Ferdi) => {
464 // Write your scripts here 543 // Write your scripts here
465 console.log("Hello, World!", config); 544 console.log("Hello, World!", config);
466} 545}
467`); 546`,
547 );
468 } 548 }
469 } else { 549 } else {
470 await fs.ensureFile(filePath); 550 await fs.ensureFile(filePath);
@@ -478,22 +558,27 @@ export default class ServicesStore extends Store {
478 await request._promise; 558 await request._promise;
479 } 559 }
480 560
481 @action _setActive({ serviceId, keepActiveRoute }) { 561 @action _setActive({ serviceId, keepActiveRoute = null }) {
482 if (!keepActiveRoute) this.stores.router.push('/'); 562 if (!keepActiveRoute) this.stores.router.push('/');
483 const service = this.one(serviceId); 563 const service = this.one(serviceId);
484 564
485 this.all.forEach((s) => { 565 this.all.forEach(s => {
486 s.isActive = false; 566 s.isActive = false;
487 }); 567 });
488 service.isActive = true; 568 service.isActive = true;
489 this._awake({ serviceId: service.id }); 569 this._awake({ serviceId: service.id });
490 570
491 if (this.isTodosServiceActive && !this.stores.todos.settings.isFeatureEnabledByUser) { 571 if (
572 this.isTodosServiceActive &&
573 !this.stores.todos.settings.isFeatureEnabledByUser
574 ) {
492 this.actions.todos.toggleTodosFeatureVisibility(); 575 this.actions.todos.toggleTodosFeatureVisibility();
493 } 576 }
494 577
495 // Update list of last used services 578 // Update list of last used services
496 this.lastUsedServices = this.lastUsedServices.filter((id) => id !== serviceId); 579 this.lastUsedServices = this.lastUsedServices.filter(
580 id => id !== serviceId,
581 );
497 this.lastUsedServices.unshift(serviceId); 582 this.lastUsedServices.unshift(serviceId);
498 583
499 this._focusActiveService(); 584 this._focusActiveService();
@@ -505,7 +590,11 @@ export default class ServicesStore extends Store {
505 } 590 }
506 591
507 @action _setActiveNext() { 592 @action _setActiveNext() {
508 const nextIndex = this._wrapIndex(this.allDisplayed.findIndex((service) => service.isActive), 1, this.allDisplayed.length); 593 const nextIndex = this._wrapIndex(
594 this.allDisplayed.findIndex(service => service.isActive),
595 1,
596 this.allDisplayed.length,
597 );
509 598
510 // TODO: simplify this; 599 // TODO: simplify this;
511 this.all.forEach((s, index) => { 600 this.all.forEach((s, index) => {
@@ -515,7 +604,11 @@ export default class ServicesStore extends Store {
515 } 604 }
516 605
517 @action _setActivePrev() { 606 @action _setActivePrev() {
518 const prevIndex = this._wrapIndex(this.allDisplayed.findIndex((service) => service.isActive), -1, this.allDisplayed.length); 607 const prevIndex = this._wrapIndex(
608 this.allDisplayed.findIndex(service => service.isActive),
609 -1,
610 this.allDisplayed.length,
611 );
519 612
520 // TODO: simplify this; 613 // TODO: simplify this;
521 this.all.forEach((s, index) => { 614 this.all.forEach((s, index) => {
@@ -606,17 +699,21 @@ export default class ServicesStore extends Store {
606 const { options } = args[0]; 699 const { options } = args[0];
607 700
608 // Check if we are in scheduled Do-not-Disturb time 701 // Check if we are in scheduled Do-not-Disturb time
609 const { 702 const { scheduledDNDEnabled, scheduledDNDStart, scheduledDNDEnd } =
610 scheduledDNDEnabled, 703 this.stores.settings.all.app;
611 scheduledDNDStart,
612 scheduledDNDEnd,
613 } = this.stores.settings.all.app;
614 704
615 if (scheduledDNDEnabled && isInTimeframe(scheduledDNDStart, scheduledDNDEnd)) { 705 if (
706 scheduledDNDEnabled &&
707 isInTimeframe(scheduledDNDStart, scheduledDNDEnd)
708 ) {
616 return; 709 return;
617 } 710 }
618 711
619 if (service.recipe.hasNotificationSound || service.isMuted || this.stores.settings.all.app.isAppMuted) { 712 if (
713 service.recipe.hasNotificationSound ||
714 service.isMuted ||
715 this.stores.settings.all.app.isAppMuted
716 ) {
620 Object.assign(options, { 717 Object.assign(options, {
621 silent: true, 718 silent: true,
622 }); 719 });
@@ -626,7 +723,8 @@ export default class ServicesStore extends Store {
626 let title = `Notification from ${service.name}`; 723 let title = `Notification from ${service.name}`;
627 if (!this.stores.settings.all.app.privateNotifications) { 724 if (!this.stores.settings.all.app.privateNotifications) {
628 options.body = typeof options.body === 'string' ? options.body : ''; 725 options.body = typeof options.body === 'string' ? options.body : '';
629 title = typeof args[0].title === 'string' ? args[0].title : service.name; 726 title =
727 typeof args[0].title === 'string' ? args[0].title : service.name;
630 } else { 728 } else {
631 // Remove message data from notification in private mode 729 // Remove message data from notification in private mode
632 options.body = ''; 730 options.body = '';
@@ -689,11 +787,13 @@ export default class ServicesStore extends Store {
689 } 787 }
690 788
691 @action _sendIPCMessageToAllServices({ channel, args }) { 789 @action _sendIPCMessageToAllServices({ channel, args }) {
692 this.all.forEach((s) => this.actions.service.sendIPCMessage({ 790 this.all.forEach(s =>
693 serviceId: s.id, 791 this.actions.service.sendIPCMessage({
694 channel, 792 serviceId: s.id,
695 args, 793 channel,
696 })); 794 args,
795 }),
796 );
697 } 797 }
698 798
699 @action _openWindow({ event }) { 799 @action _openWindow({ event }) {
@@ -740,9 +840,11 @@ export default class ServicesStore extends Store {
740 } 840 }
741 841
742 @action _reloadAll() { 842 @action _reloadAll() {
743 this.enabled.forEach((s) => this._reload({ 843 this.enabled.forEach(s =>
744 serviceId: s.id, 844 this._reload({
745 })); 845 serviceId: s.id,
846 }),
847 );
746 } 848 }
747 849
748 @action _reloadUpdatedServices() { 850 @action _reloadUpdatedServices() {
@@ -761,10 +863,18 @@ export default class ServicesStore extends Store {
761 863
762 @action _reorderService({ oldIndex, newIndex }) { 864 @action _reorderService({ oldIndex, newIndex }) {
763 const { showDisabledServices } = this.stores.settings.all.app; 865 const { showDisabledServices } = this.stores.settings.all.app;
764 const oldEnabledSortIndex = showDisabledServices ? oldIndex : this.all.indexOf(this.enabled[oldIndex]); 866 const oldEnabledSortIndex = showDisabledServices
765 const newEnabledSortIndex = showDisabledServices ? newIndex : this.all.indexOf(this.enabled[newIndex]); 867 ? oldIndex
766 868 : this.all.indexOf(this.enabled[oldIndex]);
767 this.all.splice(newEnabledSortIndex, 0, this.all.splice(oldEnabledSortIndex, 1)[0]); 869 const newEnabledSortIndex = showDisabledServices
870 ? newIndex
871 : this.all.indexOf(this.enabled[newIndex]);
872
873 this.all.splice(
874 newEnabledSortIndex,
875 0,
876 this.all.splice(oldEnabledSortIndex, 1)[0],
877 );
768 878
769 const services = {}; 879 const services = {};
770 this.all.forEach((s, index) => { 880 this.all.forEach((s, index) => {
@@ -772,8 +882,8 @@ export default class ServicesStore extends Store {
772 }); 882 });
773 883
774 this.reorderServicesRequest.execute(services); 884 this.reorderServicesRequest.execute(services);
775 this.allServicesRequest.patch((data) => { 885 this.allServicesRequest.patch(data => {
776 data.forEach((s) => { 886 data.forEach(s => {
777 const service = s; 887 const service = s;
778 888
779 service.order = services[s.id]; 889 service.order = services[s.id];
@@ -851,15 +961,19 @@ export default class ServicesStore extends Store {
851 } 961 }
852 962
853 @action _resetLastPollTimer({ serviceId = null }) { 963 @action _resetLastPollTimer({ serviceId = null }) {
854 debug(`Reset last poll timer for ${serviceId ? `service: "${serviceId}"` : 'all services'}`); 964 debug(
965 `Reset last poll timer for ${
966 serviceId ? `service: "${serviceId}"` : 'all services'
967 }`,
968 );
855 969
856 const resetTimer = (service) => { 970 const resetTimer = service => {
857 service.lastPollAnswer = Date.now(); 971 service.lastPollAnswer = Date.now();
858 service.lastPoll = Date.now(); 972 service.lastPoll = Date.now();
859 }; 973 };
860 974
861 if (!serviceId) { 975 if (!serviceId) {
862 this.allDisplayed.forEach((service) => resetTimer(service)); 976 this.allDisplayed.forEach(service => resetTimer(service));
863 } else { 977 } else {
864 const service = this.one(serviceId); 978 const service = this.one(serviceId);
865 if (service) { 979 if (service) {
@@ -893,9 +1007,13 @@ export default class ServicesStore extends Store {
893 _mapActiveServiceToServiceModelReaction() { 1007 _mapActiveServiceToServiceModelReaction() {
894 const { activeService } = this.stores.settings.all.service; 1008 const { activeService } = this.stores.settings.all.service;
895 if (this.allDisplayed.length) { 1009 if (this.allDisplayed.length) {
896 this.allDisplayed.map((service) => Object.assign(service, { 1010 this.allDisplayed.map(service =>
897 isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id, 1011 Object.assign(service, {
898 })); 1012 isActive: activeService
1013 ? activeService === service.id
1014 : this.allDisplayed[0].id === service.id,
1015 }),
1016 );
899 } 1017 }
900 } 1018 }
901 1019
@@ -904,13 +1022,24 @@ export default class ServicesStore extends Store {
904 const { showMessageBadgesEvenWhenMuted } = this.stores.ui; 1022 const { showMessageBadgesEvenWhenMuted } = this.stores.ui;
905 1023
906 const unreadDirectMessageCount = this.allDisplayed 1024 const unreadDirectMessageCount = this.allDisplayed
907 .filter((s) => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) 1025 .filter(
908 .map((s) => s.unreadDirectMessageCount) 1026 s =>
1027 (showMessageBadgeWhenMuted || s.isNotificationEnabled) &&
1028 showMessageBadgesEvenWhenMuted &&
1029 s.isBadgeEnabled,
1030 )
1031 .map(s => s.unreadDirectMessageCount)
909 .reduce((a, b) => a + b, 0); 1032 .reduce((a, b) => a + b, 0);
910 1033
911 const unreadIndirectMessageCount = this.allDisplayed 1034 const unreadIndirectMessageCount = this.allDisplayed
912 .filter((s) => (showMessageBadgeWhenMuted && showMessageBadgesEvenWhenMuted) && (s.isBadgeEnabled && s.isIndirectMessageBadgeEnabled)) 1035 .filter(
913 .map((s) => s.unreadIndirectMessageCount) 1036 s =>
1037 showMessageBadgeWhenMuted &&
1038 showMessageBadgesEvenWhenMuted &&
1039 s.isBadgeEnabled &&
1040 s.isIndirectMessageBadgeEnabled,
1041 )
1042 .map(s => s.unreadIndirectMessageCount)
914 .reduce((a, b) => a + b, 0); 1043 .reduce((a, b) => a + b, 0);
915 1044
916 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases 1045 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases
@@ -936,7 +1065,7 @@ export default class ServicesStore extends Store {
936 const { enabled } = this; 1065 const { enabled } = this;
937 const { isAppMuted } = this.stores.settings.app; 1066 const { isAppMuted } = this.stores.settings.app;
938 1067
939 enabled.forEach((service) => { 1068 enabled.forEach(service => {
940 const { isAttached } = service; 1069 const { isAttached } = service;
941 const isMuted = isAppMuted || service.isMuted; 1070 const isMuted = isAppMuted || service.isMuted;
942 1071
@@ -963,7 +1092,12 @@ export default class ServicesStore extends Store {
963 1092
964 if (!recipe) return; 1093 if (!recipe) return;
965 1094
966 if (recipe.hasTeamId && recipe.hasCustomUrl && data.team && data.customUrl) { 1095 if (
1096 recipe.hasTeamId &&
1097 recipe.hasCustomUrl &&
1098 data.team &&
1099 data.customUrl
1100 ) {
967 delete serviceData.team; 1101 delete serviceData.team;
968 } 1102 }
969 1103
@@ -971,11 +1105,17 @@ export default class ServicesStore extends Store {
971 } 1105 }
972 1106
973 _checkForActiveService() { 1107 _checkForActiveService() {
974 if (!this.stores.router.location || this.stores.router.location.pathname.includes('auth/signup')) { 1108 if (
1109 !this.stores.router.location ||
1110 this.stores.router.location.pathname.includes('auth/signup')
1111 ) {
975 return; 1112 return;
976 } 1113 }
977 1114
978 if (this.allDisplayed.findIndex((service) => service.isActive) === -1 && this.allDisplayed.length !== 0) { 1115 if (
1116 this.allDisplayed.findIndex(service => service.isActive) === -1 &&
1117 this.allDisplayed.length !== 0
1118 ) {
979 debug('No active service found, setting active service to index 0'); 1119 debug('No active service found, setting active service to index 0');
980 1120
981 this._setActive({ serviceId: this.allDisplayed[0].id }); 1121 this._setActive({ serviceId: this.allDisplayed[0].id });
@@ -988,13 +1128,19 @@ export default class ServicesStore extends Store {
988 1128
989 if (service.webview) { 1129 if (service.webview) {
990 // We need to completely clone the object, otherwise Electron won't be able to send the object via IPC 1130 // We need to completely clone the object, otherwise Electron won't be able to send the object via IPC
991 const shareWithWebview = JSON.parse(JSON.stringify(service.shareWithWebview)); 1131 const shareWithWebview = JSON.parse(
1132 JSON.stringify(service.shareWithWebview),
1133 );
992 1134
993 debug('Initialize recipe', service.recipe.id, service.name); 1135 debug('Initialize recipe', service.recipe.id, service.name);
994 service.webview.send('initialize-recipe', { 1136 service.webview.send(
995 ...shareWithWebview, 1137 'initialize-recipe',
996 franzVersion: app.getVersion(), 1138 {
997 }, service.recipe); 1139 ...shareWithWebview,
1140 franzVersion: app.getVersion(),
1141 },
1142 service.recipe,
1143 );
998 } 1144 }
999 } 1145 }
1000 1146