diff options
author | mhatvan <markus_hatvan@aon.at> | 2021-08-05 08:58:28 +0200 |
---|---|---|
committer | Vijay Raghavan Aravamudhan <vraravam@users.noreply.github.com> | 2021-08-05 08:05:49 +0000 |
commit | 305c2c5ecb49a1349be2efb1ef557d61da9a64dc (patch) | |
tree | 19a05ed4ddfc1e5b5bb7fc3ecc071ad562da820f /src/stores | |
parent | refactor: minor refactoring: solve name-clash of env vars vs vars in the program (diff) | |
download | ferdium-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.js | 378 |
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 @@ | |||
1 | import { shell } from 'electron'; | 1 | import { shell } from 'electron'; |
2 | import { | 2 | import { action, reaction, computed, observable } from 'mobx'; |
3 | action, | ||
4 | reaction, | ||
5 | computed, | ||
6 | observable, | ||
7 | } from 'mobx'; | ||
8 | import { debounce, remove } from 'lodash'; | 3 | import { debounce, remove } from 'lodash'; |
9 | import ms from 'ms'; | 4 | import ms from 'ms'; |
10 | import { app } from '@electron/remote'; | 5 | import { app } from '@electron/remote'; |
@@ -16,7 +11,10 @@ import Request from './lib/Request'; | |||
16 | import CachedRequest from './lib/CachedRequest'; | 11 | import CachedRequest from './lib/CachedRequest'; |
17 | import { matchRoute } from '../helpers/routing-helpers'; | 12 | import { matchRoute } from '../helpers/routing-helpers'; |
18 | import { isInTimeframe } from '../helpers/schedule-helpers'; | 13 | import { isInTimeframe } from '../helpers/schedule-helpers'; |
19 | import { getRecipeDirectory, getDevRecipeDirectory } from '../helpers/recipe-helpers'; | 14 | import { |
15 | getRecipeDirectory, | ||
16 | getDevRecipeDirectory, | ||
17 | } from '../helpers/recipe-helpers'; | ||
20 | import { workspaceStore } from '../features/workspaces'; | 18 | import { workspaceStore } from '../features/workspaces'; |
21 | import { KEEP_WS_LOADED_USID } from '../config'; | 19 | import { KEEP_WS_LOADED_USID } from '../config'; |
22 | import { SPELLCHECKER_LOCALES } from '../i18n/languages'; | 20 | import { 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 | ||