aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-07-30 10:54:54 +0200
committerLibravatar GitHub <noreply@github.com>2021-07-30 14:24:54 +0530
commitf4b4416ea52d564bc2dbe543a82084ed98843ccc (patch)
tree7ca6b23571c86458a6b799746c91a7191de02715 /src
parent5.6.1-nightly.8 [skip ci] (diff)
downloadferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.tar.gz
ferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.tar.zst
ferdium-app-f4b4416ea52d564bc2dbe543a82084ed98843ccc.zip
chore: migrate from tslint to @typescript-eslint (#1706)
- update .eslintrc to work for .js and .ts - update devDependencies - lint properly both root /src and nested /packages - update webhint recommended setting for tsconfig.json to shrink output - Manage all eslint rules from the repo root - escape single quotes in scripts to please windows build Co-authored-by: Vijay A <avijayr@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/actions/lib/actions.js4
-rw-r--r--src/api/server/LocalApi.js20
-rw-r--r--src/api/server/ServerApi.js288
-rw-r--r--src/app.js8
-rw-r--r--src/components/auth/AuthLayout.js28
-rw-r--r--src/components/auth/ChangeServer.js4
-rw-r--r--src/components/auth/Locked.js2
-rw-r--r--src/components/auth/Login.js2
-rw-r--r--src/components/auth/Password.js2
-rw-r--r--src/components/auth/SetupAssistant.js10
-rw-r--r--src/components/auth/Signup.js2
-rw-r--r--src/components/auth/Welcome.js2
-rw-r--r--src/components/layout/AppLayout.js4
-rw-r--r--src/components/services/content/ConnectionLostBanner.js2
-rw-r--r--src/components/services/content/ErrorHandlers/styles.js2
-rw-r--r--src/components/services/content/Services.js2
-rw-r--r--src/components/services/content/WebviewCrashHandler.js2
-rw-r--r--src/components/services/tabs/Tabbar.js10
-rw-r--r--src/components/settings/services/EditServiceForm.js2
-rw-r--r--src/components/settings/services/ServicesDashboard.js4
-rw-r--r--src/components/settings/settings/EditSettingsForm.js23
-rw-r--r--src/components/settings/supportFerdi/SupportFerdiDashboard.js18
-rw-r--r--src/components/settings/user/EditUserForm.js2
-rw-r--r--src/components/ui/AppLoader/index.js2
-rw-r--r--src/components/ui/FeatureItem.js2
-rw-r--r--src/components/ui/FeatureList.js2
-rw-r--r--src/components/ui/Link.js2
-rw-r--r--src/components/ui/Modal/styles.js2
-rw-r--r--src/components/ui/Radio.js2
-rw-r--r--src/components/ui/SearchInput.js2
-rw-r--r--src/components/ui/Select.js4
-rw-r--r--src/components/ui/ServiceIcon.js2
-rw-r--r--src/components/ui/Slider.js2
-rw-r--r--src/components/ui/Tabs/TabItem.js8
-rw-r--r--src/components/ui/Tabs/Tabs.js2
-rw-r--r--src/components/ui/Toggle.js2
-rw-r--r--src/components/ui/ToggleRaw.js2
-rw-r--r--src/components/ui/WebviewLoader/styles.js2
-rw-r--r--src/components/util/ErrorBoundary/styles.js2
-rw-r--r--src/containers/auth/SetupAssistantScreen.js2
-rw-r--r--src/containers/auth/SignupScreen.js2
-rw-r--r--src/containers/layout/AppLayoutContainer.js4
-rw-r--r--src/containers/settings/AccountScreen.js5
-rw-r--r--src/containers/settings/EditServiceScreen.js4
-rw-r--r--src/containers/settings/EditSettingsScreen.js2
-rw-r--r--src/containers/settings/EditUserScreen.js2
-rw-r--r--src/containers/settings/RecipesScreen.js10
-rw-r--r--src/features/announcements/components/AnnouncementScreen.js2
-rw-r--r--src/features/communityRecipes/store.js2
-rw-r--r--src/features/publishDebugInfo/Component.js6
-rw-r--r--src/features/quickSwitch/Component.js4
-rw-r--r--src/features/shareFranz/Component.js2
-rw-r--r--src/features/todos/containers/TodosScreen.js4
-rw-r--r--src/features/utils/ActionBinding.js4
-rw-r--r--src/features/utils/FeatureStore.js8
-rw-r--r--src/features/webControls/components/WebControls.js4
-rw-r--r--src/features/webControls/containers/WebControlsScreen.js2
-rw-r--r--src/features/workspaces/api.js2
-rw-r--r--src/features/workspaces/components/WorkspaceDrawer.js2
-rw-r--r--src/features/workspaces/components/WorkspaceDrawerItem.js2
-rw-r--r--src/features/workspaces/components/WorkspaceItem.js2
-rw-r--r--src/features/workspaces/components/WorkspaceServiceListItem.js2
-rw-r--r--src/features/workspaces/components/WorkspaceSwitchingIndicator.js2
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js4
-rw-r--r--src/features/workspaces/containers/WorkspacesScreen.js4
-rw-r--r--src/features/workspaces/models/Workspace.js4
-rw-r--r--src/helpers/array-helpers.js6
-rw-r--r--src/helpers/async-helpers.js2
-rw-r--r--src/helpers/service-helpers.js2
-rw-r--r--src/helpers/validation-helpers.js2
-rw-r--r--src/models/Recipe.js2
-rw-r--r--src/models/Service.js2
-rw-r--r--src/models/UserAgent.js4
-rw-r--r--src/stores/AppStore.js105
-rw-r--r--src/stores/NewsStore.js2
-rw-r--r--src/stores/RecipePreviewsStore.js2
-rw-r--r--src/stores/RecipesStore.js8
-rw-r--r--src/stores/ServicesStore.js44
-rw-r--r--src/stores/UIStore.js2
-rw-r--r--src/stores/UserStore.js4
-rw-r--r--src/stores/lib/CachedRequest.js4
-rw-r--r--src/stores/lib/Reaction.js4
-rw-r--r--src/stores/lib/Request.js2
-rw-r--r--src/stores/lib/Store.js6
-rw-r--r--src/webview/contextMenuBuilder.js4
-rw-r--r--src/webview/lib/RecipeWebview.js2
-rw-r--r--src/webview/notifications.js2
-rw-r--r--src/webview/spellchecker.js2
88 files changed, 447 insertions, 342 deletions
diff --git a/src/actions/lib/actions.js b/src/actions/lib/actions.js
index b38db9946..7be40f1cf 100644
--- a/src/actions/lib/actions.js
+++ b/src/actions/lib/actions.js
@@ -8,12 +8,12 @@ export const createActionsFromDefinitions = (actionDefinitions, validate) => {
8 }; 8 };
9 actions[actionName] = action; 9 actions[actionName] = action;
10 action.listeners = []; 10 action.listeners = [];
11 action.listen = listener => action.listeners.push(listener); 11 action.listen = (listener) => action.listeners.push(listener);
12 action.off = (listener) => { 12 action.off = (listener) => {
13 const { listeners } = action; 13 const { listeners } = action;
14 listeners.splice(listeners.indexOf(listener), 1); 14 listeners.splice(listeners.indexOf(listener), 1);
15 }; 15 };
16 action.notify = params => action.listeners.forEach(listener => listener(params)); 16 action.notify = (params) => action.listeners.forEach((listener) => listener(params));
17 }); 17 });
18 return actions; 18 return actions;
19}; 19};
diff --git a/src/api/server/LocalApi.js b/src/api/server/LocalApi.js
index 4b1f03f22..2d5bd8b80 100644
--- a/src/api/server/LocalApi.js
+++ b/src/api/server/LocalApi.js
@@ -2,7 +2,7 @@ import { ipcRenderer } from 'electron';
2import { session } from '@electron/remote'; 2import { session } from '@electron/remote';
3import du from 'du'; 3import du from 'du';
4 4
5import { getServicePartitionsDirectory } from '../../helpers/service-helpers.js'; 5import { getServicePartitionsDirectory } from '../../helpers/service-helpers';
6 6
7const debug = require('debug')('Ferdi:LocalApi'); 7const debug = require('debug')('Ferdi:LocalApi');
8 8
@@ -41,11 +41,23 @@ export default class LocalApi {
41 } 41 }
42 42
43 async clearCache(serviceId = null) { 43 async clearCache(serviceId = null) {
44 const s = serviceId ? session.fromPartition(`persist:service-${serviceId}`) : session.defaultSession; 44 const s = serviceId
45 ? session.fromPartition(`persist:service-${serviceId}`)
46 : session.defaultSession;
45 47
46 debug('LocalApi::clearCache resolves', (serviceId || 'clearAppCache')); 48 debug('LocalApi::clearCache resolves', serviceId || 'clearAppCache');
47 await s.clearStorageData({ 49 await s.clearStorageData({
48 storages: ['appcache', 'cookies', 'filesystem', 'indexdb', 'localstorage', 'shadercache', 'websql', 'serviceworkers', 'cachestorage'], 50 storages: [
51 'appcache',
52 'cookies',
53 'filesystem',
54 'indexdb',
55 'localstorage',
56 'shadercache',
57 'websql',
58 'serviceworkers',
59 'cachestorage',
60 ],
49 quotas: ['temporary', 'persistent', 'syncable'], 61 quotas: ['temporary', 'persistent', 'syncable'],
50 }); 62 });
51 return s.clearCache(); 63 return s.clearCache();
diff --git a/src/api/server/ServerApi.js b/src/api/server/ServerApi.js
index 78a98e544..bc1d665b1 100644
--- a/src/api/server/ServerApi.js
+++ b/src/api/server/ServerApi.js
@@ -23,16 +23,11 @@ import {
23 loadRecipeConfig, 23 loadRecipeConfig,
24} from '../../helpers/recipe-helpers'; 24} from '../../helpers/recipe-helpers';
25 25
26import { 26import { removeServicePartitionDirectory } from '../../helpers/service-helpers';
27 removeServicePartitionDirectory,
28} from '../../helpers/service-helpers.js';
29 27
30const debug = require('debug')('Ferdi:ServerApi'); 28const debug = require('debug')('Ferdi:ServerApi');
31 29
32module.paths.unshift( 30module.paths.unshift(getDevRecipeDirectory(), getRecipeDirectory());
33 getDevRecipeDirectory(),
34 getRecipeDirectory(),
35);
36 31
37const { default: fetch } = remoteRequire('electron-fetch'); 32const { default: fetch } = remoteRequire('electron-fetch');
38 33
@@ -43,12 +38,16 @@ export default class ServerApi {
43 38
44 // User 39 // User
45 async login(email, passwordHash) { 40 async login(email, passwordHash) {
46 const request = await sendAuthRequest(`${apiBase()}/auth/login`, { 41 const request = await sendAuthRequest(
47 method: 'POST', 42 `${apiBase()}/auth/login`,
48 headers: { 43 {
49 Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`, 44 method: 'POST',
45 headers: {
46 Authorization: `Basic ${window.btoa(`${email}:${passwordHash}`)}`,
47 },
50 }, 48 },
51 }, false); 49 false,
50 );
52 if (!request.ok) { 51 if (!request.ok) {
53 throw request; 52 throw request;
54 } 53 }
@@ -59,10 +58,14 @@ export default class ServerApi {
59 } 58 }
60 59
61 async signup(data) { 60 async signup(data) {
62 const request = await sendAuthRequest(`${apiBase()}/auth/signup`, { 61 const request = await sendAuthRequest(
63 method: 'POST', 62 `${apiBase()}/auth/signup`,
64 body: JSON.stringify(data), 63 {
65 }, false); 64 method: 'POST',
65 body: JSON.stringify(data),
66 },
67 false,
68 );
66 if (!request.ok) { 69 if (!request.ok) {
67 throw request; 70 throw request;
68 } 71 }
@@ -86,12 +89,16 @@ export default class ServerApi {
86 } 89 }
87 90
88 async retrievePassword(email) { 91 async retrievePassword(email) {
89 const request = await sendAuthRequest(`${apiBase()}/auth/password`, { 92 const request = await sendAuthRequest(
90 method: 'POST', 93 `${apiBase()}/auth/password`,
91 body: JSON.stringify({ 94 {
92 email, 95 method: 'POST',
93 }), 96 body: JSON.stringify({
94 }, false); 97 email,
98 }),
99 },
100 false,
101 );
95 if (!request.ok) { 102 if (!request.ok) {
96 throw request; 103 throw request;
97 } 104 }
@@ -128,7 +135,9 @@ export default class ServerApi {
128 } 135 }
129 const updatedData = await request.json(); 136 const updatedData = await request.json();
130 137
131 const user = Object.assign(updatedData, { data: new UserModel(updatedData.data) }); 138 const user = Object.assign(updatedData, {
139 data: new UserModel(updatedData.data),
140 });
132 debug('ServerApi::updateUserInfo resolves', user); 141 debug('ServerApi::updateUserInfo resolves', user);
133 return user; 142 return user;
134 } 143 }
@@ -159,7 +168,7 @@ export default class ServerApi {
159 const data = await request.json(); 168 const data = await request.json();
160 169
161 let services = await this._mapServiceModels(data); 170 let services = await this._mapServiceModels(data);
162 services = services.filter(service => service !== null); 171 services = services.filter((service) => service !== null);
163 debug('ServerApi::getServices resolves', services); 172 debug('ServerApi::getServices resolves', services);
164 return services; 173 return services;
165 } 174 }
@@ -175,12 +184,17 @@ export default class ServerApi {
175 const serviceData = await request.json(); 184 const serviceData = await request.json();
176 185
177 if (data.iconFile) { 186 if (data.iconFile) {
178 const iconData = await this.uploadServiceIcon(serviceData.data.id, data.iconFile); 187 const iconData = await this.uploadServiceIcon(
188 serviceData.data.id,
189 data.iconFile,
190 );
179 191
180 serviceData.data = iconData; 192 serviceData.data = iconData;
181 } 193 }
182 194
183 const service = Object.assign(serviceData, { data: await this._prepareServiceModel(serviceData.data) }); 195 const service = Object.assign(serviceData, {
196 data: await this._prepareServiceModel(serviceData.data),
197 });
184 198
185 debug('ServerApi::createService resolves', service); 199 debug('ServerApi::createService resolves', service);
186 return service; 200 return service;
@@ -204,7 +218,9 @@ export default class ServerApi {
204 218
205 const serviceData = await request.json(); 219 const serviceData = await request.json();
206 220
207 const service = Object.assign(serviceData, { data: await this._prepareServiceModel(serviceData.data) }); 221 const service = Object.assign(serviceData, {
222 data: await this._prepareServiceModel(serviceData.data),
223 });
208 224
209 debug('ServerApi::updateService resolves', service); 225 debug('ServerApi::updateService resolves', service);
210 return service; 226 return service;
@@ -221,7 +237,10 @@ export default class ServerApi {
221 237
222 delete requestData.headers['Content-Type']; 238 delete requestData.headers['Content-Type'];
223 239
224 const request = await window.fetch(`${apiBase()}/service/${serviceId}`, requestData); 240 const request = await window.fetch(
241 `${apiBase()}/service/${serviceId}`,
242 requestData,
243 );
225 244
226 if (!request.ok) { 245 if (!request.ok) {
227 throw request; 246 throw request;
@@ -292,18 +311,21 @@ export default class ServerApi {
292 // Recipes 311 // Recipes
293 async getInstalledRecipes() { 312 async getInstalledRecipes() {
294 const recipesDirectory = getRecipeDirectory(); 313 const recipesDirectory = getRecipeDirectory();
295 const paths = fs.readdirSync(recipesDirectory) 314 const paths = fs
296 .filter(file => ( 315 .readdirSync(recipesDirectory)
297 fs.statSync(path.join(recipesDirectory, file)).isDirectory() 316 .filter(
298 && file !== 'temp' 317 (file) => fs.statSync(path.join(recipesDirectory, file)).isDirectory()
299 && file !== 'dev' 318 && file !== 'temp'
300 )); 319 && file !== 'dev',
301 320 );
302 this.recipes = paths.map((id) => { 321
303 // eslint-disable-next-line 322 this.recipes = paths
304 const Recipe = require(id)(RecipeModel); 323 .map((id) => {
305 return new Recipe(loadRecipeConfig(id)); 324 // eslint-disable-next-line
306 }).filter(recipe => recipe.id); 325 const Recipe = require(id)(RecipeModel);
326 return new Recipe(loadRecipeConfig(id));
327 })
328 .filter((recipe) => recipe.id);
307 329
308 this.recipes = this.recipes.concat(this._getDevRecipes()); 330 this.recipes = this.recipes.concat(this._getDevRecipes());
309 331
@@ -373,7 +395,9 @@ export default class ServerApi {
373 console.log('[ServerApi::getRecipePackage] Using internal recipe file'); 395 console.log('[ServerApi::getRecipePackage] Using internal recipe file');
374 archivePath = internalRecipeFile; 396 archivePath = internalRecipeFile;
375 } else { 397 } else {
376 console.log('[ServerApi::getRecipePackage] Downloading recipe from server'); 398 console.log(
399 '[ServerApi::getRecipePackage] Downloading recipe from server',
400 );
377 archivePath = tempArchivePath; 401 archivePath = tempArchivePath;
378 402
379 const packageUrl = `${apiBase()}/recipes/download/${recipeId}`; 403 const packageUrl = `${apiBase()}/recipes/download/${recipeId}`;
@@ -393,12 +417,14 @@ export default class ServerApi {
393 preservePaths: true, 417 preservePaths: true,
394 unlink: true, 418 unlink: true,
395 preserveOwner: false, 419 preserveOwner: false,
396 onwarn: x => console.log('warn', recipeId, x), 420 onwarn: (x) => console.log('warn', recipeId, x),
397 }); 421 });
398 422
399 await sleep(10); 423 await sleep(10);
400 424
401 const { id } = fs.readJsonSync(path.join(recipeTempDirectory, 'package.json')); 425 const { id } = fs.readJsonSync(
426 path.join(recipeTempDirectory, 'package.json'),
427 );
402 const recipeDirectory = path.join(recipesDirectory, id); 428 const recipeDirectory = path.join(recipesDirectory, id);
403 fs.copySync(recipeTempDirectory, recipeDirectory); 429 fs.copySync(recipeTempDirectory, recipeDirectory);
404 fs.remove(recipeTempDirectory); 430 fs.remove(recipeTempDirectory);
@@ -414,7 +440,9 @@ export default class ServerApi {
414 440
415 // News 441 // News
416 async getLatestNews() { 442 async getLatestNews() {
417 const url = `${apiBase(true)}/news?platform=${osPlatform}&arch=${osArch}&version=${app.getVersion()}`; 443 const url = `${apiBase(
444 true,
445 )}/news?platform=${osPlatform}&arch=${osArch}&version=${app.getVersion()}`;
418 const request = await sendAuthRequest(url); 446 const request = await sendAuthRequest(url);
419 if (!request.ok) throw request; 447 if (!request.ok) throw request;
420 const data = await request.json(); 448 const data = await request.json();
@@ -435,9 +463,13 @@ export default class ServerApi {
435 throw new Error('Server not loaded'); 463 throw new Error('Server not loaded');
436 } 464 }
437 465
438 const request = await sendAuthRequest(`${apiBase(false)}/health`, { 466 const request = await sendAuthRequest(
439 method: 'GET', 467 `${apiBase(false)}/health`,
440 }, false); 468 {
469 method: 'GET',
470 },
471 false,
472 );
441 if (!request.ok) { 473 if (!request.ok) {
442 throw request; 474 throw request;
443 } 475 }
@@ -445,23 +477,31 @@ export default class ServerApi {
445 } 477 }
446 478
447 async getLegacyServices() { 479 async getLegacyServices() {
448 const file = path.join(app.getPath('userData'), 'settings', 'services.json'); 480 const file = path.join(
481 app.getPath('userData'),
482 'settings',
483 'services.json',
484 );
449 485
450 try { 486 try {
451 const config = fs.readJsonSync(file); 487 const config = fs.readJsonSync(file);
452 488
453 if (Object.prototype.hasOwnProperty.call(config, 'services')) { 489 if (Object.prototype.hasOwnProperty.call(config, 'services')) {
454 const services = await Promise.all(config.services.map(async (s) => { 490 const services = await Promise.all(
455 const service = s; 491 config.services.map(async (s) => {
456 const request = await sendAuthRequest(`${apiBase()}/recipes/${s.service}`); 492 const service = s;
457 493 const request = await sendAuthRequest(
458 if (request.status === 200) { 494 `${apiBase()}/recipes/${s.service}`,
459 const data = await request.json(); 495 );
460 service.recipe = new RecipePreviewModel(data); 496
461 } 497 if (request.status === 200) {
462 498 const data = await request.json();
463 return service; 499 service.recipe = new RecipePreviewModel(data);
464 })); 500 }
501
502 return service;
503 }),
504 );
465 505
466 debug('ServerApi::getLegacyServices resolves', services); 506 debug('ServerApi::getLegacyServices resolves', services);
467 return services; 507 return services;
@@ -475,17 +515,19 @@ export default class ServerApi {
475 515
476 // Helper 516 // Helper
477 async _mapServiceModels(services) { 517 async _mapServiceModels(services) {
478 const recipes = services.map(s => s.recipeId); 518 const recipes = services.map((s) => s.recipeId);
479 await this._bulkRecipeCheck(recipes); 519 await this._bulkRecipeCheck(recipes);
480 /* eslint-disable no-return-await */ 520 /* eslint-disable no-return-await */
481 return Promise.all(services.map(async service => await this._prepareServiceModel(service))); 521 return Promise.all(
522 services.map(async (service) => await this._prepareServiceModel(service)),
523 );
482 /* eslint-enable no-return-await */ 524 /* eslint-enable no-return-await */
483 } 525 }
484 526
485 async _prepareServiceModel(service) { 527 async _prepareServiceModel(service) {
486 let recipe; 528 let recipe;
487 try { 529 try {
488 recipe = this.recipes.find(r => r.id === service.recipeId); 530 recipe = this.recipes.find((r) => r.id === service.recipeId);
489 531
490 if (!recipe) { 532 if (!recipe) {
491 console.warn(`Recipe ${service.recipeId} not loaded`); 533 console.warn(`Recipe ${service.recipeId} not loaded`);
@@ -501,21 +543,25 @@ export default class ServerApi {
501 543
502 async _bulkRecipeCheck(unfilteredRecipes) { 544 async _bulkRecipeCheck(unfilteredRecipes) {
503 // Filter recipe duplicates as we don't need to download 3 Slack recipes 545 // Filter recipe duplicates as we don't need to download 3 Slack recipes
504 const recipes = unfilteredRecipes.filter((elem, pos, arr) => arr.indexOf(elem) === pos); 546 const recipes = unfilteredRecipes.filter(
547 (elem, pos, arr) => arr.indexOf(elem) === pos,
548 );
505 549
506 return Promise.all(recipes 550 return Promise.all(
507 .map(async (recipeId) => { 551 recipes.map(async (recipeId) => {
508 let recipe = this.recipes.find(r => r.id === recipeId); 552 let recipe = this.recipes.find((r) => r.id === recipeId);
509 553
510 if (!recipe) { 554 if (!recipe) {
511 console.warn(`Recipe '${recipeId}' not installed, trying to fetch from server`); 555 console.warn(
556 `Recipe '${recipeId}' not installed, trying to fetch from server`,
557 );
512 558
513 await this.getRecipePackage(recipeId); 559 await this.getRecipePackage(recipeId);
514 560
515 debug('Rerun ServerAPI::getInstalledRecipes'); 561 debug('Rerun ServerAPI::getInstalledRecipes');
516 await this.getInstalledRecipes(); 562 await this.getInstalledRecipes();
517 563
518 recipe = this.recipes.find(r => r.id === recipeId); 564 recipe = this.recipes.find((r) => r.id === recipeId);
519 565
520 if (!recipe) { 566 if (!recipe) {
521 console.warn(`Could not load recipe ${recipeId}`); 567 console.warn(`Could not load recipe ${recipeId}`);
@@ -524,69 +570,83 @@ export default class ServerApi {
524 } 570 }
525 571
526 return recipe; 572 return recipe;
527 })).catch(err => console.error('Can\'t load recipe', err)); 573 }),
574 ).catch((err) => console.error("Can't load recipe", err));
528 } 575 }
529 576
530 _mapRecipePreviewModel(recipes) { 577 _mapRecipePreviewModel(recipes) {
531 return recipes.map((recipe) => { 578 return recipes
532 try { 579 .map((recipe) => {
533 return new RecipePreviewModel(recipe); 580 try {
534 } catch (e) { 581 return new RecipePreviewModel(recipe);
535 console.error(e); 582 } catch (e) {
536 return null; 583 console.error(e);
537 } 584 return null;
538 }).filter(recipe => recipe !== null); 585 }
586 })
587 .filter((recipe) => recipe !== null);
539 } 588 }
540 589
541 _mapNewsModels(news) { 590 _mapNewsModels(news) {
542 return news.map((newsItem) => { 591 return news
543 try { 592 .map((newsItem) => {
544 return new NewsModel(newsItem); 593 try {
545 } catch (e) { 594 return new NewsModel(newsItem);
546 console.error(e); 595 } catch (e) {
547 return null; 596 console.error(e);
548 } 597 return null;
549 }).filter(newsItem => newsItem !== null); 598 }
599 })
600 .filter((newsItem) => newsItem !== null);
550 } 601 }
551 602
552 _mapOrderModels(orders) { 603 _mapOrderModels(orders) {
553 return orders.map((orderItem) => { 604 return orders
554 try { 605 .map((orderItem) => {
555 return new OrderModel(orderItem); 606 try {
556 } catch (e) { 607 return new OrderModel(orderItem);
557 console.error(e); 608 } catch (e) {
558 return null; 609 console.error(e);
559 } 610 return null;
560 }).filter(orderItem => orderItem !== null); 611 }
612 })
613 .filter((orderItem) => orderItem !== null);
561 } 614 }
562 615
563 _getDevRecipes() { 616 _getDevRecipes() {
564 const recipesDirectory = getDevRecipeDirectory(); 617 const recipesDirectory = getDevRecipeDirectory();
565 try { 618 try {
566 const paths = fs.readdirSync(recipesDirectory) 619 const paths = fs
567 .filter(file => fs.statSync(path.join(recipesDirectory, file)).isDirectory() && file !== 'temp'); 620 .readdirSync(recipesDirectory)
568 621 .filter(
569 const recipes = paths.map((id) => { 622 (file) => fs.statSync(path.join(recipesDirectory, file)).isDirectory()
570 let Recipe; 623 && file !== 'temp',
571 try { 624 );
572 // eslint-disable-next-line 625
573 Recipe = require(id)(RecipeModel); 626 const recipes = paths
574 return new Recipe(loadRecipeConfig(id)); 627 .map((id) => {
575 } catch (err) { 628 let Recipe;
576 console.error(err); 629 try {
577 } 630 // eslint-disable-next-line
631 Recipe = require(id)(RecipeModel);
632 return new Recipe(loadRecipeConfig(id));
633 } catch (err) {
634 console.error(err);
635 }
578 636
579 return false; 637 return false;
580 }).filter(recipe => recipe.id).map((data) => { 638 })
581 const recipe = data; 639 .filter((recipe) => recipe.id)
640 .map((data) => {
641 const recipe = data;
582 642
583 recipe.icons = { 643 recipe.icons = {
584 svg: `${recipe.path}/icon.svg`, 644 svg: `${recipe.path}/icon.svg`,
585 }; 645 };
586 recipe.local = true; 646 recipe.local = true;
587 647
588 return data; 648 return data;
589 }); 649 });
590 650
591 return recipes; 651 return recipes;
592 } catch (err) { 652 } catch (err) {
diff --git a/src/app.js b/src/app.js
index aab1729d7..a2d60dbe4 100644
--- a/src/app.js
+++ b/src/app.js
@@ -59,7 +59,7 @@ window.addEventListener('load', () => {
59}); 59});
60 60
61// Prevent drag and drop into window from redirecting 61// Prevent drag and drop into window from redirecting
62window.addEventListener('dragover', event => event.preventDefault()); 62window.addEventListener('dragover', (event) => event.preventDefault());
63window.addEventListener('drop', event => event.preventDefault()); 63window.addEventListener('drop', (event) => event.preventDefault());
64window.addEventListener('dragover', event => event.stopPropagation()); 64window.addEventListener('dragover', (event) => event.stopPropagation());
65window.addEventListener('drop', event => event.stopPropagation()); 65window.addEventListener('drop', (event) => event.stopPropagation());
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js
index 6fa3adf92..c0e6b982b 100644
--- a/src/components/auth/AuthLayout.js
+++ b/src/components/auth/AuthLayout.js
@@ -7,14 +7,19 @@ import { TitleBar } from 'electron-react-titlebar';
7import Link from '../ui/Link'; 7import Link from '../ui/Link';
8import InfoBar from '../ui/InfoBar'; 8import InfoBar from '../ui/InfoBar';
9 9
10import { oneOrManyChildElements, globalError as globalErrorPropType } from '../../prop-types'; 10import {
11 oneOrManyChildElements,
12 globalError as globalErrorPropType,
13} from '../../prop-types';
11import globalMessages from '../../i18n/globalMessages'; 14import globalMessages from '../../i18n/globalMessages';
12 15
13import { isWindows } from '../../environment'; 16import { isWindows } from '../../environment';
14import AppUpdateInfoBar from '../AppUpdateInfoBar'; 17import AppUpdateInfoBar from '../AppUpdateInfoBar';
15import { GITHUB_FERDI_URL } from '../../config'; 18import { GITHUB_FERDI_URL } from '../../config';
16 19
17export default @observer class AuthLayout extends Component { 20export default
21@observer
22class AuthLayout extends Component {
18 static propTypes = { 23 static propTypes = {
19 children: oneOrManyChildElements.isRequired, 24 children: oneOrManyChildElements.isRequired,
20 error: globalErrorPropType.isRequired, 25 error: globalErrorPropType.isRequired,
@@ -30,7 +35,7 @@ export default @observer class AuthLayout extends Component {
30 35
31 state = { 36 state = {
32 shouldShowAppUpdateInfoBar: true, 37 shouldShowAppUpdateInfoBar: true,
33 } 38 };
34 39
35 static defaultProps = { 40 static defaultProps = {
36 nextAppReleaseVersion: null, 41 nextAppReleaseVersion: null,
@@ -57,12 +62,15 @@ export default @observer class AuthLayout extends Component {
57 62
58 return ( 63 return (
59 <> 64 <>
60 {isWindows && !isFullScreen && <TitleBar menu={window.ferdi.menu.template} icon="assets/images/logo.svg" />} 65 {isWindows && !isFullScreen && (
66 <TitleBar
67 menu={window.ferdi.menu.template}
68 icon="assets/images/logo.svg"
69 />
70 )}
61 <div className="auth"> 71 <div className="auth">
62 {!isOnline && ( 72 {!isOnline && (
63 <InfoBar 73 <InfoBar type="warning">
64 type="warning"
65 >
66 <span className="mdi mdi-flash" /> 74 <span className="mdi mdi-flash" />
67 {intl.formatMessage(globalMessages.notConnectedToTheInternet)} 75 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
68 </InfoBar> 76 </InfoBar>
@@ -95,7 +103,11 @@ export default @observer class AuthLayout extends Component {
95 })} 103 })}
96 </div> 104 </div>
97 {/* </div> */} 105 {/* </div> */}
98 <Link to={`${GITHUB_FERDI_URL}/ferdi`} className="auth__adlk" target="_blank"> 106 <Link
107 to={`${GITHUB_FERDI_URL}/ferdi`}
108 className="auth__adlk"
109 target="_blank"
110 >
99 <img src="./assets/images/adlk.svg" alt="" /> 111 <img src="./assets/images/adlk.svg" alt="" />
100 </Link> 112 </Link>
101 </div> 113 </div>
diff --git a/src/components/auth/ChangeServer.js b/src/components/auth/ChangeServer.js
index 0dedd825a..7bab80280 100644
--- a/src/components/auth/ChangeServer.js
+++ b/src/components/auth/ChangeServer.js
@@ -100,7 +100,7 @@ export default @observer class ChangeServer extends Component {
100 const { intl } = this.context; 100 const { intl } = this.context;
101 return ( 101 return (
102 <div className="auth__container"> 102 <div className="auth__container">
103 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 103 <form className="franz-form auth__form" onSubmit={(e) => this.submit(e)}>
104 <h1>{intl.formatMessage(messages.headline)}</h1> 104 <h1>{intl.formatMessage(messages.headline)}</h1>
105 {form.$('server').value === this.franzServer 105 {form.$('server').value === this.franzServer
106 && ( 106 && (
@@ -113,7 +113,7 @@ export default @observer class ChangeServer extends Component {
113 && ( 113 && (
114 <Input 114 <Input
115 placeholder="Custom Server" 115 placeholder="Custom Server"
116 onChange={e => this.submit(e)} 116 onChange={(e) => this.submit(e)}
117 field={form.$('customServer')} 117 field={form.$('customServer')}
118 /> 118 />
119 )} 119 )}
diff --git a/src/components/auth/Locked.js b/src/components/auth/Locked.js
index 1fdbea595..2ad8a2409 100644
--- a/src/components/auth/Locked.js
+++ b/src/components/auth/Locked.js
@@ -102,7 +102,7 @@ export default @observer class Locked extends Component {
102 102
103 return ( 103 return (
104 <div className="auth__container"> 104 <div className="auth__container">
105 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 105 <form className="franz-form auth__form" onSubmit={(e) => this.submit(e)}>
106 <img 106 <img
107 src="./assets/images/logo.svg" 107 src="./assets/images/logo.svg"
108 className="auth__logo" 108 className="auth__logo"
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 52b09eab6..9e6a8d046 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -135,7 +135,7 @@ export default @inject('actions') @observer class Login extends Component {
135 135
136 return ( 136 return (
137 <div className="auth__container"> 137 <div className="auth__container">
138 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 138 <form className="franz-form auth__form" onSubmit={(e) => this.submit(e)}>
139 <img 139 <img
140 src="./assets/images/logo.svg" 140 src="./assets/images/logo.svg"
141 className="auth__logo" 141 className="auth__logo"
diff --git a/src/components/auth/Password.js b/src/components/auth/Password.js
index ad34e39af..eafc48502 100644
--- a/src/components/auth/Password.js
+++ b/src/components/auth/Password.js
@@ -86,7 +86,7 @@ export default @observer class Password extends Component {
86 86
87 return ( 87 return (
88 <div className="auth__container"> 88 <div className="auth__container">
89 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 89 <form className="franz-form auth__form" onSubmit={(e) => this.submit(e)}>
90 <img 90 <img
91 src="./assets/images/logo.svg" 91 src="./assets/images/logo.svg"
92 className="auth__logo" 92 className="auth__logo"
diff --git a/src/components/auth/SetupAssistant.js b/src/components/auth/SetupAssistant.js
index e03cf9101..bd9069eb7 100644
--- a/src/components/auth/SetupAssistant.js
+++ b/src/components/auth/SetupAssistant.js
@@ -34,7 +34,7 @@ const messages = defineMessages({
34 }, 34 },
35}); 35});
36 36
37const styles = theme => ({ 37const styles = (theme) => ({
38 root: { 38 root: {
39 width: '500px !important', 39 width: '500px !important',
40 textAlign: 'center', 40 textAlign: 'center',
@@ -161,7 +161,7 @@ class SetupAssistant extends Component {
161 const sanitizedWorkspace = slackWorkspace.trim().replace(/^https?:\/\//, ''); 161 const sanitizedWorkspace = slackWorkspace.trim().replace(/^https?:\/\//, '');
162 162
163 if (sanitizedWorkspace) { 163 if (sanitizedWorkspace) {
164 const index = services.findIndex(s => s.id === SLACK_ID); 164 const index = services.findIndex((s) => s.id === SLACK_ID);
165 165
166 if (index === -1) { 166 if (index === -1) {
167 const newServices = services; 167 const newServices = services;
@@ -215,11 +215,11 @@ class SetupAssistant extends Component {
215 <button 215 <button
216 className={classnames({ 216 className={classnames({
217 [classes.serviceContainer]: true, 217 [classes.serviceContainer]: true,
218 [classes.selected]: this.state.services.findIndex(s => s.id === id) !== -1, 218 [classes.selected]: this.state.services.findIndex((s) => s.id === id) !== -1,
219 })} 219 })}
220 key={id} 220 key={id}
221 onClick={() => { 221 onClick={() => {
222 const index = this.state.services.findIndex(s => s.id === id); 222 const index = this.state.services.findIndex((s) => s.id === id);
223 if (index === -1) { 223 if (index === -1) {
224 if (id === SLACK_ID) { 224 if (id === SLACK_ID) {
225 this.setState({ isSlackModalOpen: true }); 225 this.setState({ isSlackModalOpen: true });
@@ -283,7 +283,7 @@ class SetupAssistant extends Component {
283 <Input 283 <Input
284 suffix=".slack.com" 284 suffix=".slack.com"
285 placeholder="workspace-url" 285 placeholder="workspace-url"
286 onChange={e => this.setState({ slackWorkspace: e.target.value })} 286 onChange={(e) => this.setState({ slackWorkspace: e.target.value })}
287 value={slackWorkspace} 287 value={slackWorkspace}
288 /> 288 />
289 <div className={classes.modalActionContainer}> 289 <div className={classes.modalActionContainer}>
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index 140867ea1..411b6697b 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -138,7 +138,7 @@ export default @inject('actions') @observer class Signup extends Component {
138 return ( 138 return (
139 <div className="auth__scroll-container"> 139 <div className="auth__scroll-container">
140 <div className="auth__container auth__container--signup"> 140 <div className="auth__container auth__container--signup">
141 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> 141 <form className="franz-form auth__form" onSubmit={(e) => this.submit(e)}>
142 <img 142 <img
143 src="./assets/images/logo.svg" 143 src="./assets/images/logo.svg"
144 className="auth__logo" 144 className="auth__logo"
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js
index 5f2fac64b..cb522e26e 100644
--- a/src/components/auth/Welcome.js
+++ b/src/components/auth/Welcome.js
@@ -84,7 +84,7 @@ export default @inject('actions') @observer class Login extends Component {
84 </Link> 84 </Link>
85 </div> 85 </div>
86 <div className="welcome__featured-services"> 86 <div className="welcome__featured-services">
87 {recipes.map(recipe => ( 87 {recipes.map((recipe) => (
88 <div 88 <div
89 key={recipe.id} 89 key={recipe.id}
90 className="welcome__featured-service" 90 className="welcome__featured-service"
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 7e4d0e53e..6e1d7c9a0 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -44,7 +44,7 @@ const messages = defineMessages({
44 }, 44 },
45}); 45});
46 46
47const styles = theme => ({ 47const styles = (theme) => ({
48 appContent: { 48 appContent: {
49 // width: `calc(100% + ${theme.workspaces.drawer.width}px)`, 49 // width: `calc(100% + ${theme.workspaces.drawer.width}px)`,
50 width: '100%', 50 width: '100%',
@@ -124,7 +124,7 @@ class AppLayout extends Component {
124 {sidebar} 124 {sidebar}
125 <div className="app__service"> 125 <div className="app__service">
126 <WorkspaceSwitchingIndicator /> 126 <WorkspaceSwitchingIndicator />
127 {news.length > 0 && news.map(item => ( 127 {news.length > 0 && news.map((item) => (
128 <InfoBar 128 <InfoBar
129 key={item.id} 129 key={item.id}
130 position="top" 130 position="top"
diff --git a/src/components/services/content/ConnectionLostBanner.js b/src/components/services/content/ConnectionLostBanner.js
index e54a88faa..0b9d3122c 100644
--- a/src/components/services/content/ConnectionLostBanner.js
+++ b/src/components/services/content/ConnectionLostBanner.js
@@ -26,7 +26,7 @@ const messages = defineMessages({
26 }, 26 },
27}); 27});
28 28
29const styles = theme => ({ 29const styles = (theme) => ({
30 root: { 30 root: {
31 background: theme.colorBackground, 31 background: theme.colorBackground,
32 borderRadius: theme.borderRadius, 32 borderRadius: theme.borderRadius,
diff --git a/src/components/services/content/ErrorHandlers/styles.js b/src/components/services/content/ErrorHandlers/styles.js
index 9e2509ee5..72d62f5e3 100644
--- a/src/components/services/content/ErrorHandlers/styles.js
+++ b/src/components/services/content/ErrorHandlers/styles.js
@@ -1,4 +1,4 @@
1export default theme => ({ 1export default (theme) => ({
2 component: { 2 component: {
3 left: 0, 3 left: 0,
4 position: 'absolute', 4 position: 'absolute',
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js
index 6e46a60d2..fbf884f0a 100644
--- a/src/components/services/content/Services.js
+++ b/src/components/services/content/Services.js
@@ -167,7 +167,7 @@ export default @injectSheet(styles) @inject('actions') @observer class Services
167 </div> 167 </div>
168 </Appear> 168 </Appear>
169 )} 169 )}
170 {services.filter(service => !service.isTodosService).map(service => ( 170 {services.filter((service) => !service.isTodosService).map((service) => (
171 <ServiceView 171 <ServiceView
172 key={service.id} 172 key={service.id}
173 service={service} 173 service={service}
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js
index b62940c06..10ff0bbbb 100644
--- a/src/components/services/content/WebviewCrashHandler.js
+++ b/src/components/services/content/WebviewCrashHandler.js
@@ -47,7 +47,7 @@ export default @observer class WebviewCrashHandler extends Component {
47 const { reload } = this.props; 47 const { reload } = this.props;
48 48
49 this.countdownInterval = setInterval(() => { 49 this.countdownInterval = setInterval(() => {
50 this.setState(prevState => ({ 50 this.setState((prevState) => ({
51 countdown: prevState.countdown - this.countdownIntervalTimeout, 51 countdown: prevState.countdown - this.countdownIntervalTimeout,
52 })); 52 }));
53 53
diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js
index db7a69bfc..0f608c415 100644
--- a/src/components/services/tabs/Tabbar.js
+++ b/src/components/services/tabs/Tabbar.js
@@ -33,7 +33,7 @@ export default @observer class TabBar extends Component {
33 reorder({ oldIndex, newIndex }); 33 reorder({ oldIndex, newIndex });
34 }; 34 };
35 35
36 shouldPreventSorting = event => event.target.tagName !== 'LI'; 36 shouldPreventSorting = (event) => event.target.tagName !== 'LI';
37 37
38 toggleService = ({ serviceId, isEnabled }) => { 38 toggleService = ({ serviceId, isEnabled }) => {
39 const { updateService } = this.props; 39 const { updateService } = this.props;
@@ -95,10 +95,10 @@ export default @observer class TabBar extends Component {
95 toggleNotifications={toggleNotifications} 95 toggleNotifications={toggleNotifications}
96 toggleAudio={toggleAudio} 96 toggleAudio={toggleAudio}
97 deleteService={deleteService} 97 deleteService={deleteService}
98 disableService={args => this.disableService(args)} 98 disableService={(args) => this.disableService(args)}
99 enableService={args => this.enableService(args)} 99 enableService={(args) => this.enableService(args)}
100 hibernateService={args => this.hibernateService(args)} 100 hibernateService={(args) => this.hibernateService(args)}
101 wakeUpService={args => this.wakeUpService(args)} 101 wakeUpService={(args) => this.wakeUpService(args)}
102 openSettings={openSettings} 102 openSettings={openSettings}
103 distance={20} 103 distance={20}
104 axis="y" 104 axis="y"
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 56e5f9c94..5e424fdd5 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -266,7 +266,7 @@ export default @observer class EditServiceForm extends Component {
266 </span> 266 </span>
267 </div> 267 </div>
268 <div className="settings__body"> 268 <div className="settings__body">
269 <form onSubmit={e => this.submit(e)} id="form"> 269 <form onSubmit={(e) => this.submit(e)} id="form">
270 <div className="service-name"> 270 <div className="service-name">
271 <Input field={form.$('name')} focus /> 271 <Input field={form.$('name')} focus />
272 </div> 272 </div>
diff --git a/src/components/settings/services/ServicesDashboard.js b/src/components/settings/services/ServicesDashboard.js
index a05af5da0..11d3eaa79 100644
--- a/src/components/settings/services/ServicesDashboard.js
+++ b/src/components/settings/services/ServicesDashboard.js
@@ -96,7 +96,7 @@ export default @observer class ServicesDashboard extends Component {
96 {(services.length !== 0 || searchNeedle) && !isLoading && ( 96 {(services.length !== 0 || searchNeedle) && !isLoading && (
97 <SearchInput 97 <SearchInput
98 placeholder={intl.formatMessage(messages.searchService)} 98 placeholder={intl.formatMessage(messages.searchService)}
99 onChange={needle => filterServices({ needle })} 99 onChange={(needle) => filterServices({ needle })}
100 onReset={() => resetFilter()} 100 onReset={() => resetFilter()}
101 autoFocus 101 autoFocus
102 /> 102 />
@@ -163,7 +163,7 @@ export default @observer class ServicesDashboard extends Component {
163 ) : ( 163 ) : (
164 <table className="service-table"> 164 <table className="service-table">
165 <tbody> 165 <tbody>
166 {services.map(service => ( 166 {services.map((service) => (
167 <ServiceItem 167 <ServiceItem
168 key={service.id} 168 key={service.id}
169 service={service} 169 service={service}
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 7ac644446..339e2dff6 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -266,8 +266,8 @@ export default @observer class EditSettingsForm extends Component {
266 </div> 266 </div>
267 <div className="settings__body"> 267 <div className="settings__body">
268 <form 268 <form
269 onSubmit={e => this.submit(e)} 269 onSubmit={(e) => this.submit(e)}
270 onChange={e => this.submit(e)} 270 onChange={(e) => this.submit(e)}
271 id="form" 271 id="form"
272 > 272 >
273 {/* Titles */} 273 {/* Titles */}
@@ -367,7 +367,7 @@ export default @observer class EditSettingsForm extends Component {
367 <div> 367 <div>
368 <Input 368 <Input
369 placeholder="Todo Server" 369 placeholder="Todo Server"
370 onChange={e => this.submit(e)} 370 onChange={(e) => this.submit(e)}
371 field={form.$('customTodoServer')} 371 field={form.$('customTodoServer')}
372 /> 372 />
373 <p 373 <p
@@ -401,7 +401,7 @@ export default @observer class EditSettingsForm extends Component {
401 > 401 >
402 <Input 402 <Input
403 placeholder="17:00" 403 placeholder="17:00"
404 onChange={e => this.submit(e)} 404 onChange={(e) => this.submit(e)}
405 field={form.$('scheduledDNDStart')} 405 field={form.$('scheduledDNDStart')}
406 type="time" 406 type="time"
407 /> 407 />
@@ -413,7 +413,7 @@ export default @observer class EditSettingsForm extends Component {
413 > 413 >
414 <Input 414 <Input
415 placeholder="09:00" 415 placeholder="09:00"
416 onChange={e => this.submit(e)} 416 onChange={(e) => this.submit(e)}
417 field={form.$('scheduledDNDEnd')} 417 field={form.$('scheduledDNDEnd')}
418 type="time" 418 type="time"
419 /> 419 />
@@ -480,7 +480,7 @@ export default @observer class EditSettingsForm extends Component {
480 480
481 <Input 481 <Input
482 placeholder="Accent Color" 482 placeholder="Accent Color"
483 onChange={e => this.submit(e)} 483 onChange={(e) => this.submit(e)}
484 field={form.$('accentColor')} 484 field={form.$('accentColor')}
485 /> 485 />
486 <p> 486 <p>
@@ -515,7 +515,7 @@ export default @observer class EditSettingsForm extends Component {
515 515
516 <Input 516 <Input
517 placeholder={intl.formatMessage(messages.lockedPassword)} 517 placeholder={intl.formatMessage(messages.lockedPassword)}
518 onChange={e => this.submit(e)} 518 onChange={(e) => this.submit(e)}
519 field={form.$('lockedPassword')} 519 field={form.$('lockedPassword')}
520 type="password" 520 type="password"
521 scorePassword 521 scorePassword
@@ -527,7 +527,7 @@ export default @observer class EditSettingsForm extends Component {
527 527
528 <Input 528 <Input
529 placeholder="Lock after inactivity" 529 placeholder="Lock after inactivity"
530 onChange={e => this.submit(e)} 530 onChange={(e) => this.submit(e)}
531 field={form.$('inactivityLock')} 531 field={form.$('inactivityLock')}
532 autoFocus 532 autoFocus
533 /> 533 />
@@ -570,6 +570,7 @@ export default @observer class EditSettingsForm extends Component {
570 href={FRANZ_TRANSLATION} 570 href={FRANZ_TRANSLATION}
571 target="_blank" 571 target="_blank"
572 className="link" 572 className="link"
573 rel="noreferrer"
573 > 574 >
574 {intl.formatMessage(messages.translationHelp)} 575 {intl.formatMessage(messages.translationHelp)}
575 {' '} 576 {' '}
@@ -588,7 +589,7 @@ export default @observer class EditSettingsForm extends Component {
588 589
589 <Input 590 <Input
590 placeholder="User Agent" 591 placeholder="User Agent"
591 onChange={e => this.submit(e)} 592 onChange={(e) => this.submit(e)}
592 field={form.$('userAgentPref')} 593 field={form.$('userAgentPref')}
593 /> 594 />
594 <p className="settings__help">{intl.formatMessage(globalMessages.userAgentHelp)}</p> 595 <p className="settings__help">{intl.formatMessage(globalMessages.userAgentHelp)}</p>
@@ -674,12 +675,12 @@ export default @observer class EditSettingsForm extends Component {
674 675
675 Ferdi is based on 676 Ferdi is based on
676 {' '} 677 {' '}
677 <a href={`${GITHUB_FRANZ_URL}/franz`} target="_blank">Franz</a> 678 <a href={`${GITHUB_FRANZ_URL}/franz`} target="_blank" rel="noreferrer">Franz</a>
678 679
679 , a project published 680 , a project published
680 under the 681 under the
681 {' '} 682 {' '}
682 <a href={`${GITHUB_FRANZ_URL}/franz/blob/master/LICENSE`} target="_blank">Apache-2.0 License</a> 683 <a href={`${GITHUB_FRANZ_URL}/franz/blob/master/LICENSE`} target="_blank" rel="noreferrer">Apache-2.0 License</a>
683 </span> 684 </span>
684 <br /> 685 <br />
685 <span className="mdi mdi-information" /> 686 <span className="mdi mdi-information" />
diff --git a/src/components/settings/supportFerdi/SupportFerdiDashboard.js b/src/components/settings/supportFerdi/SupportFerdiDashboard.js
index 36c126565..b84e06739 100644
--- a/src/components/settings/supportFerdi/SupportFerdiDashboard.js
+++ b/src/components/settings/supportFerdi/SupportFerdiDashboard.js
@@ -94,10 +94,10 @@ class SupportFerdiDashboard extends Component {
94 <h1>{intl.formatMessage(messages.title)}</h1> 94 <h1>{intl.formatMessage(messages.title)}</h1>
95 <div> 95 <div>
96 <p className="settings__support-badges"> 96 <p className="settings__support-badges">
97 <a href="https://github.com/getferdi/ferdi" target="_blank"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/getferdi/ferdi?style=social" /></a> 97 <a href="https://github.com/getferdi/ferdi" target="_blank" rel="noreferrer"><img alt="GitHub Stars" src="https://img.shields.io/github/stars/getferdi/ferdi?style=social" /></a>
98 <a href="https://twitter.com/getferdi/" target="_blank"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/getferdi?label=Follow&style=social" /></a> 98 <a href="https://twitter.com/getferdi/" target="_blank" rel="noreferrer"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/getferdi?label=Follow&style=social" /></a>
99 <a href="https://opencollective.com/getferdi#section-contributors" target="_blank"><img alt="Open Collective backers" src="https://img.shields.io/opencollective/backers/getferdi?logo=open-collective" /></a> 99 <a href="https://opencollective.com/getferdi#section-contributors" target="_blank" rel="noreferrer"><img alt="Open Collective backers" src="https://img.shields.io/opencollective/backers/getferdi?logo=open-collective" /></a>
100 <a href="https://opencollective.com/getferdi#section-contributors" target="_blank"><img alt="Open Collective sponsors" src="https://img.shields.io/opencollective/sponsors/getferdi?logo=open-collective" /></a> 100 <a href="https://opencollective.com/getferdi#section-contributors" target="_blank" rel="noreferrer"><img alt="Open Collective sponsors" src="https://img.shields.io/opencollective/sponsors/getferdi?logo=open-collective" /></a>
101 </p> 101 </p>
102 <FormattedHTMLMessage {...messages.aboutIntro} /> 102 <FormattedHTMLMessage {...messages.aboutIntro} />
103 <br /> 103 <br />
@@ -109,7 +109,7 @@ class SupportFerdiDashboard extends Component {
109 </p> 109 </p>
110 <p> 110 <p>
111 {intl.formatMessage(messages.textListContributors)} 111 {intl.formatMessage(messages.textListContributors)}
112 <a href="https://github.com/getferdi/ferdi#contributors-" target="_blank" className="link"> 112 <a href="https://github.com/getferdi/ferdi#contributors-" target="_blank" className="link" rel="noreferrer">
113 {' '} 113 {' '}
114 {intl.formatMessage(messages.textListContributorsHere)} 114 {intl.formatMessage(messages.textListContributorsHere)}
115 <i className="mdi mdi-open-in-new" /> 115 <i className="mdi mdi-open-in-new" />
@@ -122,7 +122,7 @@ class SupportFerdiDashboard extends Component {
122 </p> 122 </p>
123 <p> 123 <p>
124 {intl.formatMessage(messages.textSupportWelcome)} 124 {intl.formatMessage(messages.textSupportWelcome)}
125 <a href="https://help.getferdi.com/general/support" target="_blank" className="link"> 125 <a href="https://help.getferdi.com/general/support" target="_blank" className="link" rel="noreferrer">
126 {' '} 126 {' '}
127 {intl.formatMessage(messages.textSupportWelcomeHere)} 127 {intl.formatMessage(messages.textSupportWelcomeHere)}
128 <i className="mdi mdi-open-in-new" /> 128 <i className="mdi mdi-open-in-new" />
@@ -130,7 +130,7 @@ class SupportFerdiDashboard extends Component {
130 </p> 130 </p>
131 <p> 131 <p>
132 {intl.formatMessage(messages.textExpenses)} 132 {intl.formatMessage(messages.textExpenses)}
133 <a href="https://opencollective.com/getferdi#section-budget" target="_blank" className="link"> 133 <a href="https://opencollective.com/getferdi#section-budget" target="_blank" className="link" rel="noreferrer">
134 {' '} 134 {' '}
135 {intl.formatMessage(messages.textOpenCollective)} 135 {intl.formatMessage(messages.textOpenCollective)}
136 <i className="mdi mdi-open-in-new" /> 136 <i className="mdi mdi-open-in-new" />
@@ -138,14 +138,14 @@ class SupportFerdiDashboard extends Component {
138 </p> 138 </p>
139 <p> 139 <p>
140 {intl.formatMessage(messages.textDonation)} 140 {intl.formatMessage(messages.textDonation)}
141 <a href="https://opencollective.com/getferdi#section-contribute" target="_blank" className="link"> 141 <a href="https://opencollective.com/getferdi#section-contribute" target="_blank" className="link" rel="noreferrer">
142 {' '} 142 {' '}
143 {intl.formatMessage(messages.textOpenCollective)} 143 {intl.formatMessage(messages.textOpenCollective)}
144 <i className="mdi mdi-open-in-new" /> 144 <i className="mdi mdi-open-in-new" />
145 </a> 145 </a>
146 {' '} 146 {' '}
147 {intl.formatMessage(messages.textDonationAnd)} 147 {intl.formatMessage(messages.textDonationAnd)}
148 <a href="https://github.com/sponsors/getferdi" target="_blank" className="link"> 148 <a href="https://github.com/sponsors/getferdi" target="_blank" className="link" rel="noreferrer">
149 {' '} 149 {' '}
150 {intl.formatMessage(messages.textGitHubSponsors)} 150 {intl.formatMessage(messages.textGitHubSponsors)}
151 <i className="mdi mdi-open-in-new" /> 151 <i className="mdi mdi-open-in-new" />
diff --git a/src/components/settings/user/EditUserForm.js b/src/components/settings/user/EditUserForm.js
index a1a353e57..db78acb69 100644
--- a/src/components/settings/user/EditUserForm.js
+++ b/src/components/settings/user/EditUserForm.js
@@ -84,7 +84,7 @@ export default @observer class EditUserForm extends Component {
84 </span> 84 </span>
85 </div> 85 </div>
86 <div className="settings__body"> 86 <div className="settings__body">
87 <form onSubmit={e => this.submit(e)} id="form"> 87 <form onSubmit={(e) => this.submit(e)} id="form">
88 {status.length > 0 && status.includes('data-updated') && ( 88 {status.length > 0 && status.includes('data-updated') && (
89 <Infobox 89 <Infobox
90 type="success" 90 type="success"
diff --git a/src/components/ui/AppLoader/index.js b/src/components/ui/AppLoader/index.js
index a7f6f4545..31d7ca249 100644
--- a/src/components/ui/AppLoader/index.js
+++ b/src/components/ui/AppLoader/index.js
@@ -37,7 +37,7 @@ export default @injectSheet(styles) @withTheme class AppLoader extends Component
37 37
38 componentDidMount() { 38 componentDidMount() {
39 this.interval = setInterval(() => { 39 this.interval = setInterval(() => {
40 this.setState(prevState => ({ 40 this.setState((prevState) => ({
41 step: prevState.step === textList.length - 1 ? 0 : prevState.step + 1, 41 step: prevState.step === textList.length - 1 ? 0 : prevState.step + 1,
42 })); 42 }));
43 }, 2500); 43 }, 2500);
diff --git a/src/components/ui/FeatureItem.js b/src/components/ui/FeatureItem.js
index 4926df470..646cf56ca 100644
--- a/src/components/ui/FeatureItem.js
+++ b/src/components/ui/FeatureItem.js
@@ -4,7 +4,7 @@ import { Icon } from '@meetfranz/ui';
4import classnames from 'classnames'; 4import classnames from 'classnames';
5import { mdiCheckCircle } from '@mdi/js'; 5import { mdiCheckCircle } from '@mdi/js';
6 6
7const styles = theme => ({ 7const styles = (theme) => ({
8 featureItem: { 8 featureItem: {
9 borderBottom: [1, 'solid', theme.defaultContentBorder], 9 borderBottom: [1, 'solid', theme.defaultContentBorder],
10 padding: [8, 0], 10 padding: [8, 0],
diff --git a/src/components/ui/FeatureList.js b/src/components/ui/FeatureList.js
index ada15244b..cf2664830 100644
--- a/src/components/ui/FeatureList.js
+++ b/src/components/ui/FeatureList.js
@@ -92,7 +92,7 @@ export class FeatureList extends Component {
92 92
93 return ( 93 return (
94 <ul className={className}> 94 <ul className={className}>
95 {features.map(feature => <FeatureItem name={intl.formatMessage(feature)} className={featureClassName} />)} 95 {features.map((feature) => <FeatureItem name={intl.formatMessage(feature)} className={featureClassName} />)}
96 </ul> 96 </ul>
97 ); 97 );
98 } 98 }
diff --git a/src/components/ui/Link.js b/src/components/ui/Link.js
index 7930d98b4..fd14b7018 100644
--- a/src/components/ui/Link.js
+++ b/src/components/ui/Link.js
@@ -48,7 +48,7 @@ export default @inject('stores') @observer class Link extends Component {
48 href={router.history.createHref(to)} 48 href={router.history.createHref(to)}
49 className={linkClasses} 49 className={linkClasses}
50 style={style} 50 style={style}
51 onClick={e => this.onClick(e)} 51 onClick={(e) => this.onClick(e)}
52 > 52 >
53 {children} 53 {children}
54 </a> 54 </a>
diff --git a/src/components/ui/Modal/styles.js b/src/components/ui/Modal/styles.js
index c2bebf9bb..f32c075ce 100644
--- a/src/components/ui/Modal/styles.js
+++ b/src/components/ui/Modal/styles.js
@@ -1,4 +1,4 @@
1export default theme => ({ 1export default (theme) => ({
2 component: { 2 component: {
3 zIndex: 500, 3 zIndex: 500,
4 position: 'absolute', 4 position: 'absolute',
diff --git a/src/components/ui/Radio.js b/src/components/ui/Radio.js
index ba13aca63..e77714eb7 100644
--- a/src/components/ui/Radio.js
+++ b/src/components/ui/Radio.js
@@ -54,7 +54,7 @@ export default @observer class Radio extends Component {
54 </label> 54 </label>
55 )} 55 )}
56 <div className="franz-form__radio-wrapper"> 56 <div className="franz-form__radio-wrapper">
57 {field.options.map(type => ( 57 {field.options.map((type) => (
58 <label 58 <label
59 key={type.value} 59 key={type.value}
60 htmlFor={`${field.id}-${type.value}`} 60 htmlFor={`${field.id}-${type.value}`}
diff --git a/src/components/ui/SearchInput.js b/src/components/ui/SearchInput.js
index 78d6aae8b..0b25734dd 100644
--- a/src/components/ui/SearchInput.js
+++ b/src/components/ui/SearchInput.js
@@ -96,7 +96,7 @@ export default @observer class SearchInput extends Component {
96 type="text" 96 type="text"
97 placeholder={placeholder} 97 placeholder={placeholder}
98 value={value} 98 value={value}
99 onChange={e => this.onChange(e)} 99 onChange={(e) => this.onChange(e)}
100 ref={(ref) => { this.input = ref; }} 100 ref={(ref) => { this.input = ref; }}
101 /> 101 />
102 </label> 102 </label>
diff --git a/src/components/ui/Select.js b/src/components/ui/Select.js
index b4511433c..e7a5eafa8 100644
--- a/src/components/ui/Select.js
+++ b/src/components/ui/Select.js
@@ -82,7 +82,7 @@ export default @observer class Select extends Component {
82 </label> 82 </label>
83 )} 83 )}
84 <select 84 <select
85 onChange={multiple ? e => this.multipleChange(e) : field.onChange} 85 onChange={multiple ? (e) => this.multipleChange(e) : field.onChange}
86 id={field.id} 86 id={field.id}
87 defaultValue={selected} 87 defaultValue={selected}
88 className="franz-form__select" 88 className="franz-form__select"
@@ -90,7 +90,7 @@ export default @observer class Select extends Component {
90 multiple={multiple} 90 multiple={multiple}
91 ref={this.element} 91 ref={this.element}
92 > 92 >
93 {field.options.map(type => ( 93 {field.options.map((type) => (
94 <option 94 <option
95 key={type.value} 95 key={type.value}
96 value={type.value} 96 value={type.value}
diff --git a/src/components/ui/ServiceIcon.js b/src/components/ui/ServiceIcon.js
index 0b9155a4e..b2dadeac3 100644
--- a/src/components/ui/ServiceIcon.js
+++ b/src/components/ui/ServiceIcon.js
@@ -6,7 +6,7 @@ import classnames from 'classnames';
6 6
7import ServiceModel from '../../models/Service'; 7import ServiceModel from '../../models/Service';
8 8
9const styles = theme => ({ 9const styles = (theme) => ({
10 root: { 10 root: {
11 height: 'auto', 11 height: 'auto',
12 }, 12 },
diff --git a/src/components/ui/Slider.js b/src/components/ui/Slider.js
index b00a6a3f8..f344449a0 100644
--- a/src/components/ui/Slider.js
+++ b/src/components/ui/Slider.js
@@ -53,7 +53,7 @@ export default @observer class Slider extends Component {
53 value={field.value} 53 value={field.value}
54 min="1" 54 min="1"
55 max="100" 55 max="100"
56 onChange={e => (!disabled ? this.onChange(e) : null)} 56 onChange={(e) => (!disabled ? this.onChange(e) : null)}
57 /> 57 />
58 </div> 58 </div>
59 59
diff --git a/src/components/ui/Tabs/TabItem.js b/src/components/ui/Tabs/TabItem.js
index 546b05a4e..d0ef4e798 100644
--- a/src/components/ui/Tabs/TabItem.js
+++ b/src/components/ui/Tabs/TabItem.js
@@ -1,17 +1,15 @@
1import React, { Component, Fragment } from 'react'; 1import React, { Component } from 'react';
2 2
3import { oneOrManyChildElements } from '../../../prop-types'; 3import { oneOrManyChildElements } from '../../../prop-types';
4 4
5export default class TabItem extends Component { 5export default class TabItem extends Component {
6 static propTypes = { 6 static propTypes = {
7 children: oneOrManyChildElements.isRequired, 7 children: oneOrManyChildElements.isRequired,
8 } 8 };
9 9
10 render() { 10 render() {
11 const { children } = this.props; 11 const { children } = this.props;
12 12
13 return ( 13 return <>{children}</>;
14 <>{children}</>
15 );
16 } 14 }
17} 15}
diff --git a/src/components/ui/Tabs/Tabs.js b/src/components/ui/Tabs/Tabs.js
index e68dc3a1d..56c76f215 100644
--- a/src/components/ui/Tabs/Tabs.js
+++ b/src/components/ui/Tabs/Tabs.js
@@ -28,7 +28,7 @@ class Tab extends Component {
28 28
29 render() { 29 render() {
30 const { children: childElements } = this.props; 30 const { children: childElements } = this.props;
31 const children = childElements.filter(c => !!c); 31 const children = childElements.filter((c) => !!c);
32 32
33 if (children.length === 1) { 33 if (children.length === 1) {
34 return <div>{children}</div>; 34 return <div>{children}</div>;
diff --git a/src/components/ui/Toggle.js b/src/components/ui/Toggle.js
index 78fb77cbe..14330e5c7 100644
--- a/src/components/ui/Toggle.js
+++ b/src/components/ui/Toggle.js
@@ -59,7 +59,7 @@ export default @observer class Toggle extends Component {
59 name={field.name} 59 name={field.name}
60 value={field.name} 60 value={field.name}
61 checked={field.value} 61 checked={field.value}
62 onChange={e => (!disabled ? this.onChange(e) : null)} 62 onChange={(e) => (!disabled ? this.onChange(e) : null)}
63 /> 63 />
64 </label> 64 </label>
65 {field.error && <div className={field.error}>{field.error}</div>} 65 {field.error && <div className={field.error}>{field.error}</div>}
diff --git a/src/components/ui/ToggleRaw.js b/src/components/ui/ToggleRaw.js
index dcaf664e1..4700127d4 100644
--- a/src/components/ui/ToggleRaw.js
+++ b/src/components/ui/ToggleRaw.js
@@ -64,7 +64,7 @@ export default @observer class ToggleRaw extends Component {
64 name={field.name} 64 name={field.name}
65 value={field.name} 65 value={field.name}
66 checked={field.value} 66 checked={field.value}
67 onChange={e => (!disabled ? this.onChange(e) : null)} 67 onChange={(e) => (!disabled ? this.onChange(e) : null)}
68 /> 68 />
69 </label> 69 </label>
70 {field.error && <div className={field.error}>{field.error}</div>} 70 {field.error && <div className={field.error}>{field.error}</div>}
diff --git a/src/components/ui/WebviewLoader/styles.js b/src/components/ui/WebviewLoader/styles.js
index dbd75db8a..5d58011fe 100644
--- a/src/components/ui/WebviewLoader/styles.js
+++ b/src/components/ui/WebviewLoader/styles.js
@@ -1,4 +1,4 @@
1export default theme => ({ 1export default (theme) => ({
2 component: { 2 component: {
3 background: theme.colorWebviewLoaderBackground, 3 background: theme.colorWebviewLoaderBackground,
4 padding: 20, 4 padding: 20,
diff --git a/src/components/util/ErrorBoundary/styles.js b/src/components/util/ErrorBoundary/styles.js
index 0960546ff..51b36fdf3 100644
--- a/src/components/util/ErrorBoundary/styles.js
+++ b/src/components/util/ErrorBoundary/styles.js
@@ -1,4 +1,4 @@
1export default theme => ({ 1export default (theme) => ({
2 component: { 2 component: {
3 display: 'flex', 3 display: 'flex',
4 width: '100%', 4 width: '100%',
diff --git a/src/containers/auth/SetupAssistantScreen.js b/src/containers/auth/SetupAssistantScreen.js
index eaf3fda8a..d14085f63 100644
--- a/src/containers/auth/SetupAssistantScreen.js
+++ b/src/containers/auth/SetupAssistantScreen.js
@@ -102,7 +102,7 @@ export default @inject('stores', 'actions') @observer class SetupAssistantScreen
102 render() { 102 render() {
103 return ( 103 return (
104 <SetupAssistant 104 <SetupAssistant
105 onSubmit={config => this.setupServices(config)} 105 onSubmit={(config) => this.setupServices(config)}
106 services={this.services} 106 services={this.services}
107 embed={false} 107 embed={false}
108 isSettingUpServices={this.state.isSettingUpServices} 108 isSettingUpServices={this.state.isSettingUpServices}
diff --git a/src/containers/auth/SignupScreen.js b/src/containers/auth/SignupScreen.js
index eeab63a0c..38c5dfb43 100644
--- a/src/containers/auth/SignupScreen.js
+++ b/src/containers/auth/SignupScreen.js
@@ -24,7 +24,7 @@ export default @inject('stores', 'actions') @observer class SignupScreen extends
24 24
25 return ( 25 return (
26 <Signup 26 <Signup
27 onSubmit={values => this.onSignup(values)} 27 onSubmit={(values) => this.onSignup(values)}
28 isSubmitting={stores.user.signupRequest.isExecuting} 28 isSubmitting={stores.user.signupRequest.isExecuting}
29 loginRoute={stores.user.loginRoute} 29 loginRoute={stores.user.loginRoute}
30 changeServerRoute={stores.user.changeServerRoute} 30 changeServerRoute={stores.user.changeServerRoute}
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 21be9d9d1..fff628946 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -92,8 +92,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
92 92
93 const workspacesDrawer = ( 93 const workspacesDrawer = (
94 <WorkspaceDrawer 94 <WorkspaceDrawer
95 getServicesForWorkspace={workspace => ( 95 getServicesForWorkspace={(workspace) => (
96 workspace ? workspaceStore.getWorkspaceServices(workspace).map(s => s.name) : services.all.map(s => s.name) 96 workspace ? workspaceStore.getWorkspaceServices(workspace).map((s) => s.name) : services.all.map((s) => s.name)
97 )} 97 )}
98 /> 98 />
99 ); 99 );
diff --git a/src/containers/settings/AccountScreen.js b/src/containers/settings/AccountScreen.js
index 4ee932895..8d92b01be 100644
--- a/src/containers/settings/AccountScreen.js
+++ b/src/containers/settings/AccountScreen.js
@@ -46,10 +46,7 @@ class AccountScreen extends Component {
46 } 46 }
47 47
48 render() { 48 render() {
49 const { 49 const { user, settings } = this.props.stores;
50 user,
51 settings,
52 } = this.props.stores;
53 const { user: userActions } = this.props.actions; 50 const { user: userActions } = this.props.actions;
54 51
55 const isLoadingUserInfo = user.getUserInfoRequest.isExecuting; 52 const isLoadingUserInfo = user.getUserInfoRequest.isExecuting;
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js
index 0fe84792f..c880e97ae 100644
--- a/src/containers/settings/EditServiceScreen.js
+++ b/src/containers/settings/EditServiceScreen.js
@@ -394,9 +394,9 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
394 status={services.actionStatus} 394 status={services.actionStatus}
395 isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting} 395 isSaving={services.updateServiceRequest.isExecuting || services.createServiceRequest.isExecuting}
396 isDeleting={services.deleteServiceRequest.isExecuting} 396 isDeleting={services.deleteServiceRequest.isExecuting}
397 onSubmit={d => this.onSubmit(d)} 397 onSubmit={(d) => this.onSubmit(d)}
398 onDelete={() => this.deleteService()} 398 onDelete={() => this.deleteService()}
399 openRecipeFile={file => this.openRecipeFile(file)} 399 openRecipeFile={(file) => this.openRecipeFile(file)}
400 isProxyFeatureEnabled={proxyFeature.isEnabled} 400 isProxyFeatureEnabled={proxyFeature.isEnabled}
401 /> 401 />
402 </ErrorBoundary> 402 </ErrorBoundary>
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index 764078cb8..e0a648095 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -652,7 +652,7 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
652 isUpdateAvailable={updateStatus === updateStatusTypes.AVAILABLE} 652 isUpdateAvailable={updateStatus === updateStatusTypes.AVAILABLE}
653 noUpdateAvailable={updateStatus === updateStatusTypes.NOT_AVAILABLE} 653 noUpdateAvailable={updateStatus === updateStatusTypes.NOT_AVAILABLE}
654 updateIsReadyToInstall={updateStatus === updateStatusTypes.DOWNLOADED} 654 updateIsReadyToInstall={updateStatus === updateStatusTypes.DOWNLOADED}
655 onSubmit={d => this.onSubmit(d)} 655 onSubmit={(d) => this.onSubmit(d)}
656 getCacheSize={() => app.cacheSize} 656 getCacheSize={() => app.cacheSize}
657 isClearingAllCache={isClearingAllCache} 657 isClearingAllCache={isClearingAllCache}
658 onClearAllCache={clearAllCache} 658 onClearAllCache={clearAllCache}
diff --git a/src/containers/settings/EditUserScreen.js b/src/containers/settings/EditUserScreen.js
index 8e93164de..820b5e4d3 100644
--- a/src/containers/settings/EditUserScreen.js
+++ b/src/containers/settings/EditUserScreen.js
@@ -141,7 +141,7 @@ export default @inject('stores', 'actions') @observer class EditUserScreen exten
141 status={user.actionStatus} 141 status={user.actionStatus}
142 form={form} 142 form={form}
143 isSaving={user.updateUserInfoRequest.isExecuting} 143 isSaving={user.updateUserInfoRequest.isExecuting}
144 onSubmit={d => this.onSubmit(d)} 144 onSubmit={(d) => this.onSubmit(d)}
145 /> 145 />
146 </ErrorBoundary> 146 </ErrorBoundary>
147 ); 147 );
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js
index 9a16fd064..0d6506705 100644
--- a/src/containers/settings/RecipesScreen.js
+++ b/src/containers/settings/RecipesScreen.js
@@ -82,7 +82,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
82 return recipes 82 return recipes
83 // Filter out duplicate recipes 83 // Filter out duplicate recipes
84 .filter((recipe, index, self) => { 84 .filter((recipe, index, self) => {
85 const ids = self.map(rec => rec.id); 85 const ids = self.map((rec) => rec.id);
86 return ids.indexOf(recipe.id) === index; 86 return ids.indexOf(recipe.id) === index;
87 87
88 // Sort alphabetically 88 // Sort alphabetically
@@ -95,7 +95,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
95 95
96 // Create an array of RecipePreviews from an array of recipe objects 96 // Create an array of RecipePreviews from an array of recipe objects
97 createPreviews(recipes) { 97 createPreviews(recipes) {
98 return recipes.map(recipe => new RecipePreview(recipe)); 98 return recipes.map((recipe) => new RecipePreview(recipe));
99 } 99 }
100 100
101 resetSearch() { 101 resetSearch() {
@@ -134,11 +134,11 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
134 // All search recipes from local recipes 134 // All search recipes from local recipes
135 ...this.createPreviews( 135 ...this.createPreviews(
136 this.customRecipes 136 this.customRecipes
137 .filter(service => service.name.toLowerCase().includes(this.state.needle.toLowerCase())), 137 .filter((service) => service.name.toLowerCase().includes(this.state.needle.toLowerCase())),
138 ), 138 ),
139 ]) : recipeFilter; 139 ]) : recipeFilter;
140 140
141 const customWebsiteRecipe = recipePreviews.all.find(service => service.id === CUSTOM_WEBSITE_RECIPE_ID); 141 const customWebsiteRecipe = recipePreviews.all.find((service) => service.id === CUSTOM_WEBSITE_RECIPE_ID);
142 142
143 const isLoading = recipePreviews.featuredRecipePreviewsRequest.isExecuting 143 const isLoading = recipePreviews.featuredRecipePreviewsRequest.isExecuting
144 || recipePreviews.allRecipePreviewsRequest.isExecuting 144 || recipePreviews.allRecipePreviewsRequest.isExecuting
@@ -156,7 +156,7 @@ export default @inject('stores', 'actions') @observer class RecipesScreen extend
156 addedServiceCount={services.all.length} 156 addedServiceCount={services.all.length}
157 hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted} 157 hasLoadedRecipes={recipePreviews.featuredRecipePreviewsRequest.wasExecuted}
158 showAddServiceInterface={serviceActions.showAddServiceInterface} 158 showAddServiceInterface={serviceActions.showAddServiceInterface}
159 searchRecipes={e => this.searchRecipes(e)} 159 searchRecipes={(e) => this.searchRecipes(e)}
160 resetSearch={() => this.resetSearch()} 160 resetSearch={() => this.resetSearch()}
161 searchNeedle={this.state.needle} 161 searchNeedle={this.state.needle}
162 serviceStatus={services.actionStatus} 162 serviceStatus={services.actionStatus}
diff --git a/src/features/announcements/components/AnnouncementScreen.js b/src/features/announcements/components/AnnouncementScreen.js
index 21964b108..315843db3 100644
--- a/src/features/announcements/components/AnnouncementScreen.js
+++ b/src/features/announcements/components/AnnouncementScreen.js
@@ -25,7 +25,7 @@ const messages = defineMessages({
25 25
26const smallScreen = '1000px'; 26const smallScreen = '1000px';
27 27
28const styles = theme => ({ 28const styles = (theme) => ({
29 container: { 29 container: {
30 background: theme.colorBackground, 30 background: theme.colorBackground,
31 position: 'relative', 31 position: 'relative',
diff --git a/src/features/communityRecipes/store.js b/src/features/communityRecipes/store.js
index acc1e52f6..b115a53e1 100644
--- a/src/features/communityRecipes/store.js
+++ b/src/features/communityRecipes/store.js
@@ -19,7 +19,7 @@ export class CommunityRecipesStore extends FeatureStore {
19 if (!this.stores) return []; 19 if (!this.stores) return [];
20 20
21 return this.stores.recipePreviews.dev.map((r) => { 21 return this.stores.recipePreviews.dev.map((r) => {
22 r.isDevRecipe = !!r.author.find(a => a.email === this.stores.user.data.email); 22 r.isDevRecipe = !!r.author.find((a) => a.email === this.stores.user.data.email);
23 23
24 return r; 24 return r;
25 }); 25 });
diff --git a/src/features/publishDebugInfo/Component.js b/src/features/publishDebugInfo/Component.js
index f97a7c750..5387bd358 100644
--- a/src/features/publishDebugInfo/Component.js
+++ b/src/features/publishDebugInfo/Component.js
@@ -46,7 +46,7 @@ const messages = defineMessages({
46 }, 46 },
47}); 47});
48 48
49const styles = theme => ({ 49const styles = (theme) => ({
50 container: { 50 container: {
51 minWidth: '70vw', 51 minWidth: '70vw',
52 }, 52 },
@@ -186,10 +186,10 @@ export default @injectSheet(styles) @inject('stores', 'actions') @observer class
186 <> 186 <>
187 <p className={classes.info}>{intl.formatMessage(messages.info)}</p> 187 <p className={classes.info}>{intl.formatMessage(messages.info)}</p>
188 188
189 <a href={`${DEBUG_API}/privacy.html`} target="_blank" className={classes.link}> 189 <a href={`${DEBUG_API}/privacy.html`} target="_blank" className={classes.link} rel="noreferrer">
190 {intl.formatMessage(messages.privacy)} 190 {intl.formatMessage(messages.privacy)}
191 </a> 191 </a>
192 <a href={`${DEBUG_API}/terms.html`} target="_blank" className={classes.link}> 192 <a href={`${DEBUG_API}/terms.html`} target="_blank" className={classes.link} rel="noreferrer">
193 {intl.formatMessage(messages.terms)} 193 {intl.formatMessage(messages.terms)}
194 </a> 194 </a>
195 195
diff --git a/src/features/quickSwitch/Component.js b/src/features/quickSwitch/Component.js
index 04822db71..812f2c04b 100644
--- a/src/features/quickSwitch/Component.js
+++ b/src/features/quickSwitch/Component.js
@@ -28,7 +28,7 @@ const messages = defineMessages({
28 }, 28 },
29}); 29});
30 30
31const styles = theme => ({ 31const styles = (theme) => ({
32 modal: { 32 modal: {
33 width: '80%', 33 width: '80%',
34 maxWidth: 600, 34 maxWidth: 600,
@@ -139,7 +139,7 @@ export default @injectSheet(styles) @inject('stores', 'actions') @observer class
139 if (this.state.search && compact(invoke(this.state.search, 'match', /^[a-z0-9]/i)).length > 0) { 139 if (this.state.search && compact(invoke(this.state.search, 'match', /^[a-z0-9]/i)).length > 0) {
140 // Apply simple search algorythm to list of all services 140 // Apply simple search algorythm to list of all services
141 services = this.props.stores.services.allDisplayed; 141 services = this.props.stores.services.allDisplayed;
142 services = services.filter(service => service.name.toLowerCase().search(this.state.search.toLowerCase()) !== -1); 142 services = services.filter((service) => service.name.toLowerCase().search(this.state.search.toLowerCase()) !== -1);
143 } else { 143 } else {
144 // Add the currently active service first 144 // Add the currently active service first
145 const currentService = this.props.stores.services.active; 145 const currentService = this.props.stores.services.active;
diff --git a/src/features/shareFranz/Component.js b/src/features/shareFranz/Component.js
index b66375453..cc2e81b70 100644
--- a/src/features/shareFranz/Component.js
+++ b/src/features/shareFranz/Component.js
@@ -44,7 +44,7 @@ const messages = defineMessages({
44 }, 44 },
45}); 45});
46 46
47const styles = theme => ({ 47const styles = (theme) => ({
48 modal: { 48 modal: {
49 width: '80%', 49 width: '80%',
50 maxWidth: 600, 50 maxWidth: 600,
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js
index 6425746e6..d05e24e56 100644
--- a/src/features/todos/containers/TodosScreen.js
+++ b/src/features/todos/containers/TodosScreen.js
@@ -24,10 +24,10 @@ class TodosScreen extends Component {
24 isVisible={todosStore.isTodosPanelVisible} 24 isVisible={todosStore.isTodosPanelVisible}
25 togglePanel={todoActions.toggleTodosPanel} 25 togglePanel={todoActions.toggleTodosPanel}
26 handleClientMessage={todoActions.handleClientMessage} 26 handleClientMessage={todoActions.handleClientMessage}
27 setTodosWebview={webview => todoActions.setTodosWebview({ webview })} 27 setTodosWebview={(webview) => todoActions.setTodosWebview({ webview })}
28 width={todosStore.width} 28 width={todosStore.width}
29 minWidth={TODOS_MIN_WIDTH} 29 minWidth={TODOS_MIN_WIDTH}
30 resize={width => todoActions.resize({ width })} 30 resize={(width) => todoActions.resize({ width })}
31 userAgent={todosStore.userAgent} 31 userAgent={todosStore.userAgent}
32 todoUrl={todosStore.todoUrl} 32 todoUrl={todosStore.todoUrl}
33 isTodoUrlValid={todosStore.isTodoUrlValid} 33 isTodoUrlValid={todosStore.isTodoUrlValid}
diff --git a/src/features/utils/ActionBinding.js b/src/features/utils/ActionBinding.js
index 497aa071b..787166d44 100644
--- a/src/features/utils/ActionBinding.js
+++ b/src/features/utils/ActionBinding.js
@@ -24,6 +24,6 @@ export default class ActionBinding {
24 } 24 }
25} 25}
26 26
27export const createActionBindings = actions => ( 27export const createActionBindings = (actions) => (
28 actions.map(a => new ActionBinding(a)) 28 actions.map((a) => new ActionBinding(a))
29); 29);
diff --git a/src/features/utils/FeatureStore.js b/src/features/utils/FeatureStore.js
index 0bc10e176..4d4e217a9 100644
--- a/src/features/utils/FeatureStore.js
+++ b/src/features/utils/FeatureStore.js
@@ -16,11 +16,11 @@ export class FeatureStore {
16 } 16 }
17 17
18 _startActions(actions = this._actions) { 18 _startActions(actions = this._actions) {
19 actions.forEach(a => a.start()); 19 actions.forEach((a) => a.start());
20 } 20 }
21 21
22 _stopActions(actions = this._actions) { 22 _stopActions(actions = this._actions) {
23 actions.forEach(a => a.stop()); 23 actions.forEach((a) => a.stop());
24 } 24 }
25 25
26 // REACTIONS 26 // REACTIONS
@@ -31,10 +31,10 @@ export class FeatureStore {
31 } 31 }
32 32
33 _startReactions(reactions = this._reactions) { 33 _startReactions(reactions = this._reactions) {
34 reactions.forEach(r => r.start()); 34 reactions.forEach((r) => r.start());
35 } 35 }
36 36
37 _stopReactions(reactions = this._reactions) { 37 _stopReactions(reactions = this._reactions) {
38 reactions.forEach(r => r.stop()); 38 reactions.forEach((r) => r.stop());
39 } 39 }
40} 40}
diff --git a/src/features/webControls/components/WebControls.js b/src/features/webControls/components/WebControls.js
index b9403bd0d..1cdd14e55 100644
--- a/src/features/webControls/components/WebControls.js
+++ b/src/features/webControls/components/WebControls.js
@@ -32,7 +32,7 @@ const messages = defineMessages({
32 }, 32 },
33}); 33});
34 34
35const styles = theme => ({ 35const styles = (theme) => ({
36 root: { 36 root: {
37 background: theme.colorBackground, 37 background: theme.colorBackground,
38 position: 'relative', 38 position: 'relative',
@@ -197,7 +197,7 @@ class WebControls extends Component {
197 <input 197 <input
198 value={editUrl ? inputUrl : url} 198 value={editUrl ? inputUrl : url}
199 className={classes.input} 199 className={classes.input}
200 onChange={event => this.setState({ 200 onChange={(event) => this.setState({
201 inputUrl: event.target.value, 201 inputUrl: event.target.value,
202 })} 202 })}
203 onFocus={(event) => { 203 onFocus={(event) => {
diff --git a/src/features/webControls/containers/WebControlsScreen.js b/src/features/webControls/containers/WebControlsScreen.js
index d638b831c..e1e1b9991 100644
--- a/src/features/webControls/containers/WebControlsScreen.js
+++ b/src/features/webControls/containers/WebControlsScreen.js
@@ -114,7 +114,7 @@ class WebControlsScreen extends Component {
114 goBack={() => this.goBack()} 114 goBack={() => this.goBack()}
115 canGoForward={this.canGoForward} 115 canGoForward={this.canGoForward}
116 goForward={() => this.goForward()} 116 goForward={() => this.goForward()}
117 navigate={url => this.navigate(url)} 117 navigate={(url) => this.navigate(url)}
118 url={this.url} 118 url={this.url}
119 /> 119 />
120 ); 120 );
diff --git a/src/features/workspaces/api.js b/src/features/workspaces/api.js
index 30fbd84be..322695ed2 100644
--- a/src/features/workspaces/api.js
+++ b/src/features/workspaces/api.js
@@ -14,7 +14,7 @@ export const workspaceApi = {
14 debug('getUserWorkspaces RESULT', result); 14 debug('getUserWorkspaces RESULT', result);
15 if (!result.ok) throw result; 15 if (!result.ok) throw result;
16 const workspaces = await result.json(); 16 const workspaces = await result.json();
17 return workspaces.map(data => new Workspace(data)); 17 return workspaces.map((data) => new Workspace(data));
18 }, 18 },
19 19
20 createWorkspace: async (name) => { 20 createWorkspace: async (name) => {
diff --git a/src/features/workspaces/components/WorkspaceDrawer.js b/src/features/workspaces/components/WorkspaceDrawer.js
index 3ddc9cf16..1138f23d7 100644
--- a/src/features/workspaces/components/WorkspaceDrawer.js
+++ b/src/features/workspaces/components/WorkspaceDrawer.js
@@ -34,7 +34,7 @@ const messages = defineMessages({
34 }, 34 },
35}); 35});
36 36
37const styles = theme => ({ 37const styles = (theme) => ({
38 drawer: { 38 drawer: {
39 background: theme.workspaces.drawer.background, 39 background: theme.workspaces.drawer.background,
40 width: `${theme.workspaces.drawer.width}px`, 40 width: `${theme.workspaces.drawer.width}px`,
diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js
index 2e58b70d6..a3fdf4f47 100644
--- a/src/features/workspaces/components/WorkspaceDrawerItem.js
+++ b/src/features/workspaces/components/WorkspaceDrawerItem.js
@@ -18,7 +18,7 @@ const messages = defineMessages({
18 }, 18 },
19}); 19});
20 20
21const styles = theme => ({ 21const styles = (theme) => ({
22 item: { 22 item: {
23 height: '67px', 23 height: '67px',
24 padding: `15px ${theme.workspaces.drawer.padding}px`, 24 padding: `15px ${theme.workspaces.drawer.padding}px`,
diff --git a/src/features/workspaces/components/WorkspaceItem.js b/src/features/workspaces/components/WorkspaceItem.js
index cc4b1a3ba..85fc02d51 100644
--- a/src/features/workspaces/components/WorkspaceItem.js
+++ b/src/features/workspaces/components/WorkspaceItem.js
@@ -6,7 +6,7 @@ import injectSheet from 'react-jss';
6 6
7import Workspace from '../models/Workspace'; 7import Workspace from '../models/Workspace';
8 8
9const styles = theme => ({ 9const styles = (theme) => ({
10 row: { 10 row: {
11 height: theme.workspaces.settings.listItems.height, 11 height: theme.workspaces.settings.listItems.height,
12 borderBottom: `1px solid ${theme.workspaces.settings.listItems.borderColor}`, 12 borderBottom: `1px solid ${theme.workspaces.settings.listItems.borderColor}`,
diff --git a/src/features/workspaces/components/WorkspaceServiceListItem.js b/src/features/workspaces/components/WorkspaceServiceListItem.js
index e05b21440..f6e2a2786 100644
--- a/src/features/workspaces/components/WorkspaceServiceListItem.js
+++ b/src/features/workspaces/components/WorkspaceServiceListItem.js
@@ -8,7 +8,7 @@ import { Toggle } from '@meetfranz/forms';
8import Service from '../../../models/Service'; 8import Service from '../../../models/Service';
9import ServiceIcon from '../../../components/ui/ServiceIcon'; 9import ServiceIcon from '../../../components/ui/ServiceIcon';
10 10
11const styles = theme => ({ 11const styles = (theme) => ({
12 listItem: { 12 listItem: {
13 height: theme.workspaces.settings.listItems.height, 13 height: theme.workspaces.settings.listItems.height,
14 borderBottom: `1px solid ${theme.workspaces.settings.listItems.borderColor}`, 14 borderBottom: `1px solid ${theme.workspaces.settings.listItems.borderColor}`,
diff --git a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
index a70d1d66f..b46959e91 100644
--- a/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
+++ b/src/features/workspaces/components/WorkspaceSwitchingIndicator.js
@@ -15,7 +15,7 @@ const messages = defineMessages({
15 }, 15 },
16}); 16});
17 17
18const styles = theme => ({ 18const styles = (theme) => ({
19 wrapper: { 19 wrapper: {
20 display: 'flex', 20 display: 'flex',
21 alignItems: 'flex-start', 21 alignItems: 'flex-start',
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 0c2588c42..8319d3bc6 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -175,11 +175,11 @@ class WorkspacesDashboard extends Component {
175 <table className={classes.table}> 175 <table className={classes.table}>
176 {/* ===== Workspaces list ===== */} 176 {/* ===== Workspaces list ===== */}
177 <tbody> 177 <tbody>
178 {workspaces.map(workspace => ( 178 {workspaces.map((workspace) => (
179 <WorkspaceItem 179 <WorkspaceItem
180 key={workspace.id} 180 key={workspace.id}
181 workspace={workspace} 181 workspace={workspace}
182 onItemClick={w => onWorkspaceClick(w)} 182 onItemClick={(w) => onWorkspaceClick(w)}
183 /> 183 />
184 ))} 184 ))}
185 </tbody> 185 </tbody>
diff --git a/src/features/workspaces/containers/WorkspacesScreen.js b/src/features/workspaces/containers/WorkspacesScreen.js
index c241cd622..4828658f9 100644
--- a/src/features/workspaces/containers/WorkspacesScreen.js
+++ b/src/features/workspaces/containers/WorkspacesScreen.js
@@ -30,8 +30,8 @@ class WorkspacesScreen extends Component {
30 createWorkspaceRequest={createWorkspaceRequest} 30 createWorkspaceRequest={createWorkspaceRequest}
31 deleteWorkspaceRequest={deleteWorkspaceRequest} 31 deleteWorkspaceRequest={deleteWorkspaceRequest}
32 updateWorkspaceRequest={updateWorkspaceRequest} 32 updateWorkspaceRequest={updateWorkspaceRequest}
33 onCreateWorkspaceSubmit={data => actions.workspaces.create(data)} 33 onCreateWorkspaceSubmit={(data) => actions.workspaces.create(data)}
34 onWorkspaceClick={w => actions.workspaces.edit({ workspace: w })} 34 onWorkspaceClick={(w) => actions.workspaces.edit({ workspace: w })}
35 /> 35 />
36 </ErrorBoundary> 36 </ErrorBoundary>
37 ); 37 );
diff --git a/src/features/workspaces/models/Workspace.js b/src/features/workspaces/models/Workspace.js
index 77c4e05f4..11ee377cd 100644
--- a/src/features/workspaces/models/Workspace.js
+++ b/src/features/workspaces/models/Workspace.js
@@ -22,13 +22,13 @@ export default class Workspace {
22 this.name = data.name; 22 this.name = data.name;
23 this.order = data.order; 23 this.order = data.order;
24 24
25 let services = data.services; 25 let { services } = data;
26 if (data.saving && data.keepLoaded) { 26 if (data.saving && data.keepLoaded) {
27 // Keep workspaces loaded 27 // Keep workspaces loaded
28 services.push(KEEP_WS_LOADED_USID); 28 services.push(KEEP_WS_LOADED_USID);
29 } else if (data.saving && data.services.includes(KEEP_WS_LOADED_USID)) { 29 } else if (data.saving && data.services.includes(KEEP_WS_LOADED_USID)) {
30 // Don't keep loaded 30 // Don't keep loaded
31 services = services.filter(e => e !== KEEP_WS_LOADED_USID); 31 services = services.filter((e) => e !== KEEP_WS_LOADED_USID);
32 } 32 }
33 this.services.replace(services); 33 this.services.replace(services);
34 34
diff --git a/src/helpers/array-helpers.js b/src/helpers/array-helpers.js
index ffb3b63dc..5e592b7f7 100644
--- a/src/helpers/array-helpers.js
+++ b/src/helpers/array-helpers.js
@@ -1,4 +1,4 @@
1export const shuffleArray = arr => arr 1export const shuffleArray = (arr) => arr
2 .map(a => [Math.random(), a]) 2 .map((a) => [Math.random(), a])
3 .sort((a, b) => a[0] - b[0]) 3 .sort((a, b) => a[0] - b[0])
4 .map(a => a[1]); 4 .map((a) => a[1]);
diff --git a/src/helpers/async-helpers.js b/src/helpers/async-helpers.js
index 2ef01ee09..c6c57e28e 100644
--- a/src/helpers/async-helpers.js
+++ b/src/helpers/async-helpers.js
@@ -1,5 +1,5 @@
1/* eslint-disable import/prefer-default-export */ 1/* eslint-disable import/prefer-default-export */
2 2
3export function sleep(ms = 0) { 3export function sleep(ms = 0) {
4 return new Promise(r => setTimeout(r, ms)); 4 return new Promise((r) => setTimeout(r, ms));
5} 5}
diff --git a/src/helpers/service-helpers.js b/src/helpers/service-helpers.js
index f6363aca8..28d483182 100644
--- a/src/helpers/service-helpers.js
+++ b/src/helpers/service-helpers.js
@@ -14,5 +14,5 @@ export function removeServicePartitionDirectory(id = '', addServicePrefix = fals
14 14
15export async function getServiceIdsFromPartitions() { 15export async function getServiceIdsFromPartitions() {
16 const files = await fs.readdir(getServicePartitionsDirectory()); 16 const files = await fs.readdir(getServicePartitionsDirectory());
17 return files.filter(n => n !== '__chrome_extension'); 17 return files.filter((n) => n !== '__chrome_extension');
18} 18}
diff --git a/src/helpers/validation-helpers.js b/src/helpers/validation-helpers.js
index f489ec65e..116f19905 100644
--- a/src/helpers/validation-helpers.js
+++ b/src/helpers/validation-helpers.js
@@ -61,7 +61,7 @@ export function minLength(length) {
61 61
62export function oneRequired(targets) { 62export function oneRequired(targets) {
63 return ({ field, form }) => { 63 return ({ field, form }) => {
64 const invalidFields = targets.filter(target => form.$(target).value === ''); 64 const invalidFields = targets.filter((target) => form.$(target).value === '');
65 return [targets.length !== invalidFields.length, window.ferdi.intl.formatMessage(messages.required, { field: field.label })]; 65 return [targets.length !== invalidFields.length, window.ferdi.intl.formatMessage(messages.required, { field: field.label })];
66 }; 66 };
67} 67}
diff --git a/src/models/Recipe.js b/src/models/Recipe.js
index 4db056f26..106b4a56a 100644
--- a/src/models/Recipe.js
+++ b/src/models/Recipe.js
@@ -89,7 +89,7 @@ export default class Recipe {
89 get author() { 89 get author() {
90 try { 90 try {
91 const addresses = emailParser.parse(this.rawAuthor); 91 const addresses = emailParser.parse(this.rawAuthor);
92 return addresses.map(a => ({ email: a.address, name: a.phrase })); 92 return addresses.map((a) => ({ email: a.address, name: a.phrase }));
93 } catch (err) { 93 } catch (err) {
94 console.warn(`Not a valid author for ${this.name}`); 94 console.warn(`Not a valid author for ${this.name}`);
95 } 95 }
diff --git a/src/models/Service.js b/src/models/Service.js
index 36b310da1..79181186a 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -277,7 +277,7 @@ export default class Service {
277 277
278 this.webview.addEventListener('ipc-message', async (e) => { 278 this.webview.addEventListener('ipc-message', async (e) => {
279 if (e.channel === 'inject-js-unsafe') { 279 if (e.channel === 'inject-js-unsafe') {
280 await Promise.all(e.args.map(script => this.webview.executeJavaScript(`"use strict"; (() => { ${script} })();`))); 280 await Promise.all(e.args.map((script) => this.webview.executeJavaScript(`"use strict"; (() => { ${script} })();`)));
281 } else { 281 } else {
282 handleIPCMessage({ 282 handleIPCMessage({
283 serviceId: this.id, 283 serviceId: this.id,
diff --git a/src/models/UserAgent.js b/src/models/UserAgent.js
index 6f91d4ed0..930ae19ef 100644
--- a/src/models/UserAgent.js
+++ b/src/models/UserAgent.js
@@ -95,10 +95,10 @@ export default class UserAgent {
95 _addWebviewEvents(webview) { 95 _addWebviewEvents(webview) {
96 debug('Adding event handlers'); 96 debug('Adding event handlers');
97 97
98 this._willNavigateListener = event => this._handleNavigate(event.url, true); 98 this._willNavigateListener = (event) => this._handleNavigate(event.url, true);
99 webview.addEventListener('will-navigate', this._willNavigateListener); 99 webview.addEventListener('will-navigate', this._willNavigateListener);
100 100
101 this._didNavigateListener = event => this._handleNavigate(event.url); 101 this._didNavigateListener = (event) => this._handleNavigate(event.url);
102 webview.addEventListener('did-navigate', this._didNavigateListener); 102 webview.addEventListener('did-navigate', this._didNavigateListener);
103 } 103 }
104 104
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.js
index bbb5e6305..6b5ca7c9a 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.js
@@ -1,6 +1,11 @@
1import { ipcRenderer, shell } from 'electron'; 1import { ipcRenderer, shell } from 'electron';
2import { 2import {
3 app, screen, powerMonitor, nativeTheme, getCurrentWindow, process as remoteProcess, 3 app,
4 screen,
5 powerMonitor,
6 nativeTheme,
7 getCurrentWindow,
8 process as remoteProcess,
4} from '@electron/remote'; 9} from '@electron/remote';
5import { action, computed, observable } from 'mobx'; 10import { action, computed, observable } from 'mobx';
6import moment from 'moment'; 11import moment from 'moment';
@@ -14,13 +19,20 @@ import Store from './lib/Store';
14import Request from './lib/Request'; 19import Request from './lib/Request';
15import { CHECK_INTERVAL } from '../config'; 20import { CHECK_INTERVAL } from '../config';
16import { 21import {
17 DEFAULT_APP_SETTINGS, isMac, ferdiVersion, electronVersion, osRelease, 22 DEFAULT_APP_SETTINGS,
23 isMac,
24 ferdiVersion,
25 electronVersion,
26 osRelease,
18} from '../environment'; 27} from '../environment';
19import locales from '../i18n/translations'; 28import locales from '../i18n/translations';
20import { onVisibilityChange } from '../helpers/visibility-helper'; 29import { onVisibilityChange } from '../helpers/visibility-helper';
21import { getLocale } from '../helpers/i18n-helpers'; 30import { getLocale } from '../helpers/i18n-helpers';
22 31
23import { getServiceIdsFromPartitions, removeServicePartitionDirectory } from '../helpers/service-helpers.js'; 32import {
33 getServiceIdsFromPartitions,
34 removeServicePartitionDirectory,
35} from '../helpers/service-helpers';
24import { isValidExternalURL } from '../helpers/url-helpers'; 36import { isValidExternalURL } from '../helpers/url-helpers';
25import { sleep } from '../helpers/async-helpers'; 37import { sleep } from '../helpers/async-helpers';
26 38
@@ -49,7 +61,10 @@ export default class AppStore extends Store {
49 61
50 @observable healthCheckRequest = new Request(this.api.app, 'health'); 62 @observable healthCheckRequest = new Request(this.api.app, 'health');
51 63
52 @observable getAppCacheSizeRequest = new Request(this.api.local, 'getAppCacheSize'); 64 @observable getAppCacheSizeRequest = new Request(
65 this.api.local,
66 'getAppCacheSize',
67 );
53 68
54 @observable clearAppCacheRequest = new Request(this.api.local, 'clearCache'); 69 @observable clearAppCacheRequest = new Request(this.api.local, 'clearCache');
55 70
@@ -93,7 +108,9 @@ export default class AppStore extends Store {
93 this.actions.app.openExternalUrl.listen(this._openExternalUrl.bind(this)); 108 this.actions.app.openExternalUrl.listen(this._openExternalUrl.bind(this));
94 this.actions.app.checkForUpdates.listen(this._checkForUpdates.bind(this)); 109 this.actions.app.checkForUpdates.listen(this._checkForUpdates.bind(this));
95 this.actions.app.installUpdate.listen(this._installUpdate.bind(this)); 110 this.actions.app.installUpdate.listen(this._installUpdate.bind(this));
96 this.actions.app.resetUpdateStatus.listen(this._resetUpdateStatus.bind(this)); 111 this.actions.app.resetUpdateStatus.listen(
112 this._resetUpdateStatus.bind(this),
113 );
97 this.actions.app.healthCheck.listen(this._healthCheck.bind(this)); 114 this.actions.app.healthCheck.listen(this._healthCheck.bind(this));
98 this.actions.app.muteApp.listen(this._muteApp.bind(this)); 115 this.actions.app.muteApp.listen(this._muteApp.bind(this));
99 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this)); 116 this.actions.app.toggleMuteApp.listen(this._toggleMuteApp.bind(this));
@@ -183,9 +200,7 @@ export default class AppStore extends Store {
183 // Handle deep linking (ferdi://) 200 // Handle deep linking (ferdi://)
184 ipcRenderer.on('navigateFromDeepLink', (event, data) => { 201 ipcRenderer.on('navigateFromDeepLink', (event, data) => {
185 debug('Navigate from deep link', data); 202 debug('Navigate from deep link', data);
186 let { 203 let { url } = data;
187 url,
188 } = data;
189 if (!url) return; 204 if (!url) return;
190 205
191 url = url.replace(/\/$/, ''); 206 url = url.replace(/\/$/, '');
@@ -221,7 +236,10 @@ export default class AppStore extends Store {
221 debug('System resumed, last suspended on', this.timeSuspensionStart); 236 debug('System resumed, last suspended on', this.timeSuspensionStart);
222 this.actions.service.resetLastPollTimer(); 237 this.actions.service.resetLastPollTimer();
223 238
224 if (this.timeSuspensionStart.add(10, 'm').isBefore(moment()) && this.stores.settings.app.get('reloadAfterResume')) { 239 if (
240 this.timeSuspensionStart.add(10, 'm').isBefore(moment())
241 && this.stores.settings.app.get('reloadAfterResume')
242 ) {
225 debug('Reloading services, user info and features'); 243 debug('Reloading services, user info and features');
226 244
227 setInterval(() => { 245 setInterval(() => {
@@ -266,15 +284,15 @@ export default class AppStore extends Store {
266 ferdi: { 284 ferdi: {
267 version: ferdiVersion, 285 version: ferdiVersion,
268 electron: electronVersion, 286 electron: electronVersion,
269 installedRecipes: this.stores.recipes.all.map(recipe => ({ 287 installedRecipes: this.stores.recipes.all.map((recipe) => ({
270 id: recipe.id, 288 id: recipe.id,
271 version: recipe.version, 289 version: recipe.version,
272 })), 290 })),
273 devRecipes: this.stores.recipePreviews.dev.map(recipe => ({ 291 devRecipes: this.stores.recipePreviews.dev.map((recipe) => ({
274 id: recipe.id, 292 id: recipe.id,
275 version: recipe.version, 293 version: recipe.version,
276 })), 294 })),
277 services: this.stores.services.all.map(service => ({ 295 services: this.stores.services.all.map((service) => ({
278 id: service.id, 296 id: service.id,
279 recipe: service.recipe.id, 297 recipe: service.recipe.id,
280 isAttached: service.isAttached, 298 isAttached: service.isAttached,
@@ -285,11 +303,13 @@ export default class AppStore extends Store {
285 isDarkModeEnabled: service.isDarkModeEnabled, 303 isDarkModeEnabled: service.isDarkModeEnabled,
286 })), 304 })),
287 messages: this.stores.globalError.messages, 305 messages: this.stores.globalError.messages,
288 workspaces: this.stores.workspaces.workspaces.map(workspace => ({ 306 workspaces: this.stores.workspaces.workspaces.map((workspace) => ({
289 id: workspace.id, 307 id: workspace.id,
290 services: workspace.services, 308 services: workspace.services,
291 })), 309 })),
292 windowSettings: readJsonSync(path.join(app.getPath('userData'), 'window-state.json')), 310 windowSettings: readJsonSync(
311 path.join(app.getPath('userData'), 'window-state.json'),
312 ),
293 settings, 313 settings,
294 features: this.stores.features.features, 314 features: this.stores.features.features,
295 user: this.stores.user.data.id, 315 user: this.stores.user.data.id,
@@ -299,10 +319,7 @@ export default class AppStore extends Store {
299 319
300 // Actions 320 // Actions
301 @action _notify({ 321 @action _notify({
302 title, 322 title, options, notificationId, serviceId = null,
303 options,
304 notificationId,
305 serviceId = null,
306 }) { 323 }) {
307 if (this.stores.settings.all.app.isAppMuted) return; 324 if (this.stores.settings.all.app.isAppMuted) return;
308 325
@@ -339,15 +356,15 @@ export default class AppStore extends Store {
339 }; 356 };
340 } 357 }
341 358
342 @action _setBadge({ 359 @action _setBadge({ unreadDirectMessageCount, unreadIndirectMessageCount }) {
343 unreadDirectMessageCount,
344 unreadIndirectMessageCount,
345 }) {
346 let indicator = unreadDirectMessageCount; 360 let indicator = unreadDirectMessageCount;
347 361
348 if (indicator === 0 && unreadIndirectMessageCount !== 0) { 362 if (indicator === 0 && unreadIndirectMessageCount !== 0) {
349 indicator = '•'; 363 indicator = '•';
350 } else if (unreadDirectMessageCount === 0 && unreadIndirectMessageCount === 0) { 364 } else if (
365 unreadDirectMessageCount === 0
366 && unreadIndirectMessageCount === 0
367 ) {
351 indicator = 0; 368 indicator = 0;
352 } else { 369 } else {
353 indicator = parseInt(indicator, 10); 370 indicator = parseInt(indicator, 10);
@@ -358,9 +375,7 @@ export default class AppStore extends Store {
358 }); 375 });
359 } 376 }
360 377
361 @action _launchOnStartup({ 378 @action _launchOnStartup({ enable }) {
362 enable,
363 }) {
364 this.autoLaunchOnStart = enable; 379 this.autoLaunchOnStart = enable;
365 380
366 try { 381 try {
@@ -376,9 +391,7 @@ export default class AppStore extends Store {
376 } 391 }
377 } 392 }
378 393
379 @action _openExternalUrl({ 394 @action _openExternalUrl({ url }) {
380 url,
381 }) {
382 const parsedUrl = new URL(url); 395 const parsedUrl = new URL(url);
383 debug('open external url', parsedUrl); 396 debug('open external url', parsedUrl);
384 397
@@ -414,10 +427,7 @@ export default class AppStore extends Store {
414 this.healthCheckRequest.execute(); 427 this.healthCheckRequest.execute();
415 } 428 }
416 429
417 @action _muteApp({ 430 @action _muteApp({ isMuted, overrideSystemMute = true }) {
418 isMuted,
419 overrideSystemMute = true,
420 }) {
421 this.isSystemMuteOverridden = overrideSystemMute; 431 this.isSystemMuteOverridden = overrideSystemMute;
422 this.actions.settings.update({ 432 this.actions.settings.update({
423 type: 'app', 433 type: 'app',
@@ -437,16 +447,24 @@ export default class AppStore extends Store {
437 this.isClearingAllCache = true; 447 this.isClearingAllCache = true;
438 const clearAppCache = this.clearAppCacheRequest.execute(); 448 const clearAppCache = this.clearAppCacheRequest.execute();
439 const allServiceIds = await getServiceIdsFromPartitions(); 449 const allServiceIds = await getServiceIdsFromPartitions();
440 const allOrphanedServiceIds = allServiceIds.filter(id => !this.stores.services.all.find(s => id.replace('service-', '') === s.id)); 450 const allOrphanedServiceIds = allServiceIds.filter(
451 (id) => !this.stores.services.all.find(
452 (s) => id.replace('service-', '') === s.id,
453 ),
454 );
441 455
442 try { 456 try {
443 await Promise.all(allOrphanedServiceIds.map(id => removeServicePartitionDirectory(id))); 457 await Promise.all(
458 allOrphanedServiceIds.map((id) => removeServicePartitionDirectory(id)),
459 );
444 } catch (ex) { 460 } catch (ex) {
445 console.log('Error while deleting service partition directory - ', ex); 461 console.log('Error while deleting service partition directory - ', ex);
446 } 462 }
447 await Promise.all(this.stores.services.all.map(s => this.actions.service.clearCache({ 463 await Promise.all(
448 serviceId: s.id, 464 this.stores.services.all.map((s) => this.actions.service.clearCache({
449 }))); 465 serviceId: s.id,
466 })),
467 );
450 468
451 await clearAppCache._promise; 469 await clearAppCache._promise;
452 470
@@ -476,7 +494,11 @@ export default class AppStore extends Store {
476 locale = this.stores.user.data.locale; 494 locale = this.stores.user.data.locale;
477 } 495 }
478 496
479 if (locale && Object.prototype.hasOwnProperty.call(locales, locale) && locale !== this.locale) { 497 if (
498 locale
499 && Object.prototype.hasOwnProperty.call(locales, locale)
500 && locale !== this.locale
501 ) {
480 this.locale = locale; 502 this.locale = locale;
481 } else if (!locale) { 503 } else if (!locale) {
482 this.locale = this._getDefaultLocale(); 504 this.locale = this._getDefaultLocale();
@@ -553,7 +575,10 @@ export default class AppStore extends Store {
553 const dnd = await ipcRenderer.invoke('get-dnd'); 575 const dnd = await ipcRenderer.invoke('get-dnd');
554 debug('Do not disturb mode is', dnd); 576 debug('Do not disturb mode is', dnd);
555 // ipcRenderer.on('autoUpdate', (event, data) => { 577 // ipcRenderer.on('autoUpdate', (event, data) => {
556 if (dnd !== this.stores.settings.all.app.isAppMuted && !this.isSystemMuteOverridden) { 578 if (
579 dnd !== this.stores.settings.all.app.isAppMuted
580 && !this.isSystemMuteOverridden
581 ) {
557 this.actions.app.muteApp({ 582 this.actions.app.muteApp({
558 isMuted: dnd, 583 isMuted: dnd,
559 overrideSystemMute: false, 584 overrideSystemMute: false,
diff --git a/src/stores/NewsStore.js b/src/stores/NewsStore.js
index 86e092592..66a17cb29 100644
--- a/src/stores/NewsStore.js
+++ b/src/stores/NewsStore.js
@@ -38,7 +38,7 @@ export default class NewsStore extends Store {
38 38
39 this.latestNewsRequest.invalidate().patch((result) => { 39 this.latestNewsRequest.invalidate().patch((result) => {
40 // TODO: check if we can use mobx.array remove 40 // TODO: check if we can use mobx.array remove
41 remove(result, n => n.id === newsId); 41 remove(result, (n) => n.id === newsId);
42 }); 42 });
43 } 43 }
44 44
diff --git a/src/stores/RecipePreviewsStore.js b/src/stores/RecipePreviewsStore.js
index 989e1124a..10c170e81 100644
--- a/src/stores/RecipePreviewsStore.js
+++ b/src/stores/RecipePreviewsStore.js
@@ -31,7 +31,7 @@ export default class RecipePreviewsStore extends Store {
31 } 31 }
32 32
33 @computed get dev() { 33 @computed get dev() {
34 return this.stores.recipes.all.filter(r => r.local); 34 return this.stores.recipes.all.filter((r) => r.local);
35 } 35 }
36 36
37 // Actions 37 // Actions
diff --git a/src/stores/RecipesStore.js b/src/stores/RecipesStore.js
index b49fb72d9..c7c4c1deb 100644
--- a/src/stores/RecipesStore.js
+++ b/src/stores/RecipesStore.js
@@ -54,11 +54,11 @@ export default class RecipesStore extends Store {
54 } 54 }
55 55
56 @computed get recipeIdForServices() { 56 @computed get recipeIdForServices() {
57 return this.stores.services.all.map(s => s.recipe.id); 57 return this.stores.services.all.map((s) => s.recipe.id);
58 } 58 }
59 59
60 one(id) { 60 one(id) {
61 return this.all.find(recipe => recipe.id === id); 61 return this.all.find((recipe) => recipe.id === id);
62 } 62 }
63 63
64 isInstalled(id) { 64 isInstalled(id) {
@@ -78,7 +78,7 @@ export default class RecipesStore extends Store {
78 const recipes = {}; 78 const recipes = {};
79 79
80 // Hackfix, reference this.all to fetch services 80 // Hackfix, reference this.all to fetch services
81 debug(`Check Recipe updates for ${this.all.map(recipe => recipe.id)}`); 81 debug(`Check Recipe updates for ${this.all.map((recipe) => recipe.id)}`);
82 82
83 recipeIds.forEach((r) => { 83 recipeIds.forEach((r) => {
84 const recipe = this.one(r); 84 const recipe = this.one(r);
@@ -98,7 +98,7 @@ export default class RecipesStore extends Store {
98 const version = recipes[recipe]; 98 const version = recipes[recipe];
99 99
100 // Find recipe in local recipe repository 100 // Find recipe in local recipe repository
101 const localRecipe = allJson.find(r => r.id === recipe); 101 const localRecipe = allJson.find((r) => r.id === recipe);
102 102
103 if (localRecipe && semver.lt(version, localRecipe.version)) { 103 if (localRecipe && semver.lt(version, localRecipe.version)) {
104 localUpdates.push(recipe); 104 localUpdates.push(recipe);
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index fa31dc292..fefcb5080 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -216,7 +216,7 @@ export default class ServicesStore extends Store {
216 } 216 }
217 217
218 @computed get enabled() { 218 @computed get enabled() {
219 return this.all.filter(service => service.isEnabled); 219 return this.all.filter((service) => service.isEnabled);
220 } 220 }
221 221
222 @computed get allDisplayed() { 222 @computed get allDisplayed() {
@@ -229,7 +229,7 @@ export default class ServicesStore extends Store {
229 const { showDisabledServices } = this.stores.settings.all.app; 229 const { showDisabledServices } = this.stores.settings.all.app;
230 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings; 230 const { keepAllWorkspacesLoaded } = this.stores.workspaces.settings;
231 const services = this.allServicesRequest.execute().result || []; 231 const services = this.allServicesRequest.execute().result || [];
232 const filteredServices = showDisabledServices ? services : services.filter(service => service.isEnabled); 232 const filteredServices = showDisabledServices ? services : services.filter((service) => service.isEnabled);
233 233
234 let displayedServices; 234 let displayedServices;
235 if (keepAllWorkspacesLoaded) { 235 if (keepAllWorkspacesLoaded) {
@@ -244,8 +244,8 @@ export default class ServicesStore extends Store {
244 // Check if workspace needs to be kept loaded 244 // Check if workspace needs to be kept loaded
245 if (workspace.services.includes(KEEP_WS_LOADED_USID)) { 245 if (workspace.services.includes(KEEP_WS_LOADED_USID)) {
246 // Get services for workspace 246 // Get services for workspace
247 const serviceIDs = workspace.services.filter(i => i !== KEEP_WS_LOADED_USID); 247 const serviceIDs = workspace.services.filter((i) => i !== KEEP_WS_LOADED_USID);
248 const wsServices = filteredServices.filter(service => serviceIDs.includes(service.id)); 248 const wsServices = filteredServices.filter((service) => serviceIDs.includes(service.id));
249 249
250 displayedServices = [ 250 displayedServices = [
251 ...displayedServices, 251 ...displayedServices,
@@ -262,11 +262,11 @@ export default class ServicesStore extends Store {
262 } 262 }
263 263
264 @computed get filtered() { 264 @computed get filtered() {
265 return this.all.filter(service => service.name.toLowerCase().includes(this.filterNeedle.toLowerCase())); 265 return this.all.filter((service) => service.name.toLowerCase().includes(this.filterNeedle.toLowerCase()));
266 } 266 }
267 267
268 @computed get active() { 268 @computed get active() {
269 return this.all.find(service => service.isActive); 269 return this.all.find((service) => service.isActive);
270 } 270 }
271 271
272 @computed get activeSettings() { 272 @computed get activeSettings() {
@@ -284,7 +284,7 @@ export default class ServicesStore extends Store {
284 } 284 }
285 285
286 @computed get isTodosServiceAdded() { 286 @computed get isTodosServiceAdded() {
287 return this.allDisplayed.find(service => service.isTodosService && service.isEnabled) || false; 287 return this.allDisplayed.find((service) => service.isTodosService && service.isEnabled) || false;
288 } 288 }
289 289
290 @computed get isTodosServiceActive() { 290 @computed get isTodosServiceActive() {
@@ -292,7 +292,7 @@ export default class ServicesStore extends Store {
292 } 292 }
293 293
294 one(id) { 294 one(id) {
295 return this.all.find(service => service.id === id); 295 return this.all.find((service) => service.id === id);
296 } 296 }
297 297
298 async _showAddServiceInterface({ recipeId }) { 298 async _showAddServiceInterface({ recipeId }) {
@@ -400,7 +400,7 @@ export default class ServicesStore extends Store {
400 newData.iconUrl = data.customIconUrl; 400 newData.iconUrl = data.customIconUrl;
401 } 401 }
402 402
403 Object.assign(result.find(c => c.id === serviceId), newData); 403 Object.assign(result.find((c) => c.id === serviceId), newData);
404 }); 404 });
405 405
406 await request._promise; 406 await request._promise;
@@ -434,7 +434,7 @@ export default class ServicesStore extends Store {
434 } 434 }
435 435
436 this.allServicesRequest.patch((result) => { 436 this.allServicesRequest.patch((result) => {
437 remove(result, c => c.id === serviceId); 437 remove(result, (c) => c.id === serviceId);
438 }); 438 });
439 439
440 await request._promise; 440 await request._promise;
@@ -493,7 +493,7 @@ export default class ServicesStore extends Store {
493 } 493 }
494 494
495 // Update list of last used services 495 // Update list of last used services
496 this.lastUsedServices = this.lastUsedServices.filter(id => id !== serviceId); 496 this.lastUsedServices = this.lastUsedServices.filter((id) => id !== serviceId);
497 this.lastUsedServices.unshift(serviceId); 497 this.lastUsedServices.unshift(serviceId);
498 498
499 this._focusActiveService(); 499 this._focusActiveService();
@@ -505,7 +505,7 @@ export default class ServicesStore extends Store {
505 } 505 }
506 506
507 @action _setActiveNext() { 507 @action _setActiveNext() {
508 const nextIndex = this._wrapIndex(this.allDisplayed.findIndex(service => service.isActive), 1, this.allDisplayed.length); 508 const nextIndex = this._wrapIndex(this.allDisplayed.findIndex((service) => service.isActive), 1, this.allDisplayed.length);
509 509
510 // TODO: simplify this; 510 // TODO: simplify this;
511 this.all.forEach((s, index) => { 511 this.all.forEach((s, index) => {
@@ -515,7 +515,7 @@ export default class ServicesStore extends Store {
515 } 515 }
516 516
517 @action _setActivePrev() { 517 @action _setActivePrev() {
518 const prevIndex = this._wrapIndex(this.allDisplayed.findIndex(service => service.isActive), -1, this.allDisplayed.length); 518 const prevIndex = this._wrapIndex(this.allDisplayed.findIndex((service) => service.isActive), -1, this.allDisplayed.length);
519 519
520 // TODO: simplify this; 520 // TODO: simplify this;
521 this.all.forEach((s, index) => { 521 this.all.forEach((s, index) => {
@@ -689,7 +689,7 @@ export default class ServicesStore extends Store {
689 } 689 }
690 690
691 @action _sendIPCMessageToAllServices({ channel, args }) { 691 @action _sendIPCMessageToAllServices({ channel, args }) {
692 this.all.forEach(s => this.actions.service.sendIPCMessage({ 692 this.all.forEach((s) => this.actions.service.sendIPCMessage({
693 serviceId: s.id, 693 serviceId: s.id,
694 channel, 694 channel,
695 args, 695 args,
@@ -740,7 +740,7 @@ export default class ServicesStore extends Store {
740 } 740 }
741 741
742 @action _reloadAll() { 742 @action _reloadAll() {
743 this.enabled.forEach(s => this._reload({ 743 this.enabled.forEach((s) => this._reload({
744 serviceId: s.id, 744 serviceId: s.id,
745 })); 745 }));
746 } 746 }
@@ -859,7 +859,7 @@ export default class ServicesStore extends Store {
859 }; 859 };
860 860
861 if (!serviceId) { 861 if (!serviceId) {
862 this.allDisplayed.forEach(service => resetTimer(service)); 862 this.allDisplayed.forEach((service) => resetTimer(service));
863 } else { 863 } else {
864 const service = this.one(serviceId); 864 const service = this.one(serviceId);
865 if (service) { 865 if (service) {
@@ -893,7 +893,7 @@ export default class ServicesStore extends Store {
893 _mapActiveServiceToServiceModelReaction() { 893 _mapActiveServiceToServiceModelReaction() {
894 const { activeService } = this.stores.settings.all.service; 894 const { activeService } = this.stores.settings.all.service;
895 if (this.allDisplayed.length) { 895 if (this.allDisplayed.length) {
896 this.allDisplayed.map(service => Object.assign(service, { 896 this.allDisplayed.map((service) => Object.assign(service, {
897 isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id, 897 isActive: activeService ? activeService === service.id : this.allDisplayed[0].id === service.id,
898 })); 898 }));
899 } 899 }
@@ -904,13 +904,13 @@ export default class ServicesStore extends Store {
904 const { showMessageBadgesEvenWhenMuted } = this.stores.ui; 904 const { showMessageBadgesEvenWhenMuted } = this.stores.ui;
905 905
906 const unreadDirectMessageCount = this.allDisplayed 906 const unreadDirectMessageCount = this.allDisplayed
907 .filter(s => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled) 907 .filter((s) => (showMessageBadgeWhenMuted || s.isNotificationEnabled) && showMessageBadgesEvenWhenMuted && s.isBadgeEnabled)
908 .map(s => s.unreadDirectMessageCount) 908 .map((s) => s.unreadDirectMessageCount)
909 .reduce((a, b) => a + b, 0); 909 .reduce((a, b) => a + b, 0);
910 910
911 const unreadIndirectMessageCount = this.allDisplayed 911 const unreadIndirectMessageCount = this.allDisplayed
912 .filter(s => (showMessageBadgeWhenMuted && showMessageBadgesEvenWhenMuted) && (s.isBadgeEnabled && s.isIndirectMessageBadgeEnabled)) 912 .filter((s) => (showMessageBadgeWhenMuted && showMessageBadgesEvenWhenMuted) && (s.isBadgeEnabled && s.isIndirectMessageBadgeEnabled))
913 .map(s => s.unreadIndirectMessageCount) 913 .map((s) => s.unreadIndirectMessageCount)
914 .reduce((a, b) => a + b, 0); 914 .reduce((a, b) => a + b, 0);
915 915
916 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases 916 // We can't just block this earlier, otherwise the mobx reaction won't be aware of the vars to watch in some cases
@@ -975,7 +975,7 @@ export default class ServicesStore extends Store {
975 return; 975 return;
976 } 976 }
977 977
978 if (this.allDisplayed.findIndex(service => service.isActive) === -1 && this.allDisplayed.length !== 0) { 978 if (this.allDisplayed.findIndex((service) => service.isActive) === -1 && this.allDisplayed.length !== 0) {
979 debug('No active service found, setting active service to index 0'); 979 debug('No active service found, setting active service to index 0');
980 980
981 this._setActive({ serviceId: this.allDisplayed[0].id }); 981 this._setActive({ serviceId: this.allDisplayed[0].id });
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.js
index 0ca61046a..adcd776c1 100644
--- a/src/stores/UIStore.js
+++ b/src/stores/UIStore.js
@@ -71,7 +71,7 @@ export default class UIStore extends Store {
71 71
72 @computed get theme() { 72 @computed get theme() {
73 const themeId = (this.isDarkThemeActive || this.stores.settings.app.darkMode) ? 'dark' : 'default'; 73 const themeId = (this.isDarkThemeActive || this.stores.settings.app.darkMode) ? 'dark' : 'default';
74 const accentColor = this.stores.settings.app.accentColor; 74 const { accentColor } = this.stores.settings.app;
75 return theme(themeId, accentColor); 75 return theme(themeId, accentColor);
76 } 76 }
77 77
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 8a525c2ef..2e009893a 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -205,7 +205,7 @@ export default class UserStore extends Store {
205 } 205 }
206 206
207 @action async _invite({ invites }) { 207 @action async _invite({ invites }) {
208 const data = invites.filter(invite => invite.email !== ''); 208 const data = invites.filter((invite) => invite.email !== '');
209 209
210 const response = await this.inviteRequest.execute(data)._promise; 210 const response = await this.inviteRequest.execute(data)._promise;
211 211
@@ -250,7 +250,7 @@ export default class UserStore extends Store {
250 this.isImportLegacyServicesExecuting = true; 250 this.isImportLegacyServicesExecuting = true;
251 251
252 // Reduces recipe duplicates 252 // Reduces recipe duplicates
253 const recipes = services.filter((obj, pos, arr) => arr.map(mapObj => mapObj.recipe.id).indexOf(obj.recipe.id) === pos).map(s => s.recipe.id); 253 const recipes = services.filter((obj, pos, arr) => arr.map((mapObj) => mapObj.recipe.id).indexOf(obj.recipe.id) === pos).map((s) => s.recipe.id);
254 254
255 // Install recipes 255 // Install recipes
256 for (const recipe of recipes) { // eslint-disable-line no-unused-vars 256 for (const recipe of recipes) { // eslint-disable-line no-unused-vars
diff --git a/src/stores/lib/CachedRequest.js b/src/stores/lib/CachedRequest.js
index 31c7ce241..94f615144 100644
--- a/src/stores/lib/CachedRequest.js
+++ b/src/stores/lib/CachedRequest.js
@@ -92,7 +92,7 @@ export default class CachedRequest extends Request {
92 } 92 }
93 93
94 removeCacheForCallWith(...args) { 94 removeCacheForCallWith(...args) {
95 remove(this._apiCalls, c => isEqual(c.args, args)); 95 remove(this._apiCalls, (c) => isEqual(c.args, args));
96 } 96 }
97 97
98 _addApiCall(args) { 98 _addApiCall(args) {
@@ -102,6 +102,6 @@ export default class CachedRequest extends Request {
102 } 102 }
103 103
104 _findApiCall(args) { 104 _findApiCall(args) {
105 return this._apiCalls.find(c => isEqual(c.args, args)); 105 return this._apiCalls.find((c) => isEqual(c.args, args));
106 } 106 }
107} 107}
diff --git a/src/stores/lib/Reaction.js b/src/stores/lib/Reaction.js
index f8009b7f6..7e1bc685e 100644
--- a/src/stores/lib/Reaction.js
+++ b/src/stores/lib/Reaction.js
@@ -26,6 +26,6 @@ export default class Reaction {
26 } 26 }
27} 27}
28 28
29export const createReactions = reactions => ( 29export const createReactions = (reactions) => (
30 reactions.map(r => new Reaction(r)) 30 reactions.map((r) => new Reaction(r))
31); 31);
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.js
index cfc857c2e..32ffe4367 100644
--- a/src/stores/lib/Request.js
+++ b/src/stores/lib/Request.js
@@ -107,7 +107,7 @@ export default class Request {
107 } 107 }
108 108
109 _triggerHooks() { 109 _triggerHooks() {
110 Request._hooks.forEach(hook => hook(this)); 110 Request._hooks.forEach((hook) => hook(this));
111 } 111 }
112 112
113 reset = () => { 113 reset = () => {
diff --git a/src/stores/lib/Store.js b/src/stores/lib/Store.js
index 8d2fb4066..b03a7e725 100644
--- a/src/stores/lib/Store.js
+++ b/src/stores/lib/Store.js
@@ -28,18 +28,18 @@ export default class Store {
28 } 28 }
29 29
30 registerReactions(reactions) { 30 registerReactions(reactions) {
31 reactions.forEach(reaction => this._reactions.push(new Reaction(reaction))); 31 reactions.forEach((reaction) => this._reactions.push(new Reaction(reaction)));
32 } 32 }
33 33
34 setup() {} 34 setup() {}
35 35
36 initialize() { 36 initialize() {
37 this.setup(); 37 this.setup();
38 this._reactions.forEach(reaction => reaction.start()); 38 this._reactions.forEach((reaction) => reaction.start());
39 } 39 }
40 40
41 teardown() { 41 teardown() {
42 this._reactions.forEach(reaction => reaction.stop()); 42 this._reactions.forEach((reaction) => reaction.stop());
43 } 43 }
44 44
45 resetStatus() { 45 resetStatus() {
diff --git a/src/webview/contextMenuBuilder.js b/src/webview/contextMenuBuilder.js
index 63eed2ebe..2598dbf03 100644
--- a/src/webview/contextMenuBuilder.js
+++ b/src/webview/contextMenuBuilder.js
@@ -61,7 +61,7 @@ module.exports = class ContextMenuBuilder {
61 * @param {function} processMenu If passed, this method will be passed the menu to change 61 * @param {function} processMenu If passed, this method will be passed the menu to change
62 * it prior to display. Signature: (menu, info) => menu 62 * it prior to display. Signature: (menu, info) => menu
63 */ 63 */
64 constructor(webContents, debugMode = false, processMenu = m => m) { 64 constructor(webContents, debugMode = false, processMenu = (m) => m) {
65 this.debugMode = debugMode; 65 this.debugMode = debugMode;
66 this.processMenu = processMenu; 66 this.processMenu = processMenu;
67 this.menu = null; 67 this.menu = null;
@@ -320,7 +320,7 @@ module.exports = class ContextMenuBuilder {
320 label: this.stringTable.copyImage(), 320 label: this.stringTable.copyImage(),
321 click: () => { 321 click: () => {
322 const result = this.convertImageToBase64(menuInfo.srcURL, 322 const result = this.convertImageToBase64(menuInfo.srcURL,
323 dataURL => clipboard.writeImage(nativeImage.createFromDataURL(dataURL))); 323 (dataURL) => clipboard.writeImage(nativeImage.createFromDataURL(dataURL)));
324 324
325 this._sendNotificationOnClipboardEvent(menuInfo.clipboardNotifications, () => `Image copied from URL: ${menuInfo.srcURL}`); 325 this._sendNotificationOnClipboardEvent(menuInfo.clipboardNotifications, () => `Image copied from URL: ${menuInfo.srcURL}`);
326 return result; 326 return result;
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js
index 3bb9352f6..305e79882 100644
--- a/src/webview/lib/RecipeWebview.js
+++ b/src/webview/lib/RecipeWebview.js
@@ -75,7 +75,7 @@ class RecipeWebview {
75 debug('Script not found', file); 75 debug('Script not found', file);
76 return null; 76 return null;
77 })).then(async (scripts) => { 77 })).then(async (scripts) => {
78 const scriptsFound = scripts.filter(script => script !== null); 78 const scriptsFound = scripts.filter((script) => script !== null);
79 if (scriptsFound.length > 0) { 79 if (scriptsFound.length > 0) {
80 debug('Inject scripts to main world', scriptsFound); 80 debug('Inject scripts to main world', scriptsFound);
81 ipcRenderer.sendToHost('inject-js-unsafe', ...scriptsFound); 81 ipcRenderer.sendToHost('inject-js-unsafe', ...scriptsFound);
diff --git a/src/webview/notifications.js b/src/webview/notifications.js
index 39a515143..205a3220c 100644
--- a/src/webview/notifications.js
+++ b/src/webview/notifications.js
@@ -4,7 +4,7 @@ import uuidV1 from 'uuid/v1';
4const debug = require('debug')('Ferdi:Notifications'); 4const debug = require('debug')('Ferdi:Notifications');
5 5
6export class NotificationsHandler { 6export class NotificationsHandler {
7 onNotify = data => data; 7 onNotify = (data) => data;
8 8
9 displayNotification(title, options) { 9 displayNotification(title, options) {
10 return new Promise((resolve) => { 10 return new Promise((resolve) => {
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js
index 58a04b728..b59319495 100644
--- a/src/webview/spellchecker.js
+++ b/src/webview/spellchecker.js
@@ -9,7 +9,7 @@ const [defaultLocale] = webContents.session.getSpellCheckerLanguages();
9debug('Spellchecker default locale is', defaultLocale); 9debug('Spellchecker default locale is', defaultLocale);
10 10
11export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) { 11export function getSpellcheckerLocaleByFuzzyIdentifier(identifier) {
12 const locales = Object.keys(SPELLCHECKER_LOCALES).filter(key => key.toLocaleLowerCase() === identifier.toLowerCase() || key.split('-')[0] === identifier.toLowerCase()); 12 const locales = Object.keys(SPELLCHECKER_LOCALES).filter((key) => key.toLocaleLowerCase() === identifier.toLowerCase() || key.split('-')[0] === identifier.toLowerCase());
13 13
14 if (locales.length >= 1) { 14 if (locales.length >= 1) {
15 return locales[0]; 15 return locales[0];