aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar Markus Hatvan <markus_hatvan@aon.at>2021-10-15 09:48:06 +0200
committerLibravatar GitHub <noreply@github.com>2021-10-15 09:48:06 +0200
commit14d2364fc69e0222133115c55a36286986006098 (patch)
tree9e9b3c41ef742bbe87ca1632b292c67043051957 /src
parent5.6.3-nightly.34 [skip ci] (diff)
downloadferdium-app-14d2364fc69e0222133115c55a36286986006098.tar.gz
ferdium-app-14d2364fc69e0222133115c55a36286986006098.tar.zst
ferdium-app-14d2364fc69e0222133115c55a36286986006098.zip
chore: update eslint setup (#2074)
Diffstat (limited to 'src')
-rw-r--r--src/actions/user.ts8
-rw-r--r--src/components/layout/Sidebar.js4
-rw-r--r--src/components/services/content/ErrorHandlers/styles.ts2
-rw-r--r--src/components/services/content/ServiceView.js2
-rw-r--r--src/components/services/content/ServiceWebview.js36
-rw-r--r--src/components/services/tabs/TabBarSortableList.js10
-rw-r--r--src/components/settings/settings/EditSettingsForm.js16
-rw-r--r--src/components/ui/Modal/styles.ts2
-rw-r--r--src/components/ui/ServiceIcon.js18
-rw-r--r--src/components/ui/WebviewLoader/styles.ts2
-rw-r--r--src/components/util/ErrorBoundary/styles.js2
-rw-r--r--src/containers/settings/EditSettingsScreen.js8
-rw-r--r--src/containers/settings/RecipesScreen.js22
-rw-r--r--src/electron/exception.ts2
-rw-r--r--src/electron/ipc-api/sessionStorage.ts6
-rw-r--r--src/enforce-macos-app-location.ts18
-rw-r--r--src/environment-remote.ts18
-rwxr-xr-xsrc/features/settingsWS/actions.ts11
-rw-r--r--src/features/todos/components/TodosWebview.js15
-rw-r--r--src/features/todos/containers/TodosScreen.js17
-rw-r--r--src/features/utils/ActionBinding.ts5
-rw-r--r--src/features/utils/FeatureStore.test.js21
-rw-r--r--src/features/workspaces/components/WorkspaceDrawerItem.js8
-rw-r--r--src/features/workspaces/components/WorkspacesDashboard.js3
-rw-r--r--src/features/workspaces/store.js46
-rw-r--r--src/helpers/array-helpers.ts9
-rw-r--r--src/helpers/async-helpers.ts4
-rw-r--r--src/helpers/routing-helpers.ts3
-rw-r--r--src/helpers/schedule-helpers.ts53
-rw-r--r--src/helpers/url-helpers.ts5
-rw-r--r--src/internal-server/app/Controllers/Http/RecipeController.js2
-rw-r--r--src/internal-server/app/Controllers/Http/ServiceController.js2
-rw-r--r--src/internal-server/app/Controllers/Http/UserController.js5
-rw-r--r--src/internal-server/app/Controllers/Http/WorkspaceController.js2
-rw-r--r--src/internal-server/config/app.js1
-rw-r--r--src/internal-server/config/bodyParser.js12
-rw-r--r--src/internal-server/database/migrations/1503250034279_user.js2
-rw-r--r--src/internal-server/database/migrations/1566385379883_service_schema.js2
-rw-r--r--src/internal-server/database/migrations/1566554231482_recipe_schema.js2
-rw-r--r--src/internal-server/database/migrations/1566554359294_workspace_schema.js2
-rw-r--r--src/internal-server/start/app.js9
-rw-r--r--src/jsUtils.ts17
-rw-r--r--src/lib/Tray.js53
-rw-r--r--src/models/Recipe.ts67
-rw-r--r--src/models/User.ts3
-rw-r--r--src/models/UserAgent.js8
-rw-r--r--src/stores/RecipePreviewsStore.js12
-rw-r--r--src/stores/ServicesStore.js2
-rw-r--r--src/stores/SettingsStore.js6
-rw-r--r--src/stores/UserStore.js2
-rw-r--r--src/stores/lib/Request.js82
-rw-r--r--src/stores/lib/Store.js3
-rw-r--r--src/webview/badge.ts13
-rw-r--r--src/webview/contextMenuBuilder.ts4
-rw-r--r--src/webview/spellchecker.ts6
55 files changed, 416 insertions, 279 deletions
diff --git a/src/actions/user.ts b/src/actions/user.ts
index 20d27ee53..15a9216bd 100644
--- a/src/actions/user.ts
+++ b/src/actions/user.ts
@@ -25,8 +25,10 @@ export default {
25 userData: PropTypes.object.isRequired, 25 userData: PropTypes.object.isRequired,
26 }, 26 },
27 resetStatus: {}, 27 resetStatus: {},
28 importLegacyServices: PropTypes.arrayOf(PropTypes.shape({ 28 importLegacyServices: PropTypes.arrayOf(
29 recipe: PropTypes.string.isRequired, 29 PropTypes.shape({
30 })).isRequired, 30 recipe: PropTypes.string.isRequired,
31 }),
32 ).isRequired,
31 delete: {}, 33 delete: {},
32}; 34};
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 76edcf2e1..fc33a3c58 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -177,7 +177,7 @@ class Sidebar extends Component {
177 > 177 >
178 <i className="mdi mdi-check-all" /> 178 <i className="mdi mdi-check-all" />
179 </button> 179 </button>
180 ) : null} 180 ) : null}
181 {workspaceStore.isFeatureEnabled ? ( 181 {workspaceStore.isFeatureEnabled ? (
182 <button 182 <button
183 type="button" 183 type="button"
@@ -243,7 +243,7 @@ class Sidebar extends Component {
243 this.props.stores.app.updateStatusTypes.AVAILABLE || 243 this.props.stores.app.updateStatusTypes.AVAILABLE ||
244 this.props.stores.app.updateStatus === 244 this.props.stores.app.updateStatus ===
245 this.props.stores.app.updateStatusTypes.DOWNLOADED) && ( 245 this.props.stores.app.updateStatusTypes.DOWNLOADED) && (
246 <span className="update-available">•</span> 246 <span className="update-available">•</span>
247 )} 247 )}
248 </button> 248 </button>
249 {this.state.tooltipEnabled && ( 249 {this.state.tooltipEnabled && (
diff --git a/src/components/services/content/ErrorHandlers/styles.ts b/src/components/services/content/ErrorHandlers/styles.ts
index 72d62f5e3..9e2509ee5 100644
--- a/src/components/services/content/ErrorHandlers/styles.ts
+++ b/src/components/services/content/ErrorHandlers/styles.ts
@@ -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/ServiceView.js b/src/components/services/content/ServiceView.js
index 8e44efc5f..1bc1fbf5f 100644
--- a/src/components/services/content/ServiceView.js
+++ b/src/components/services/content/ServiceView.js
@@ -123,7 +123,7 @@ class ServiceView extends Component {
123 service.isFirstLoad && 123 service.isFirstLoad &&
124 !service.isServiceAccessRestricted && ( 124 !service.isServiceAccessRestricted && (
125 <WebviewLoader loaded={false} name={service.name} /> 125 <WebviewLoader loaded={false} name={service.name} />
126 )} 126 )}
127 {service.isError && ( 127 {service.isError && (
128 <WebviewErrorHandler 128 <WebviewErrorHandler
129 name={service.recipe.name} 129 name={service.recipe.name}
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index b60ed3267..185d41175 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -24,12 +24,10 @@ class ServiceWebview extends Component {
24 super(props); 24 super(props);
25 25
26 reaction( 26 reaction(
27 () => ( 27 () => this.webview,
28 this.webview
29 ),
30 () => { 28 () => {
31 if (this.webview && this.webview.view) { 29 if (this.webview && this.webview.view) {
32 this.webview.view.addEventListener('console-message', (e) => { 30 this.webview.view.addEventListener('console-message', e => {
33 debug('Service logged a message:', e.message); 31 debug('Service logged a message:', e.message);
34 }); 32 });
35 } 33 }
@@ -55,20 +53,26 @@ class ServiceWebview extends Component {
55 }; 53 };
56 54
57 render() { 55 render() {
58 const { 56 const { service, setWebviewReference, isSpellcheckerEnabled } = this.props;
59 service,
60 setWebviewReference,
61 isSpellcheckerEnabled,
62 } = this.props;
63 57
64 const preloadScript = join(__dirname, '..', '..', '..', 'webview', 'recipe.js'); 58 const preloadScript = join(
59 __dirname,
60 '..',
61 '..',
62 '..',
63 'webview',
64 'recipe.js',
65 );
65 66
66 return ( 67 return (
67 <ElectronWebView 68 <ElectronWebView
68 ref={(webview) => { 69 ref={webview => {
69 this.webview = webview; 70 this.webview = webview;
70 if (webview && webview.view) { 71 if (webview && webview.view) {
71 webview.view.addEventListener('did-stop-loading', this.refocusWebview); 72 webview.view.addEventListener(
73 'did-stop-loading',
74 this.refocusWebview,
75 );
72 } 76 }
73 }} 77 }}
74 autosize 78 autosize
@@ -83,10 +87,14 @@ class ServiceWebview extends Component {
83 }} 87 }}
84 onUpdateTargetUrl={this.updateTargetUrl} 88 onUpdateTargetUrl={this.updateTargetUrl}
85 useragent={service.userAgent} 89 useragent={service.userAgent}
86 disablewebsecurity={service.recipe.disablewebsecurity ? true : undefined} 90 disablewebsecurity={
91 service.recipe.disablewebsecurity ? true : undefined
92 }
87 allowpopups 93 allowpopups
88 nodeintegration 94 nodeintegration
89 webpreferences={`spellcheck=${isSpellcheckerEnabled ? 1 : 0}, contextIsolation=1, enableRemoteModule=1`} 95 webpreferences={`spellcheck=${
96 isSpellcheckerEnabled ? 1 : 0
97 }, contextIsolation=1, enableRemoteModule=1`}
90 /> 98 />
91 ); 99 );
92 } 100 }
diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js
index 146cd93eb..69a12e982 100644
--- a/src/components/services/tabs/TabBarSortableList.js
+++ b/src/components/services/tabs/TabBarSortableList.js
@@ -22,7 +22,7 @@ class TabBarSortableList extends Component {
22 wakeUpService: PropTypes.func.isRequired, 22 wakeUpService: PropTypes.func.isRequired,
23 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, 23 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired,
24 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, 24 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired,
25 } 25 };
26 26
27 render() { 27 render() {
28 const { 28 const {
@@ -43,9 +43,7 @@ class TabBarSortableList extends Component {
43 } = this.props; 43 } = this.props;
44 44
45 return ( 45 return (
46 <ul 46 <ul className="tabs">
47 className="tabs"
48 >
49 {services.map((service, index) => ( 47 {services.map((service, index) => (
50 <TabItem 48 <TabItem
51 key={service.id} 49 key={service.id}
@@ -54,7 +52,9 @@ class TabBarSortableList extends Component {
54 index={index} 52 index={index}
55 shortcutIndex={index + 1} 53 shortcutIndex={index + 1}
56 reload={() => reload({ serviceId: service.id })} 54 reload={() => reload({ serviceId: service.id })}
57 toggleNotifications={() => toggleNotifications({ serviceId: service.id })} 55 toggleNotifications={() =>
56 toggleNotifications({ serviceId: service.id })
57 }
58 toggleAudio={() => toggleAudio({ serviceId: service.id })} 58 toggleAudio={() => toggleAudio({ serviceId: service.id })}
59 toggleDarkMode={() => toggleDarkMode({ serviceId: service.id })} 59 toggleDarkMode={() => toggleDarkMode({ serviceId: service.id })}
60 deleteService={() => deleteService({ serviceId: service.id })} 60 deleteService={() => deleteService({ serviceId: service.id })}
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index 40242858a..948e9ccd5 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -12,13 +12,17 @@ import ToggleRaw from '../../ui/ToggleRaw';
12import Select from '../../ui/Select'; 12import Select from '../../ui/Select';
13import Input from '../../ui/Input'; 13import Input from '../../ui/Input';
14 14
15import { DEFAULT_APP_SETTINGS, FRANZ_TRANSLATION, GITHUB_FRANZ_URL } from '../../../config';
16import { 15import {
17 isMac, 16 DEFAULT_APP_SETTINGS,
18 isWindows, 17 FRANZ_TRANSLATION,
19 lockFerdiShortcutKey, 18 GITHUB_FRANZ_URL,
20} from '../../../environment'; 19} from '../../../config';
21import { ferdiVersion, userDataPath, userDataRecipesPath } from '../../../environment-remote'; 20import { isMac, isWindows, lockFerdiShortcutKey } from '../../../environment';
21import {
22 ferdiVersion,
23 userDataPath,
24 userDataRecipesPath,
25} from '../../../environment-remote';
22import { openPath } from '../../../helpers/url-helpers'; 26import { openPath } from '../../../helpers/url-helpers';
23import globalMessages from '../../../i18n/globalMessages'; 27import globalMessages from '../../../i18n/globalMessages';
24 28
diff --git a/src/components/ui/Modal/styles.ts b/src/components/ui/Modal/styles.ts
index f32c075ce..c2bebf9bb 100644
--- a/src/components/ui/Modal/styles.ts
+++ b/src/components/ui/Modal/styles.ts
@@ -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/ServiceIcon.js b/src/components/ui/ServiceIcon.js
index 2e9312d27..f067f8955 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 },
@@ -24,7 +24,8 @@ const styles = (theme) => ({
24 }, 24 },
25}); 25});
26 26
27@injectSheet(styles) @observer 27@injectSheet(styles)
28@observer
28class ServiceIcon extends Component { 29class ServiceIcon extends Component {
29 static propTypes = { 30 static propTypes = {
30 classes: PropTypes.object.isRequired, 31 classes: PropTypes.object.isRequired,
@@ -37,19 +38,10 @@ class ServiceIcon extends Component {
37 }; 38 };
38 39
39 render() { 40 render() {
40 const { 41 const { classes, className, service } = this.props;
41 classes,
42 className,
43 service,
44 } = this.props;
45 42
46 return ( 43 return (
47 <div 44 <div className={classnames([classes.root, className])}>
48 className={classnames([
49 classes.root,
50 className,
51 ])}
52 >
53 <img 45 <img
54 src={service.icon} 46 src={service.icon}
55 className={classnames([ 47 className={classnames([
diff --git a/src/components/ui/WebviewLoader/styles.ts b/src/components/ui/WebviewLoader/styles.ts
index 5d58011fe..dbd75db8a 100644
--- a/src/components/ui/WebviewLoader/styles.ts
+++ b/src/components/ui/WebviewLoader/styles.ts
@@ -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 51b36fdf3..0960546ff 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/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index 889f3f87f..aea077a1e 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -297,7 +297,9 @@ class EditSettingsScreen extends Component {
297 scheduledDNDStart: settingsData.scheduledDNDStart, 297 scheduledDNDStart: settingsData.scheduledDNDStart,
298 scheduledDNDEnd: settingsData.scheduledDNDEnd, 298 scheduledDNDEnd: settingsData.scheduledDNDEnd,
299 enableGPUAcceleration: Boolean(settingsData.enableGPUAcceleration), 299 enableGPUAcceleration: Boolean(settingsData.enableGPUAcceleration),
300 enableGlobalHideShortcut: Boolean(settingsData.enableGlobalHideShortcut), 300 enableGlobalHideShortcut: Boolean(
301 settingsData.enableGlobalHideShortcut,
302 ),
301 showDisabledServices: Boolean(settingsData.showDisabledServices), 303 showDisabledServices: Boolean(settingsData.showDisabledServices),
302 darkMode: Boolean(settingsData.darkMode), 304 darkMode: Boolean(settingsData.darkMode),
303 adaptableDarkMode: Boolean(settingsData.adaptableDarkMode), 305 adaptableDarkMode: Boolean(settingsData.adaptableDarkMode),
@@ -305,7 +307,9 @@ class EditSettingsScreen extends Component {
305 splitMode: Boolean(settingsData.splitMode), 307 splitMode: Boolean(settingsData.splitMode),
306 serviceRibbonWidth: Number(settingsData.serviceRibbonWidth), 308 serviceRibbonWidth: Number(settingsData.serviceRibbonWidth),
307 iconSize: Number(settingsData.iconSize), 309 iconSize: Number(settingsData.iconSize),
308 enableLongPressServiceHint: Boolean(settingsData.enableLongPressServiceHint), 310 enableLongPressServiceHint: Boolean(
311 settingsData.enableLongPressServiceHint,
312 ),
309 useVerticalStyle: Boolean(settingsData.useVerticalStyle), 313 useVerticalStyle: Boolean(settingsData.useVerticalStyle),
310 alwaysShowWorkspaces: Boolean(settingsData.alwaysShowWorkspaces), 314 alwaysShowWorkspaces: Boolean(settingsData.alwaysShowWorkspaces),
311 accentColor: settingsData.accentColor, 315 accentColor: settingsData.accentColor,
diff --git a/src/containers/settings/RecipesScreen.js b/src/containers/settings/RecipesScreen.js
index 832c2db10..7f55e54c5 100644
--- a/src/containers/settings/RecipesScreen.js
+++ b/src/containers/settings/RecipesScreen.js
@@ -130,21 +130,21 @@ class RecipesScreen extends Component {
130 130
131 const allRecipes = this.state.needle 131 const allRecipes = this.state.needle
132 ? this.prepareRecipes([ 132 ? this.prepareRecipes([
133 // All search recipes from server 133 // All search recipes from server
134 ...recipePreviews.searchResults, 134 ...recipePreviews.searchResults,
135 // All search recipes from local recipes 135 // All search recipes from local recipes
136 ...this.createPreviews( 136 ...this.createPreviews(
137 this.customRecipes.filter( 137 this.customRecipes.filter(
138 service => 138 service =>
139 service.name 139 service.name
140 .toLowerCase() 140 .toLowerCase()
141 .includes(this.state.needle.toLowerCase()) || 141 .includes(this.state.needle.toLowerCase()) ||
142 (service.aliases || []).some(alias => 142 (service.aliases || []).some(alias =>
143 alias.toLowerCase().includes(this.state.needle.toLowerCase()), 143 alias.toLowerCase().includes(this.state.needle.toLowerCase()),
144 ), 144 ),
145 ),
145 ), 146 ),
146 ), 147 ]).sort(this._sortByName)
147 ]).sort(this._sortByName)
148 : recipeFilter; 148 : recipeFilter;
149 149
150 const customWebsiteRecipe = recipePreviews.all.find( 150 const customWebsiteRecipe = recipePreviews.all.find(
diff --git a/src/electron/exception.ts b/src/electron/exception.ts
index 0065e2604..ada98d17b 100644
--- a/src/electron/exception.ts
+++ b/src/electron/exception.ts
@@ -1,4 +1,4 @@
1process.on('uncaughtException', (err) => { 1process.on('uncaughtException', err => {
2 // handle the error safely 2 // handle the error safely
3 console.error(err); 3 console.error(err);
4}); 4});
diff --git a/src/electron/ipc-api/sessionStorage.ts b/src/electron/ipc-api/sessionStorage.ts
index 3eda568a1..1ff0a51ea 100644
--- a/src/electron/ipc-api/sessionStorage.ts
+++ b/src/electron/ipc-api/sessionStorage.ts
@@ -6,7 +6,11 @@ const debug = require('debug')('Ferdi:ipcApi:sessionStorage');
6 6
7function deduceSession(serviceId: string | undefined | null): Session { 7function deduceSession(serviceId: string | undefined | null): Session {
8 if (serviceId) { 8 if (serviceId) {
9 return session.fromPartition(serviceId === TODOS_PARTITION_ID ? TODOS_PARTITION_ID : `persist:service-${serviceId}`); 9 return session.fromPartition(
10 serviceId === TODOS_PARTITION_ID
11 ? TODOS_PARTITION_ID
12 : `persist:service-${serviceId}`,
13 );
10 } 14 }
11 return session.defaultSession; 15 return session.defaultSession;
12} 16}
diff --git a/src/enforce-macos-app-location.ts b/src/enforce-macos-app-location.ts
index 0f858013d..0e6bf9ecc 100644
--- a/src/enforce-macos-app-location.ts
+++ b/src/enforce-macos-app-location.ts
@@ -12,11 +12,9 @@ export function enforceMacOSAppLocation() {
12 const clickedButtonIndex = api.dialog.showMessageBoxSync({ 12 const clickedButtonIndex = api.dialog.showMessageBoxSync({
13 type: 'error', 13 type: 'error',
14 message: 'Move to Applications folder?', 14 message: 'Move to Applications folder?',
15 detail: 'Ferdi must live in the Applications folder to be able to run correctly.', 15 detail:
16 buttons: [ 16 'Ferdi must live in the Applications folder to be able to run correctly.',
17 'Move to Applications folder', 17 buttons: ['Move to Applications folder', 'Quit Ferdi'],
18 'Quit Ferdi',
19 ],
20 defaultId: 0, 18 defaultId: 0,
21 cancelId: 1, 19 cancelId: 1,
22 }); 20 });
@@ -28,13 +26,13 @@ export function enforceMacOSAppLocation() {
28 26
29 api.app.moveToApplicationsFolder({ 27 api.app.moveToApplicationsFolder({
30 conflictHandler: conflict => { 28 conflictHandler: conflict => {
31 if (conflict === 'existsAndRunning') { // Can't replace the active version of the app 29 if (conflict === 'existsAndRunning') {
30 // Can't replace the active version of the app
32 api.dialog.showMessageBoxSync({ 31 api.dialog.showMessageBoxSync({
33 type: 'error', 32 type: 'error',
34 message: 'Another version of Ferdi is currently running. Quit it, then launch this version of the app again.', 33 message:
35 buttons: [ 34 'Another version of Ferdi is currently running. Quit it, then launch this version of the app again.',
36 'OK', 35 buttons: ['OK'],
37 ],
38 }); 36 });
39 37
40 api.app.quit(); 38 api.app.quit();
diff --git a/src/environment-remote.ts b/src/environment-remote.ts
index 192510f37..c87e89772 100644
--- a/src/environment-remote.ts
+++ b/src/environment-remote.ts
@@ -14,7 +14,13 @@ import {
14 LOCAL_TODOS_FRONTEND_URL, 14 LOCAL_TODOS_FRONTEND_URL,
15 PRODUCTION_TODOS_FRONTEND_URL, 15 PRODUCTION_TODOS_FRONTEND_URL,
16} from './config'; 16} from './config';
17import { chromeVersion, electronVersion, isWindows, nodeVersion, osArch } from './environment'; 17import {
18 chromeVersion,
19 electronVersion,
20 isWindows,
21 nodeVersion,
22 osArch,
23} from './environment';
18 24
19// @ts-expect-error Cannot find module './buildInfo.json' or its corresponding type declarations. 25// @ts-expect-error Cannot find module './buildInfo.json' or its corresponding type declarations.
20import * as buildInfo from './buildInfo.json'; 26import * as buildInfo from './buildInfo.json';
@@ -28,14 +34,20 @@ if (process.env.FERDI_APPDATA_DIR != null) {
28 app.setPath('appData', process.env.FERDI_APPDATA_DIR); 34 app.setPath('appData', process.env.FERDI_APPDATA_DIR);
29 app.setPath('userData', app.getPath('appData')); 35 app.setPath('userData', app.getPath('appData'));
30} else if (process.env.PORTABLE_EXECUTABLE_DIR != null) { 36} else if (process.env.PORTABLE_EXECUTABLE_DIR != null) {
31 app.setPath('appData', join(process.env.PORTABLE_EXECUTABLE_DIR, `${app.name}AppData`)); 37 app.setPath(
38 'appData',
39 join(process.env.PORTABLE_EXECUTABLE_DIR, `${app.name}AppData`),
40 );
32 app.setPath('userData', join(app.getPath('appData'), `${app.name}AppData`)); 41 app.setPath('userData', join(app.getPath('appData'), `${app.name}AppData`));
33} else if (isWindows && process.env.APPDATA != null) { 42} else if (isWindows && process.env.APPDATA != null) {
34 app.setPath('appData', process.env.APPDATA); 43 app.setPath('appData', process.env.APPDATA);
35 app.setPath('userData', join(app.getPath('appData'), app.name)); 44 app.setPath('userData', join(app.getPath('appData'), app.name));
36} 45}
37 46
38export const isDevMode = process.env.ELECTRON_IS_DEV !== undefined ? Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1 : !app.isPackaged; 47export const isDevMode =
48 process.env.ELECTRON_IS_DEV !== undefined
49 ? Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1
50 : !app.isPackaged;
39if (isDevMode) { 51if (isDevMode) {
40 app.setPath('userData', join(app.getPath('appData'), `${app.name}Dev`)); 52 app.setPath('userData', join(app.getPath('appData'), `${app.name}Dev`));
41} 53}
diff --git a/src/features/settingsWS/actions.ts b/src/features/settingsWS/actions.ts
index 631670c8a..03a398eb5 100755
--- a/src/features/settingsWS/actions.ts
+++ b/src/features/settingsWS/actions.ts
@@ -1,10 +1,13 @@
1import PropTypes from 'prop-types'; 1import PropTypes from 'prop-types';
2import { createActionsFromDefinitions } from '../../actions/lib/actions'; 2import { createActionsFromDefinitions } from '../../actions/lib/actions';
3 3
4export const settingsWSActions = createActionsFromDefinitions({ 4export const settingsWSActions = createActionsFromDefinitions(
5 greet: { 5 {
6 name: PropTypes.string.isRequired, 6 greet: {
7 name: PropTypes.string.isRequired,
8 },
7 }, 9 },
8}, PropTypes.checkPropTypes); 10 PropTypes.checkPropTypes,
11);
9 12
10export default settingsWSActions; 13export default settingsWSActions;
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js
index b31c7d858..1d423544b 100644
--- a/src/features/todos/components/TodosWebview.js
+++ b/src/features/todos/components/TodosWebview.js
@@ -7,14 +7,15 @@ import classnames from 'classnames';
7 7
8import { TODOS_PARTITION_ID } from '../../../config'; 8import { TODOS_PARTITION_ID } from '../../../config';
9 9
10const styles = (theme) => ({ 10const styles = theme => ({
11 root: { 11 root: {
12 background: theme.colorBackground, 12 background: theme.colorBackground,
13 position: 'relative', 13 position: 'relative',
14 borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor], 14 borderLeft: [1, 'solid', theme.todos.todosLayer.borderLeftColor],
15 zIndex: 300, 15 zIndex: 300,
16 16
17 transform: ({ isVisible, width, isTodosServiceActive }) => `translateX(${isVisible || isTodosServiceActive ? 0 : width}px)`, 17 transform: ({ isVisible, width, isTodosServiceActive }) =>
18 `translateX(${isVisible || isTodosServiceActive ? 0 : width}px)`,
18 19
19 '& webview': { 20 '& webview': {
20 height: '100%', 21 height: '100%',
@@ -79,7 +80,7 @@ class TodosWebview extends Component {
79 this.node.addEventListener('mouseleave', this.stopResize.bind(this)); 80 this.node.addEventListener('mouseleave', this.stopResize.bind(this));
80 } 81 }
81 82
82 startResize = (event) => { 83 startResize = event => {
83 this.setState({ 84 this.setState({
84 isDragging: true, 85 isDragging: true,
85 initialPos: event.clientX, 86 initialPos: event.clientX,
@@ -126,7 +127,7 @@ class TodosWebview extends Component {
126 startListeningToIpcMessages() { 127 startListeningToIpcMessages() {
127 const { handleClientMessage } = this.props; 128 const { handleClientMessage } = this.props;
128 if (!this.webview) return; 129 if (!this.webview) return;
129 this.webview.addEventListener('ipc-message', (e) => { 130 this.webview.addEventListener('ipc-message', e => {
130 // console.log(e); 131 // console.log(e);
131 handleClientMessage({ channel: e.channel, message: e.args[0] }); 132 handleClientMessage({ channel: e.channel, message: e.args[0] });
132 }); 133 });
@@ -159,7 +160,7 @@ class TodosWebview extends Component {
159 })} 160 })}
160 style={{ width: displayedWidth }} 161 style={{ width: displayedWidth }}
161 onMouseUp={() => this.stopResize()} 162 onMouseUp={() => this.stopResize()}
162 ref={(node) => { 163 ref={node => {
163 this.node = node; 164 this.node = node;
164 }} 165 }}
165 id="todos-panel" 166 id="todos-panel"
@@ -170,7 +171,7 @@ class TodosWebview extends Component {
170 left: delta, 171 left: delta,
171 ...(isDragging ? { width: 600, marginLeft: -200 } : {}), 172 ...(isDragging ? { width: 600, marginLeft: -200 } : {}),
172 }} // This hack is required as resizing with webviews beneath behaves quite bad 173 }} // This hack is required as resizing with webviews beneath behaves quite bad
173 onMouseDown={(e) => this.startResize(e)} 174 onMouseDown={e => this.startResize(e)}
174 /> 175 />
175 {isDragging && ( 176 {isDragging && (
176 <div 177 <div
@@ -188,7 +189,7 @@ class TodosWebview extends Component {
188 }} 189 }}
189 partition={TODOS_PARTITION_ID} 190 partition={TODOS_PARTITION_ID}
190 preload="./features/todos/preload.js" 191 preload="./features/todos/preload.js"
191 ref={(webview) => { 192 ref={webview => {
192 this.webview = webview ? webview.view : null; 193 this.webview = webview ? webview.view : null;
193 }} 194 }}
194 useragent={userAgent} 195 useragent={userAgent}
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js
index c2b6a5af4..536810d2d 100644
--- a/src/features/todos/containers/TodosScreen.js
+++ b/src/features/todos/containers/TodosScreen.js
@@ -10,24 +10,31 @@ import { TODOS_MIN_WIDTH } from '../../../config';
10import { todoActions } from '../actions'; 10import { todoActions } from '../actions';
11import ServicesStore from '../../../stores/ServicesStore'; 11import ServicesStore from '../../../stores/ServicesStore';
12 12
13@inject('stores', 'actions') @observer 13@inject('stores', 'actions')
14@observer
14class TodosScreen extends Component { 15class TodosScreen extends Component {
15 render() { 16 render() {
16 if (!todosStore || !todosStore.isFeatureActive || todosStore.isTodosPanelForceHidden) { 17 if (
18 !todosStore ||
19 !todosStore.isFeatureActive ||
20 todosStore.isTodosPanelForceHidden
21 ) {
17 return null; 22 return null;
18 } 23 }
19 24
20 return ( 25 return (
21 <ErrorBoundary> 26 <ErrorBoundary>
22 <TodosWebview 27 <TodosWebview
23 isTodosServiceActive={this.props.stores.services.isTodosServiceActive || false} 28 isTodosServiceActive={
29 this.props.stores.services.isTodosServiceActive || false
30 }
24 isVisible={todosStore.isTodosPanelVisible} 31 isVisible={todosStore.isTodosPanelVisible}
25 togglePanel={todoActions.toggleTodosPanel} 32 togglePanel={todoActions.toggleTodosPanel}
26 handleClientMessage={todoActions.handleClientMessage} 33 handleClientMessage={todoActions.handleClientMessage}
27 setTodosWebview={(webview) => todoActions.setTodosWebview({ webview })} 34 setTodosWebview={webview => todoActions.setTodosWebview({ webview })}
28 width={todosStore.width} 35 width={todosStore.width}
29 minWidth={TODOS_MIN_WIDTH} 36 minWidth={TODOS_MIN_WIDTH}
30 resize={(width) => todoActions.resize({ width })} 37 resize={width => todoActions.resize({ width })}
31 userAgent={todosStore.userAgent} 38 userAgent={todosStore.userAgent}
32 todoUrl={todosStore.todoUrl} 39 todoUrl={todosStore.todoUrl}
33 isTodoUrlValid={todosStore.isTodoUrlValid} 40 isTodoUrlValid={todosStore.isTodoUrlValid}
diff --git a/src/features/utils/ActionBinding.ts b/src/features/utils/ActionBinding.ts
index 787166d44..16308fae4 100644
--- a/src/features/utils/ActionBinding.ts
+++ b/src/features/utils/ActionBinding.ts
@@ -24,6 +24,5 @@ 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);
diff --git a/src/features/utils/FeatureStore.test.js b/src/features/utils/FeatureStore.test.js
index 92308bf52..1995431bd 100644
--- a/src/features/utils/FeatureStore.test.js
+++ b/src/features/utils/FeatureStore.test.js
@@ -5,9 +5,12 @@ import { createActionsFromDefinitions } from '../../actions/lib/actions';
5import { createActionBindings } from './ActionBinding'; 5import { createActionBindings } from './ActionBinding';
6import { createReactions } from '../../stores/lib/Reaction'; 6import { createReactions } from '../../stores/lib/Reaction';
7 7
8const actions = createActionsFromDefinitions({ 8const actions = createActionsFromDefinitions(
9 countUp: {}, 9 {
10}, PropTypes.checkPropTypes); 10 countUp: {},
11 },
12 PropTypes.checkPropTypes,
13);
11 14
12class TestFeatureStore extends FeatureStore { 15class TestFeatureStore extends FeatureStore {
13 @observable count = 0; 16 @observable count = 0;
@@ -15,12 +18,10 @@ class TestFeatureStore extends FeatureStore {
15 reactionInvokedCount = 0; 18 reactionInvokedCount = 0;
16 19
17 start() { 20 start() {
18 this._registerActions(createActionBindings([ 21 this._registerActions(
19 [actions.countUp, this._countUp], 22 createActionBindings([[actions.countUp, this._countUp]]),
20 ])); 23 );
21 this._registerReactions(createReactions([ 24 this._registerReactions(createReactions([this._countReaction]));
22 this._countReaction,
23 ]));
24 } 25 }
25 26
26 _countUp = () => { 27 _countUp = () => {
@@ -29,7 +30,7 @@ class TestFeatureStore extends FeatureStore {
29 30
30 _countReaction = () => { 31 _countReaction = () => {
31 this.reactionInvokedCount += 1; 32 this.reactionInvokedCount += 1;
32 } 33 };
33} 34}
34 35
35describe('FeatureStore', () => { 36describe('FeatureStore', () => {
diff --git a/src/features/workspaces/components/WorkspaceDrawerItem.js b/src/features/workspaces/components/WorkspaceDrawerItem.js
index 237f9488b..d3c9fa767 100644
--- a/src/features/workspaces/components/WorkspaceDrawerItem.js
+++ b/src/features/workspaces/components/WorkspaceDrawerItem.js
@@ -118,14 +118,12 @@ class WorkspaceDrawerItem extends Component {
118 isActive ? classes.isActiveItem : null, 118 isActive ? classes.isActiveItem : null,
119 ])} 119 ])}
120 onClick={onClick} 120 onClick={onClick}
121 onContextMenu={() => 121 onContextMenu={() => onContextMenuEditClick && contextMenu.popup()}
122 onContextMenuEditClick && contextMenu.popup()
123 }
124 data-tip={`${ 122 data-tip={`${
125 shortcutIndex <= 9 123 shortcutIndex <= 9
126 ? `(${cmdOrCtrlShortcutKey(false)}+${altKey( 124 ? `(${cmdOrCtrlShortcutKey(false)}+${altKey(
127 false, 125 false,
128 )}+${shortcutIndex})` 126 )}+${shortcutIndex})`
129 : '' 127 : ''
130 }`} 128 }`}
131 > 129 >
diff --git a/src/features/workspaces/components/WorkspacesDashboard.js b/src/features/workspaces/components/WorkspacesDashboard.js
index 78b758e7d..8ab9174d3 100644
--- a/src/features/workspaces/components/WorkspacesDashboard.js
+++ b/src/features/workspaces/components/WorkspacesDashboard.js
@@ -40,7 +40,8 @@ const messages = defineMessages({
40 }, 40 },
41 workspaceFeatureInfo: { 41 workspaceFeatureInfo: {
42 id: 'settings.workspaces.workspaceFeatureInfo', 42 id: 'settings.workspaces.workspaceFeatureInfo',
43 defaultMessage: 'Ferdi Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time. You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.', 43 defaultMessage:
44 'Ferdi Workspaces let you focus on what’s important right now. Set up different sets of services and easily switch between them at any time. You decide which services you need when and where, so we can help you stay on top of your game - or easily switch off from work whenever you want.',
44 }, 45 },
45 workspaceFeatureHeadline: { 46 workspaceFeatureHeadline: {
46 id: 'settings.workspaces.workspaceFeatureHeadline', 47 id: 'settings.workspaces.workspaceFeatureHeadline',
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js
index db2b69f99..0fa43b723 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -124,7 +124,7 @@ export default class WorkspacesStore extends FeatureStore {
124 this.isFeatureActive = false; 124 this.isFeatureActive = false;
125 } 125 }
126 126
127 filterServicesByActiveWorkspace = (services) => { 127 filterServicesByActiveWorkspace = services => {
128 const { activeWorkspace, isFeatureActive } = this; 128 const { activeWorkspace, isFeatureActive } = this;
129 if (isFeatureActive && activeWorkspace) { 129 if (isFeatureActive && activeWorkspace) {
130 return this.getWorkspaceServices(activeWorkspace); 130 return this.getWorkspaceServices(activeWorkspace);
@@ -134,14 +134,14 @@ export default class WorkspacesStore extends FeatureStore {
134 134
135 getWorkspaceServices(workspace) { 135 getWorkspaceServices(workspace) {
136 const { services } = this.stores; 136 const { services } = this.stores;
137 return workspace.services.map((id) => services.one(id)).filter((s) => !!s); 137 return workspace.services.map(id => services.one(id)).filter(s => !!s);
138 } 138 }
139 139
140 // ========== PRIVATE METHODS ========= // 140 // ========== PRIVATE METHODS ========= //
141 141
142 _getWorkspaceById = (id) => this.workspaces.find((w) => w.id === id); 142 _getWorkspaceById = id => this.workspaces.find(w => w.id === id);
143 143
144 _updateSettings = (changes) => { 144 _updateSettings = changes => {
145 localStorage.setItem('workspaces', { 145 localStorage.setItem('workspaces', {
146 ...this.settings, 146 ...this.settings,
147 ...changes, 147 ...changes,
@@ -191,9 +191,15 @@ export default class WorkspacesStore extends FeatureStore {
191 this.isSwitchingWorkspace = false; 191 this.isSwitchingWorkspace = false;
192 this.nextWorkspace = null; 192 this.nextWorkspace = null;
193 if (this.stores.settings.app.splitMode) { 193 if (this.stores.settings.app.splitMode) {
194 const serviceNames = new Set(this.getWorkspaceServices(workspace).map(service => service.name)); 194 const serviceNames = new Set(
195 for (const wrapper of document.querySelectorAll('.services__webview-wrapper')) { 195 this.getWorkspaceServices(workspace).map(service => service.name),
196 wrapper.style.display = serviceNames.has(wrapper.dataset.name) ? '' : 'none'; 196 );
197 for (const wrapper of document.querySelectorAll(
198 '.services__webview-wrapper',
199 )) {
200 wrapper.style.display = serviceNames.has(wrapper.dataset.name)
201 ? ''
202 : 'none';
197 } 203 }
198 } 204 }
199 }, 1000); 205 }, 1000);
@@ -212,7 +218,9 @@ export default class WorkspacesStore extends FeatureStore {
212 setTimeout(() => { 218 setTimeout(() => {
213 this.isSwitchingWorkspace = false; 219 this.isSwitchingWorkspace = false;
214 if (this.stores.settings.app.splitMode) { 220 if (this.stores.settings.app.splitMode) {
215 for (const wrapper of document.querySelectorAll('.services__webview-wrapper')) { 221 for (const wrapper of document.querySelectorAll(
222 '.services__webview-wrapper',
223 )) {
216 wrapper.style.display = ''; 224 wrapper.style.display = '';
217 } 225 }
218 } 226 }
@@ -262,7 +270,8 @@ export default class WorkspacesStore extends FeatureStore {
262 const activeService = this.stores.services.active; 270 const activeService = this.stores.services.active;
263 const workspaceServices = this.getWorkspaceServices(this.activeWorkspace); 271 const workspaceServices = this.getWorkspaceServices(this.activeWorkspace);
264 if (workspaceServices.length <= 0) return; 272 if (workspaceServices.length <= 0) return;
265 const isActiveServiceInWorkspace = workspaceServices.includes(activeService); 273 const isActiveServiceInWorkspace =
274 workspaceServices.includes(activeService);
266 if (!isActiveServiceInWorkspace) { 275 if (!isActiveServiceInWorkspace) {
267 this.actions.service.setActive({ 276 this.actions.service.setActive({
268 serviceId: workspaceServices[0].id, 277 serviceId: workspaceServices[0].id,
@@ -288,8 +297,10 @@ export default class WorkspacesStore extends FeatureStore {
288 const isWorkspaceSettingsRoute = router.location.pathname.includes( 297 const isWorkspaceSettingsRoute = router.location.pathname.includes(
289 WORKSPACES_ROUTES.ROOT, 298 WORKSPACES_ROUTES.ROOT,
290 ); 299 );
291 const isSwitchingToSettingsRoute = !this.isSettingsRouteActive && isWorkspaceSettingsRoute; 300 const isSwitchingToSettingsRoute =
292 const isLeavingSettingsRoute = !isWorkspaceSettingsRoute && this.isSettingsRouteActive; 301 !this.isSettingsRouteActive && isWorkspaceSettingsRoute;
302 const isLeavingSettingsRoute =
303 !isWorkspaceSettingsRoute && this.isSettingsRouteActive;
293 304
294 if (isSwitchingToSettingsRoute) { 305 if (isSwitchingToSettingsRoute) {
295 this.isSettingsRouteActive = true; 306 this.isSettingsRouteActive = true;
@@ -300,8 +311,8 @@ export default class WorkspacesStore extends FeatureStore {
300 } else if (isLeavingSettingsRoute) { 311 } else if (isLeavingSettingsRoute) {
301 this.isSettingsRouteActive = false; 312 this.isSettingsRouteActive = false;
302 if ( 313 if (
303 !this._wasDrawerOpenBeforeSettingsRoute 314 !this._wasDrawerOpenBeforeSettingsRoute &&
304 && this.isWorkspaceDrawerOpen 315 this.isWorkspaceDrawerOpen
305 ) { 316 ) {
306 workspaceActions.toggleWorkspaceDrawer(); 317 workspaceActions.toggleWorkspaceDrawer();
307 } 318 }
@@ -311,14 +322,15 @@ export default class WorkspacesStore extends FeatureStore {
311 _cleanupInvalidServiceReferences = () => { 322 _cleanupInvalidServiceReferences = () => {
312 const { services } = this.stores; 323 const { services } = this.stores;
313 const { allServicesRequest } = services; 324 const { allServicesRequest } = services;
314 const servicesHaveBeenLoaded = allServicesRequest.wasExecuted && !allServicesRequest.isError; 325 const servicesHaveBeenLoaded =
326 allServicesRequest.wasExecuted && !allServicesRequest.isError;
315 // Loop through all workspaces and remove invalid service ids (locally) 327 // Loop through all workspaces and remove invalid service ids (locally)
316 for (const workspace of this.workspaces) { 328 for (const workspace of this.workspaces) {
317 for (const serviceId of workspace.services) { 329 for (const serviceId of workspace.services) {
318 if ( 330 if (
319 servicesHaveBeenLoaded 331 servicesHaveBeenLoaded &&
320 && !services.one(serviceId) 332 !services.one(serviceId) &&
321 && serviceId !== KEEP_WS_LOADED_USID 333 serviceId !== KEEP_WS_LOADED_USID
322 ) { 334 ) {
323 workspace.services.remove(serviceId); 335 workspace.services.remove(serviceId);
324 } 336 }
diff --git a/src/helpers/array-helpers.ts b/src/helpers/array-helpers.ts
index ae5d8d99f..3f8806176 100644
--- a/src/helpers/array-helpers.ts
+++ b/src/helpers/array-helpers.ts
@@ -1,4 +1,5 @@
1export const shuffleArray = (arr: any[]) => arr 1export const shuffleArray = (arr: any[]) =>
2 .map((a) => [Math.random(), a]) 2 arr
3 .sort((a, b) => a[0] - b[0]) 3 .map(a => [Math.random(), a])
4 .map((a) => a[1]); 4 .sort((a, b) => a[0] - b[0])
5 .map(a => a[1]);
diff --git a/src/helpers/async-helpers.ts b/src/helpers/async-helpers.ts
index aae3c3928..6b1f24b5a 100644
--- a/src/helpers/async-helpers.ts
+++ b/src/helpers/async-helpers.ts
@@ -1,5 +1,3 @@
1/* eslint-disable import/prefer-default-export */
2
3export function sleep(ms: number = 0) { 1export function sleep(ms: number = 0) {
4 return new Promise((r) => setTimeout(r, ms)); 2 return new Promise(r => setTimeout(r, ms));
5} 3}
diff --git a/src/helpers/routing-helpers.ts b/src/helpers/routing-helpers.ts
index 18169f01b..46895aa6b 100644
--- a/src/helpers/routing-helpers.ts
+++ b/src/helpers/routing-helpers.ts
@@ -1,3 +1,4 @@
1import RouteParser from 'route-parser'; 1import RouteParser from 'route-parser';
2 2
3export const matchRoute = (pattern: string, path: string) => new RouteParser(pattern).match(path); 3export const matchRoute = (pattern: string, path: string) =>
4 new RouteParser(pattern).match(path);
diff --git a/src/helpers/schedule-helpers.ts b/src/helpers/schedule-helpers.ts
index 55b7c1e6f..37caffd79 100644
--- a/src/helpers/schedule-helpers.ts
+++ b/src/helpers/schedule-helpers.ts
@@ -1,17 +1,9 @@
1/* eslint-disable import/prefer-default-export */
2
3export function isInTimeframe(start: string, end: string) { 1export function isInTimeframe(start: string, end: string) {
4 const [ 2 const [startHourStr, startMinuteStr] = start.split(':');
5 startHourStr,
6 startMinuteStr,
7 ] = start.split(':');
8 const startHour = Number.parseInt(startHourStr, 10); 3 const startHour = Number.parseInt(startHourStr, 10);
9 const startMinute = Number.parseInt(startMinuteStr, 10); 4 const startMinute = Number.parseInt(startMinuteStr, 10);
10 5
11 const [ 6 const [endHourStr, endMinuteStr] = end.split(':');
12 endHourStr,
13 endMinuteStr,
14 ] = end.split(':');
15 const endHour = Number.parseInt(endHourStr, 10); 7 const endHour = Number.parseInt(endHourStr, 10);
16 const endMinute = Number.parseInt(endMinuteStr, 10); 8 const endMinute = Number.parseInt(endMinuteStr, 10);
17 9
@@ -20,46 +12,31 @@ export function isInTimeframe(start: string, end: string) {
20 12
21 // Check if the end time is before the start time (scheduled overnight) 13 // Check if the end time is before the start time (scheduled overnight)
22 // as we need to change our checks based on this 14 // as we need to change our checks based on this
23 const endBeforeStart = (startHour > endHour || (startHour === endHour && startMinute > endMinute)); 15 const endBeforeStart =
16 startHour > endHour || (startHour === endHour && startMinute > endMinute);
24 17
25 if ( 18 if (
26 // End is after start (e.g. 09:00-17:00) 19 // End is after start (e.g. 09:00-17:00)
27 !endBeforeStart 20 !endBeforeStart &&
28 // Check if past start 21 // Check if past start
29 && ((currentHour > startHour 22 (currentHour > startHour ||
30 || ( 23 (currentHour === startHour && currentMinute >= startMinute)) &&
31 currentHour === startHour 24 // Check that not past end
32 && currentMinute >= startMinute 25 (currentHour < endHour ||
33 ) 26 (currentHour === endHour && currentMinute < endMinute))
34 )
35 // Check that not past end
36 && (currentHour < endHour
37 || (
38 currentHour === endHour
39 && currentMinute < endMinute
40 )
41 ))
42 ) { 27 ) {
43 // We are in scheduled timeframe 28 // We are in scheduled timeframe
44 return true; 29 return true;
45 } 30 }
46 if ( 31 if (
47 // End is before start (e.g. 17:00-09:00) 32 // End is before start (e.g. 17:00-09:00)
48 endBeforeStart 33 endBeforeStart &&
49 // Check if past start 34 // Check if past start
50 && ((currentHour > startHour 35 (currentHour > startHour ||
51 || ( 36 (currentHour === startHour && currentMinute >= startMinute) ||
52 currentHour === startHour
53 && currentMinute >= startMinute
54 )
55 )
56 // Check that we are not past end 37 // Check that we are not past end
57 || (currentHour < endHour 38 currentHour < endHour ||
58 || ( 39 (currentHour === endHour && currentMinute < endMinute))
59 currentHour === endHour
60 && currentMinute < endMinute
61 )
62 ))
63 ) { 40 ) {
64 // We are also in scheduled timeframe 41 // We are also in scheduled timeframe
65 return true; 42 return true;
diff --git a/src/helpers/url-helpers.ts b/src/helpers/url-helpers.ts
index 1e87ecabb..135f06cbf 100644
--- a/src/helpers/url-helpers.ts
+++ b/src/helpers/url-helpers.ts
@@ -29,7 +29,10 @@ export async function openPath(folderName: string) {
29} 29}
30 30
31// TODO: Need to verify and fix/remove the skipping logic. Ideally, we should never skip this check 31// TODO: Need to verify and fix/remove the skipping logic. Ideally, we should never skip this check
32export function openExternalUrl(url: string | URL, skipValidityCheck: boolean = false) { 32export function openExternalUrl(
33 url: string | URL,
34 skipValidityCheck: boolean = false,
35) {
33 debug('Open url:', url, 'with skipValidityCheck:', skipValidityCheck); 36 debug('Open url:', url, 'with skipValidityCheck:', skipValidityCheck);
34 if (skipValidityCheck || isValidExternalURL(url)) { 37 if (skipValidityCheck || isValidExternalURL(url)) {
35 shell.openExternal(url.toString()); 38 shell.openExternal(url.toString());
diff --git a/src/internal-server/app/Controllers/Http/RecipeController.js b/src/internal-server/app/Controllers/Http/RecipeController.js
index d44839db1..1b0ac7035 100644
--- a/src/internal-server/app/Controllers/Http/RecipeController.js
+++ b/src/internal-server/app/Controllers/Http/RecipeController.js
@@ -56,7 +56,6 @@ class RecipeController {
56 let remoteResults = []; 56 let remoteResults = [];
57 // eslint-disable-next-line eqeqeq 57 // eslint-disable-next-line eqeqeq
58 if (Env.get('CONNECT_WITH_FRANZ') == 'true') { 58 if (Env.get('CONNECT_WITH_FRANZ') == 'true') {
59 // eslint-disable-line eqeqeq
60 remoteResults = JSON.parse( 59 remoteResults = JSON.parse(
61 await ( 60 await (
62 await fetch( 61 await fetch(
@@ -112,7 +111,6 @@ class RecipeController {
112 } 111 }
113 // eslint-disable-next-line eqeqeq 112 // eslint-disable-next-line eqeqeq
114 if (Env.get('CONNECT_WITH_FRANZ') == 'true') { 113 if (Env.get('CONNECT_WITH_FRANZ') == 'true') {
115 // eslint-disable-line eqeqeq
116 return response.redirect(`${RECIPES_URL}/download/${service}`); 114 return response.redirect(`${RECIPES_URL}/download/${service}`);
117 } 115 }
118 return response.status(400).send({ 116 return response.status(400).send({
diff --git a/src/internal-server/app/Controllers/Http/ServiceController.js b/src/internal-server/app/Controllers/Http/ServiceController.js
index 133473b68..dedb5a12b 100644
--- a/src/internal-server/app/Controllers/Http/ServiceController.js
+++ b/src/internal-server/app/Controllers/Http/ServiceController.js
@@ -36,7 +36,7 @@ class ServiceController {
36 } while ( 36 } while (
37 (await Service.query().where('serviceId', serviceId).fetch()).rows 37 (await Service.query().where('serviceId', serviceId).fetch()).rows
38 .length > 0 38 .length > 0
39 ); // eslint-disable-line no-await-in-loop 39 );
40 40
41 await Service.create({ 41 await Service.create({
42 serviceId, 42 serviceId,
diff --git a/src/internal-server/app/Controllers/Http/UserController.js b/src/internal-server/app/Controllers/Http/UserController.js
index 25b5277bd..2ecc8241c 100644
--- a/src/internal-server/app/Controllers/Http/UserController.js
+++ b/src/internal-server/app/Controllers/Http/UserController.js
@@ -171,7 +171,6 @@ class UserController {
171 return response.status(401).send(errorMessage); 171 return response.status(401).send(errorMessage);
172 } 172 }
173 173
174 // eslint-disable-next-line prefer-destructuring
175 token = content.token; 174 token = content.token;
176 } catch (error) { 175 } catch (error) {
177 return response.status(401).send({ 176 return response.status(401).send({
@@ -300,7 +299,7 @@ class UserController {
300 } while ( 299 } while (
301 (await Workspace.query().where('workspaceId', newWorkspaceId).fetch()) 300 (await Workspace.query().where('workspaceId', newWorkspaceId).fetch())
302 .rows.length > 0 301 .rows.length > 0
303 ); // eslint-disable-line no-await-in-loop 302 );
304 303
305 if ( 304 if (
306 workspace.services && 305 workspace.services &&
@@ -340,7 +339,7 @@ class UserController {
340 } while ( 339 } while (
341 (await Service.query().where('serviceId', newServiceId).fetch()).rows 340 (await Service.query().where('serviceId', newServiceId).fetch()).rows
342 .length > 0 341 .length > 0
343 ); // eslint-disable-line no-await-in-loop 342 );
344 343
345 // store the old serviceId as the key for future lookup 344 // store the old serviceId as the key for future lookup
346 serviceIdTranslation[service.serviceId] = newServiceId; 345 serviceIdTranslation[service.serviceId] = newServiceId;
diff --git a/src/internal-server/app/Controllers/Http/WorkspaceController.js b/src/internal-server/app/Controllers/Http/WorkspaceController.js
index 9d461135e..528721f13 100644
--- a/src/internal-server/app/Controllers/Http/WorkspaceController.js
+++ b/src/internal-server/app/Controllers/Http/WorkspaceController.js
@@ -27,7 +27,7 @@ class WorkspaceController {
27 } while ( 27 } while (
28 (await Workspace.query().where('workspaceId', workspaceId).fetch()).rows 28 (await Workspace.query().where('workspaceId', workspaceId).fetch()).rows
29 .length > 0 29 .length > 0
30 ); // eslint-disable-line no-await-in-loop 30 );
31 31
32 const order = (await Workspace.all()).rows.length; 32 const order = (await Workspace.all()).rows.length;
33 const { name } = data; 33 const { name } = data;
diff --git a/src/internal-server/config/app.js b/src/internal-server/config/app.js
index 0a1644932..379190734 100644
--- a/src/internal-server/config/app.js
+++ b/src/internal-server/config/app.js
@@ -2,7 +2,6 @@
2const Env = use('Env'); 2const Env = use('Env');
3 3
4module.exports = { 4module.exports = {
5
6 /* 5 /*
7 |-------------------------------------------------------------------------- 6 |--------------------------------------------------------------------------
8 | Application Name 7 | Application Name
diff --git a/src/internal-server/config/bodyParser.js b/src/internal-server/config/bodyParser.js
index 8a5406f9e..ef2eedf40 100644
--- a/src/internal-server/config/bodyParser.js
+++ b/src/internal-server/config/bodyParser.js
@@ -58,9 +58,7 @@ module.exports = {
58 | 58 |
59 */ 59 */
60 raw: { 60 raw: {
61 types: [ 61 types: ['text/*'],
62 'text/*',
63 ],
64 }, 62 },
65 63
66 /* 64 /*
@@ -72,9 +70,7 @@ module.exports = {
72 | 70 |
73 */ 71 */
74 form: { 72 form: {
75 types: [ 73 types: ['application/x-www-form-urlencoded'],
76 'application/x-www-form-urlencoded',
77 ],
78 }, 74 },
79 75
80 /* 76 /*
@@ -86,9 +82,7 @@ module.exports = {
86 | 82 |
87 */ 83 */
88 files: { 84 files: {
89 types: [ 85 types: ['multipart/form-data'],
90 'multipart/form-data',
91 ],
92 86
93 /* 87 /*
94 |-------------------------------------------------------------------------- 88 |--------------------------------------------------------------------------
diff --git a/src/internal-server/database/migrations/1503250034279_user.js b/src/internal-server/database/migrations/1503250034279_user.js
index 80b49020a..d502e4fa0 100644
--- a/src/internal-server/database/migrations/1503250034279_user.js
+++ b/src/internal-server/database/migrations/1503250034279_user.js
@@ -3,7 +3,7 @@ const Schema = use('Schema');
3 3
4class UserSchema extends Schema { 4class UserSchema extends Schema {
5 up() { 5 up() {
6 this.create('users', (table) => { 6 this.create('users', table => {
7 table.increments(); 7 table.increments();
8 table.json('settings'); 8 table.json('settings');
9 table.timestamps(); 9 table.timestamps();
diff --git a/src/internal-server/database/migrations/1566385379883_service_schema.js b/src/internal-server/database/migrations/1566385379883_service_schema.js
index d887ef193..d8087248f 100644
--- a/src/internal-server/database/migrations/1566385379883_service_schema.js
+++ b/src/internal-server/database/migrations/1566385379883_service_schema.js
@@ -3,7 +3,7 @@ const Schema = use('Schema');
3 3
4class ServiceSchema extends Schema { 4class ServiceSchema extends Schema {
5 up() { 5 up() {
6 this.create('services', (table) => { 6 this.create('services', table => {
7 table.increments(); 7 table.increments();
8 table.string('serviceId', 80).notNullable(); 8 table.string('serviceId', 80).notNullable();
9 table.string('name', 80).notNullable(); 9 table.string('name', 80).notNullable();
diff --git a/src/internal-server/database/migrations/1566554231482_recipe_schema.js b/src/internal-server/database/migrations/1566554231482_recipe_schema.js
index 514d57600..41bebdacb 100644
--- a/src/internal-server/database/migrations/1566554231482_recipe_schema.js
+++ b/src/internal-server/database/migrations/1566554231482_recipe_schema.js
@@ -3,7 +3,7 @@ const Schema = use('Schema');
3 3
4class RecipeSchema extends Schema { 4class RecipeSchema extends Schema {
5 up() { 5 up() {
6 this.create('recipes', (table) => { 6 this.create('recipes', table => {
7 table.increments(); 7 table.increments();
8 table.string('name', 80).notNullable(); 8 table.string('name', 80).notNullable();
9 table.string('recipeId', 254).notNullable().unique(); 9 table.string('recipeId', 254).notNullable().unique();
diff --git a/src/internal-server/database/migrations/1566554359294_workspace_schema.js b/src/internal-server/database/migrations/1566554359294_workspace_schema.js
index 421a406b5..3e5385f45 100644
--- a/src/internal-server/database/migrations/1566554359294_workspace_schema.js
+++ b/src/internal-server/database/migrations/1566554359294_workspace_schema.js
@@ -3,7 +3,7 @@ const Schema = use('Schema');
3 3
4class WorkspaceSchema extends Schema { 4class WorkspaceSchema extends Schema {
5 up() { 5 up() {
6 this.create('workspaces', (table) => { 6 this.create('workspaces', table => {
7 table.increments(); 7 table.increments();
8 table.string('workspaceId', 80).notNullable().unique(); 8 table.string('workspaceId', 80).notNullable().unique();
9 table.string('name', 80).notNullable(); 9 table.string('name', 80).notNullable();
diff --git a/src/internal-server/start/app.js b/src/internal-server/start/app.js
index 8b1a49f57..7ca544085 100644
--- a/src/internal-server/start/app.js
+++ b/src/internal-server/start/app.js
@@ -28,9 +28,7 @@ const providers = [
28| Providers for migrations, tests etc. 28| Providers for migrations, tests etc.
29| 29|
30*/ 30*/
31const aceProviders = [ 31const aceProviders = ['@adonisjs/lucid/providers/MigrationsProvider'];
32 '@adonisjs/lucid/providers/MigrationsProvider',
33];
34 32
35/* 33/*
36|-------------------------------------------------------------------------- 34|--------------------------------------------------------------------------
@@ -57,5 +55,8 @@ const aliases = {};
57const commands = []; 55const commands = [];
58 56
59module.exports = { 57module.exports = {
60 providers, aceProviders, aliases, commands, 58 providers,
59 aceProviders,
60 aliases,
61 commands,
61}; 62};
diff --git a/src/jsUtils.ts b/src/jsUtils.ts
index b1baad7c5..d7ea4eb40 100644
--- a/src/jsUtils.ts
+++ b/src/jsUtils.ts
@@ -1,3 +1,14 @@
1export const ifUndefinedString = (source: string | undefined | null, defaultValue: string): string => (source !== undefined && source !== null ? source : defaultValue); 1export const ifUndefinedString = (
2export const ifUndefinedBoolean = (source: boolean | undefined | null, defaultValue: boolean): boolean => Boolean(source !== undefined && source !== null ? source : defaultValue); 2 source: string | undefined | null,
3export const ifUndefinedNumber = (source: number | undefined | null, defaultValue: number): number => Number(source !== undefined && source !== null ? source : defaultValue); 3 defaultValue: string,
4): string => (source !== undefined && source !== null ? source : defaultValue);
5export const ifUndefinedBoolean = (
6 source: boolean | undefined | null,
7 defaultValue: boolean,
8): boolean =>
9 Boolean(source !== undefined && source !== null ? source : defaultValue);
10export const ifUndefinedNumber = (
11 source: number | undefined | null,
12 defaultValue: number,
13): number =>
14 Number(source !== undefined && source !== null ? source : defaultValue);
diff --git a/src/lib/Tray.js b/src/lib/Tray.js
index 7360611cd..e7afc3552 100644
--- a/src/lib/Tray.js
+++ b/src/lib/Tray.js
@@ -1,5 +1,11 @@
1import { 1import {
2 app, Menu, nativeImage, nativeTheme, systemPreferences, Tray, ipcMain, 2 app,
3 Menu,
4 nativeImage,
5 nativeTheme,
6 systemPreferences,
7 Tray,
8 ipcMain,
3} from 'electron'; 9} from 'electron';
4import { join } from 'path'; 10import { join } from 'path';
5import macosVersion from 'macos-version'; 11import macosVersion from 'macos-version';
@@ -65,7 +71,9 @@ export default class TrayIcon {
65 71
66 if (appSettings.type === 'app') { 72 if (appSettings.type === 'app') {
67 const { isAppMuted } = appSettings.data; 73 const { isAppMuted } = appSettings.data;
68 this.trayMenuTemplate[1].label = isAppMuted ? 'Enable Notifications && Audio' : 'Disable Notifications && Audio'; 74 this.trayMenuTemplate[1].label = isAppMuted
75 ? 'Enable Notifications && Audio'
76 : 'Disable Notifications && Audio';
69 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate); 77 this.trayMenu = Menu.buildFromTemplate(this.trayMenuTemplate);
70 if (isLinux) { 78 if (isLinux) {
71 this.trayIcon.setContextMenu(this.trayMenu); 79 this.trayIcon.setContextMenu(this.trayMenu);
@@ -108,9 +116,12 @@ export default class TrayIcon {
108 } 116 }
109 117
110 if (isMac) { 118 if (isMac) {
111 this.themeChangeSubscriberId = systemPreferences.subscribeNotification('AppleInterfaceThemeChangedNotification', () => { 119 this.themeChangeSubscriberId = systemPreferences.subscribeNotification(
112 this._refreshIcon(); 120 'AppleInterfaceThemeChangedNotification',
113 }); 121 () => {
122 this._refreshIcon();
123 },
124 );
114 } 125 }
115 } 126 }
116 127
@@ -150,7 +161,8 @@ export default class TrayIcon {
150 _getAssetFromIndicator(indicator) { 161 _getAssetFromIndicator(indicator) {
151 if (indicator === '•') { 162 if (indicator === '•') {
152 return INDICATOR_TRAY_INDIRECT; 163 return INDICATOR_TRAY_INDIRECT;
153 } if (indicator !== 0) { 164 }
165 if (indicator !== 0) {
154 return INDICATOR_TRAY_UNREAD; 166 return INDICATOR_TRAY_UNREAD;
155 } 167 }
156 return INDICATOR_TRAY_PLAIN; 168 return INDICATOR_TRAY_PLAIN;
@@ -159,11 +171,16 @@ export default class TrayIcon {
159 _refreshIcon() { 171 _refreshIcon() {
160 if (!this.trayIcon) return; 172 if (!this.trayIcon) return;
161 173
162 this.trayIcon.setImage(this._getAsset('tray', this._getAssetFromIndicator(this.indicator))); 174 this.trayIcon.setImage(
175 this._getAsset('tray', this._getAssetFromIndicator(this.indicator)),
176 );
163 177
164 if (isMac) { 178 if (isMac) {
165 this.trayIcon.setPressedImage( 179 this.trayIcon.setPressedImage(
166 this._getAsset('tray', `${this._getAssetFromIndicator(this.indicator)}-active`), 180 this._getAsset(
181 'tray',
182 `${this._getAssetFromIndicator(this.indicator)}-active`,
183 ),
167 ); 184 );
168 } 185 }
169 } 186 }
@@ -171,12 +188,24 @@ export default class TrayIcon {
171 _getAsset(type, asset) { 188 _getAsset(type, asset) {
172 let { platform } = process; 189 let { platform } = process;
173 190
174 if (isMac && (nativeTheme.shouldUseDarkColors || macosVersion.isGreaterThanOrEqualTo('11'))) { 191 if (
192 isMac &&
193 (nativeTheme.shouldUseDarkColors ||
194 macosVersion.isGreaterThanOrEqualTo('11'))
195 ) {
175 platform = `${platform}-dark`; 196 platform = `${platform}-dark`;
176 } 197 }
177 198
178 return nativeImage.createFromPath(join( 199 return nativeImage.createFromPath(
179 __dirname, '..', 'assets', 'images', type, platform, `${asset}.${FILE_EXTENSION}`, 200 join(
180 )); 201 __dirname,
202 '..',
203 'assets',
204 'images',
205 type,
206 platform,
207 `${asset}.${FILE_EXTENSION}`,
208 ),
209 );
181 } 210 }
182} 211}
diff --git a/src/models/Recipe.ts b/src/models/Recipe.ts
index 859c75df0..e45977f24 100644
--- a/src/models/Recipe.ts
+++ b/src/models/Recipe.ts
@@ -1,10 +1,7 @@
1import semver from 'semver'; 1import semver from 'semver';
2import { pathExistsSync } from 'fs-extra'; 2import { pathExistsSync } from 'fs-extra';
3import { join } from 'path'; 3import { join } from 'path';
4import { 4import { ifUndefinedString, ifUndefinedBoolean } from '../jsUtils';
5 ifUndefinedString,
6 ifUndefinedBoolean,
7} from '../jsUtils';
8 5
9interface IRecipe { 6interface IRecipe {
10 id: string; 7 id: string;
@@ -75,7 +72,8 @@ export default class Recipe {
75 72
76 message: string = ''; 73 message: string = '';
77 74
78 allowFavoritesDelineationInUnreadCount: boolean = DEFAULT_RECIPE_SETTINGS.allowFavoritesDelineationInUnreadCount; 75 allowFavoritesDelineationInUnreadCount: boolean =
76 DEFAULT_RECIPE_SETTINGS.allowFavoritesDelineationInUnreadCount;
79 77
80 disablewebsecurity: boolean = DEFAULT_RECIPE_SETTINGS.disablewebsecurity; 78 disablewebsecurity: boolean = DEFAULT_RECIPE_SETTINGS.disablewebsecurity;
81 79
@@ -98,7 +96,9 @@ export default class Recipe {
98 } 96 }
99 97
100 if (!semver.valid(data.version)) { 98 if (!semver.valid(data.version)) {
101 throw new Error(`Version ${data.version} of recipe '${data.name}' is not a valid semver version`); 99 throw new Error(
100 `Version ${data.version} of recipe '${data.name}' is not a valid semver version`,
101 );
102 } 102 }
103 103
104 // from the recipe 104 // from the recipe
@@ -106,19 +106,52 @@ export default class Recipe {
106 this.name = ifUndefinedString(data.name, this.name); 106 this.name = ifUndefinedString(data.name, this.name);
107 this.version = ifUndefinedString(data.version, this.version); 107 this.version = ifUndefinedString(data.version, this.version);
108 this.aliases = data.aliases || this.aliases; 108 this.aliases = data.aliases || this.aliases;
109 this.serviceURL = ifUndefinedString(data.config.serviceURL, this.serviceURL); 109 this.serviceURL = ifUndefinedString(
110 this.hasDirectMessages = ifUndefinedBoolean(data.config.hasDirectMessages, this.hasDirectMessages); 110 data.config.serviceURL,
111 this.hasIndirectMessages = ifUndefinedBoolean(data.config.hasIndirectMessages, this.hasIndirectMessages); 111 this.serviceURL,
112 this.hasNotificationSound = ifUndefinedBoolean(data.config.hasNotificationSound, this.hasNotificationSound); 112 );
113 this.hasDirectMessages = ifUndefinedBoolean(
114 data.config.hasDirectMessages,
115 this.hasDirectMessages,
116 );
117 this.hasIndirectMessages = ifUndefinedBoolean(
118 data.config.hasIndirectMessages,
119 this.hasIndirectMessages,
120 );
121 this.hasNotificationSound = ifUndefinedBoolean(
122 data.config.hasNotificationSound,
123 this.hasNotificationSound,
124 );
113 this.hasTeamId = ifUndefinedBoolean(data.config.hasTeamId, this.hasTeamId); 125 this.hasTeamId = ifUndefinedBoolean(data.config.hasTeamId, this.hasTeamId);
114 this.hasCustomUrl = ifUndefinedBoolean(data.config.hasCustomUrl, this.hasCustomUrl); 126 this.hasCustomUrl = ifUndefinedBoolean(
115 this.hasHostedOption = ifUndefinedBoolean(data.config.hasHostedOption, this.hasHostedOption); 127 data.config.hasCustomUrl,
116 this.urlInputPrefix = ifUndefinedString(data.config.urlInputPrefix, this.urlInputPrefix); 128 this.hasCustomUrl,
117 this.urlInputSuffix = ifUndefinedString(data.config.urlInputSuffix, this.urlInputSuffix); 129 );
118 this.disablewebsecurity = ifUndefinedBoolean(data.config.disablewebsecurity, this.disablewebsecurity); 130 this.hasHostedOption = ifUndefinedBoolean(
119 this.autoHibernate = ifUndefinedBoolean(data.config.autoHibernate, this.autoHibernate); 131 data.config.hasHostedOption,
132 this.hasHostedOption,
133 );
134 this.urlInputPrefix = ifUndefinedString(
135 data.config.urlInputPrefix,
136 this.urlInputPrefix,
137 );
138 this.urlInputSuffix = ifUndefinedString(
139 data.config.urlInputSuffix,
140 this.urlInputSuffix,
141 );
142 this.disablewebsecurity = ifUndefinedBoolean(
143 data.config.disablewebsecurity,
144 this.disablewebsecurity,
145 );
146 this.autoHibernate = ifUndefinedBoolean(
147 data.config.autoHibernate,
148 this.autoHibernate,
149 );
120 this.message = ifUndefinedString(data.config.message, this.message); 150 this.message = ifUndefinedString(data.config.message, this.message);
121 this.allowFavoritesDelineationInUnreadCount = ifUndefinedBoolean(data.config.allowFavoritesDelineationInUnreadCount, this.allowFavoritesDelineationInUnreadCount); 151 this.allowFavoritesDelineationInUnreadCount = ifUndefinedBoolean(
152 data.config.allowFavoritesDelineationInUnreadCount,
153 this.allowFavoritesDelineationInUnreadCount,
154 );
122 155
123 // computed 156 // computed
124 this.path = data.path; 157 this.path = data.path;
diff --git a/src/models/User.ts b/src/models/User.ts
index a04d46d3c..571f1f847 100644
--- a/src/models/User.ts
+++ b/src/models/User.ts
@@ -59,7 +59,8 @@ export default class User {
59 this.beta = data.beta || this.beta; 59 this.beta = data.beta || this.beta;
60 this.locale = data.locale || this.locale; 60 this.locale = data.locale || this.locale;
61 61
62 this.isSubscriptionOwner = data.isSubscriptionOwner || this.isSubscriptionOwner; 62 this.isSubscriptionOwner =
63 data.isSubscriptionOwner || this.isSubscriptionOwner;
63 64
64 this.team = data.team || this.team; 65 this.team = data.team || this.team;
65 } 66 }
diff --git a/src/models/UserAgent.js b/src/models/UserAgent.js
index 33bf9d072..02ff97db1 100644
--- a/src/models/UserAgent.js
+++ b/src/models/UserAgent.js
@@ -63,8 +63,12 @@ export default class UserAgent {
63 } 63 }
64 64
65 @computed get userAgent() { 65 @computed get userAgent() {
66 return this.serviceUserAgentPref 66 return (
67 || (this.chromelessUserAgent ? this.userAgentWithoutChromeVersion : this.defaultUserAgent); 67 this.serviceUserAgentPref ||
68 (this.chromelessUserAgent
69 ? this.userAgentWithoutChromeVersion
70 : this.defaultUserAgent)
71 );
68 } 72 }
69 73
70 @action setWebviewReference(webview) { 74 @action setWebviewReference(webview) {
diff --git a/src/stores/RecipePreviewsStore.js b/src/stores/RecipePreviewsStore.js
index f4e39306c..e01e8fc6f 100644
--- a/src/stores/RecipePreviewsStore.js
+++ b/src/stores/RecipePreviewsStore.js
@@ -5,9 +5,15 @@ import CachedRequest from './lib/CachedRequest';
5import Request from './lib/Request'; 5import Request from './lib/Request';
6 6
7export default class RecipePreviewsStore extends Store { 7export default class RecipePreviewsStore extends Store {
8 @observable allRecipePreviewsRequest = new CachedRequest(this.api.recipePreviews, 'all'); 8 @observable allRecipePreviewsRequest = new CachedRequest(
9 this.api.recipePreviews,
10 'all',
11 );
9 12
10 @observable searchRecipePreviewsRequest = new Request(this.api.recipePreviews, 'search'); 13 @observable searchRecipePreviewsRequest = new Request(
14 this.api.recipePreviews,
15 'search',
16 );
11 17
12 constructor(...args) { 18 constructor(...args) {
13 super(...args); 19 super(...args);
@@ -25,7 +31,7 @@ export default class RecipePreviewsStore extends Store {
25 } 31 }
26 32
27 @computed get dev() { 33 @computed get dev() {
28 return this.stores.recipes.all.filter((r) => r.local); 34 return this.stores.recipes.all.filter(r => r.local);
29 } 35 }
30 36
31 // Actions 37 // Actions
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index e27567e8f..5ed9e3534 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -394,7 +394,7 @@ export default class ServicesStore extends Store {
394 } 394 }
395 395
396 // set default values for serviceData 396 // set default values for serviceData
397 // eslint-disable-next-line prefer-object-spread 397
398 // TODO: How is this different from the defaults of the recipe in 'src/models/Recipe' file? 398 // TODO: How is this different from the defaults of the recipe in 'src/models/Recipe' file?
399 serviceData = { 399 serviceData = {
400 isEnabled: true, 400 isEnabled: true,
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.js
index ec80fee7c..ac9356404 100644
--- a/src/stores/SettingsStore.js
+++ b/src/stores/SettingsStore.js
@@ -2,7 +2,11 @@ import { ipcRenderer } from 'electron';
2import { getCurrentWindow } from '@electron/remote'; 2import { getCurrentWindow } from '@electron/remote';
3import { action, computed, observable, reaction } from 'mobx'; 3import { action, computed, observable, reaction } from 'mobx';
4import localStorage from 'mobx-localstorage'; 4import localStorage from 'mobx-localstorage';
5import { DEFAULT_APP_SETTINGS, FILE_SYSTEM_SETTINGS_TYPES, LOCAL_SERVER } from '../config'; 5import {
6 DEFAULT_APP_SETTINGS,
7 FILE_SYSTEM_SETTINGS_TYPES,
8 LOCAL_SERVER,
9} from '../config';
6import { hash } from '../helpers/password-helpers'; 10import { hash } from '../helpers/password-helpers';
7import Request from './lib/Request'; 11import Request from './lib/Request';
8import Store from './lib/Store'; 12import Store from './lib/Store';
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.js
index 9f222d2d3..9a5d8cb30 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.js
@@ -273,13 +273,11 @@ export default class UserStore extends Store {
273 273
274 // Install recipes 274 // Install recipes
275 for (const recipe of recipes) { 275 for (const recipe of recipes) {
276 // eslint-disable-line no-unused-vars
277 // eslint-disable-next-line no-await-in-loop 276 // eslint-disable-next-line no-await-in-loop
278 await this.stores.recipes._install({ recipeId: recipe }); 277 await this.stores.recipes._install({ recipeId: recipe });
279 } 278 }
280 279
281 for (const service of services) { 280 for (const service of services) {
282 // eslint-disable-line no-unused-vars
283 this.actions.service.createFromLegacyService({ 281 this.actions.service.createFromLegacyService({
284 data: service, 282 data: service,
285 }); 283 });
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.js
index 39f32729a..65871ea17 100644
--- a/src/stores/lib/Request.js
+++ b/src/stores/lib/Request.js
@@ -38,42 +38,56 @@ export default class Request {
38 if (this._isWaitingForResponse) return this; 38 if (this._isWaitingForResponse) return this;
39 39
40 if (!this._api[this._method]) { 40 if (!this._api[this._method]) {
41 throw new Error(`Missing method <${this._method}> on api object:`, this._api); 41 throw new Error(
42 `Missing method <${this._method}> on api object:`,
43 this._api,
44 );
42 } 45 }
43 46
44 // This timeout is necessary to avoid warnings from mobx 47 // This timeout is necessary to avoid warnings from mobx
45 // regarding triggering actions as side-effect of getters 48 // regarding triggering actions as side-effect of getters
46 setTimeout(action(() => { 49 setTimeout(
47 this.isExecuting = true; 50 action(() => {
48 }), 0); 51 this.isExecuting = true;
52 }),
53 0,
54 );
49 55
50 // Issue api call & save it as promise that is handled to update the results of the operation 56 // Issue api call & save it as promise that is handled to update the results of the operation
51 this._promise = new Promise((resolve, reject) => { 57 this._promise = new Promise((resolve, reject) => {
52 this._api[this._method](...callArgs) 58 this._api[this._method](...callArgs)
53 .then((result) => { 59 .then(result => {
54 setTimeout(action(() => { 60 setTimeout(
55 this.result = result; 61 action(() => {
56 if (this._currentApiCall) this._currentApiCall.result = result; 62 this.result = result;
57 this.isExecuting = false; 63 if (this._currentApiCall) this._currentApiCall.result = result;
58 this.isError = false; 64 this.isExecuting = false;
59 this.wasExecuted = true; 65 this.isError = false;
60 this._isWaitingForResponse = false; 66 this.wasExecuted = true;
61 this._triggerHooks(); 67 this._isWaitingForResponse = false;
62 resolve(result); 68 this._triggerHooks();
63 }), 1); 69 resolve(result);
70 }),
71 1,
72 );
64 return result; 73 return result;
65 }) 74 })
66 .catch(action((error) => { 75 .catch(
67 setTimeout(action(() => { 76 action(error => {
68 this.error = error; 77 setTimeout(
69 this.isExecuting = false; 78 action(() => {
70 this.isError = true; 79 this.error = error;
71 this.wasExecuted = true; 80 this.isExecuting = false;
72 this._isWaitingForResponse = false; 81 this.isError = true;
73 this._triggerHooks(); 82 this.wasExecuted = true;
74 reject(error); 83 this._isWaitingForResponse = false;
75 }), 1); 84 this._triggerHooks();
76 })); 85 reject(error);
86 }),
87 1,
88 );
89 }),
90 );
77 }); 91 });
78 92
79 this._isWaitingForResponse = true; 93 this._isWaitingForResponse = true;
@@ -89,7 +103,11 @@ export default class Request {
89 retry = () => this.reload(); 103 retry = () => this.reload();
90 104
91 isExecutingWithArgs(...args) { 105 isExecutingWithArgs(...args) {
92 return this.isExecuting && this._currentApiCall && isEqual(this._currentApiCall.args, args); 106 return (
107 this.isExecuting &&
108 this._currentApiCall &&
109 isEqual(this._currentApiCall.args, args)
110 );
93 } 111 }
94 112
95 @computed get isExecutingFirstTime() { 113 @computed get isExecutingFirstTime() {
@@ -97,12 +115,18 @@ export default class Request {
97 } 115 }
98 116
99 then(...args) { 117 then(...args) {
100 if (!this._promise) throw new Error('You have to call Request::execute before you can access it as promise'); 118 if (!this._promise)
119 throw new Error(
120 'You have to call Request::execute before you can access it as promise',
121 );
101 return this._promise.then(...args); 122 return this._promise.then(...args);
102 } 123 }
103 124
104 catch(...args) { 125 catch(...args) {
105 if (!this._promise) throw new Error('You have to call Request::execute before you can access it as promise'); 126 if (!this._promise)
127 throw new Error(
128 'You have to call Request::execute before you can access it as promise',
129 );
106 return this._promise.catch(...args); 130 return this._promise.catch(...args);
107 } 131 }
108 132
diff --git a/src/stores/lib/Store.js b/src/stores/lib/Store.js
index b39070ce8..a867c3a46 100644
--- a/src/stores/lib/Store.js
+++ b/src/stores/lib/Store.js
@@ -28,7 +28,8 @@ export default class Store {
28 } 28 }
29 29
30 registerReactions(reactions) { 30 registerReactions(reactions) {
31 for (const reaction of reactions) this._reactions.push(new Reaction(reaction)); 31 for (const reaction of reactions)
32 this._reactions.push(new Reaction(reaction));
32 } 33 }
33 34
34 setup() {} 35 setup() {}
diff --git a/src/webview/badge.ts b/src/webview/badge.ts
index 8e8b66c0c..fb696723d 100644
--- a/src/webview/badge.ts
+++ b/src/webview/badge.ts
@@ -3,7 +3,7 @@ import { ipcRenderer } from 'electron';
3const debug = require('debug')('Ferdi:Plugin:BadgeHandler'); 3const debug = require('debug')('Ferdi:Plugin:BadgeHandler');
4 4
5export class BadgeHandler { 5export class BadgeHandler {
6 countCache: { direct: number; indirect: number; }; 6 countCache: { direct: number; indirect: number };
7 7
8 constructor() { 8 constructor() {
9 this.countCache = { 9 this.countCache = {
@@ -26,14 +26,19 @@ export class BadgeHandler {
26 return Math.max(adjustedNumber, 0); 26 return Math.max(adjustedNumber, 0);
27 } 27 }
28 28
29 setBadge(direct: string | number | undefined | null, indirect: string | number | undefined | null) { 29 setBadge(
30 direct: string | number | undefined | null,
31 indirect: string | number | undefined | null,
32 ) {
30 const count = { 33 const count = {
31 direct: this.safeParseInt(direct), 34 direct: this.safeParseInt(direct),
32 indirect: this.safeParseInt(indirect), 35 indirect: this.safeParseInt(indirect),
33 }; 36 };
34 37
35 if (this.countCache.direct.toString() === count.direct.toString() 38 if (
36 && this.countCache.indirect.toString() === count.indirect.toString()) { 39 this.countCache.direct.toString() === count.direct.toString() &&
40 this.countCache.indirect.toString() === count.indirect.toString()
41 ) {
37 return; 42 return;
38 } 43 }
39 44
diff --git a/src/webview/contextMenuBuilder.ts b/src/webview/contextMenuBuilder.ts
index fda5fa8b8..7b8c6cb2d 100644
--- a/src/webview/contextMenuBuilder.ts
+++ b/src/webview/contextMenuBuilder.ts
@@ -6,7 +6,7 @@
6 * 6 *
7 * Source: https://github.com/electron-userland/electron-spellchecker/blob/master/src/context-menu-builder.js 7 * Source: https://github.com/electron-userland/electron-spellchecker/blob/master/src/context-menu-builder.js
8 */ 8 */
9// eslint-disable-next-line no-unused-vars 9
10import { clipboard, ipcRenderer, nativeImage, WebContents } from 'electron'; 10import { clipboard, ipcRenderer, nativeImage, WebContents } from 'electron';
11import { Menu, MenuItem } from '@electron/remote'; 11import { Menu, MenuItem } from '@electron/remote';
12import { cmdOrCtrlShortcutKey, isMac } from '../environment'; 12import { cmdOrCtrlShortcutKey, isMac } from '../environment';
@@ -311,7 +311,7 @@ export class ContextMenuBuilder {
311 menu.append( 311 menu.append(
312 new MenuItem({ 312 new MenuItem({
313 label: suggestion, 313 label: suggestion,
314 // eslint-disable-next-line no-loop-func 314
315 click: () => webContents.replaceMisspelling(suggestion), 315 click: () => webContents.replaceMisspelling(suggestion),
316 }), 316 }),
317 ); 317 );
diff --git a/src/webview/spellchecker.ts b/src/webview/spellchecker.ts
index 468a1b4ae..ee70589d5 100644
--- a/src/webview/spellchecker.ts
+++ b/src/webview/spellchecker.ts
@@ -5,7 +5,11 @@ import { isMac } from '../environment';
5const debug = require('debug')('Ferdi:spellchecker'); 5const debug = require('debug')('Ferdi:spellchecker');
6 6
7export function getSpellcheckerLocaleByFuzzyIdentifier(identifier: string) { 7export function getSpellcheckerLocaleByFuzzyIdentifier(identifier: string) {
8 const locales = Object.keys(SPELLCHECKER_LOCALES).filter((key) => key.toLocaleLowerCase() === identifier.toLowerCase() || key.split('-')[0] === identifier.toLowerCase()); 8 const locales = Object.keys(SPELLCHECKER_LOCALES).filter(
9 key =>
10 key.toLocaleLowerCase() === identifier.toLowerCase() ||
11 key.split('-')[0] === identifier.toLowerCase(),
12 );
9 13
10 return locales.length > 0 ? locales[0] : null; 14 return locales.length > 0 ? locales[0] : null;
11} 15}