aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
authorLibravatar Ricardo Cino <ricardo@cino.io>2022-06-22 00:32:18 +0200
committerLibravatar GitHub <noreply@github.com>2022-06-21 22:32:18 +0000
commit73ba955e344c8ccedd43235495ef8b72b5a2b6fd (patch)
tree03766ab32fefe7e83026a14393527f1dcbaed849 /src/stores
parentdocs: add cino as a contributor for infra [skip ci] (#330) (diff)
downloadferdium-app-73ba955e344c8ccedd43235495ef8b72b5a2b6fd.tar.gz
ferdium-app-73ba955e344c8ccedd43235495ef8b72b5a2b6fd.tar.zst
ferdium-app-73ba955e344c8ccedd43235495ef8b72b5a2b6fd.zip
chore: Transform AppStore.js into Typescript (#329)
* turn actions into typescript * correct tsconfig * added TypedStore
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/AppStore.ts (renamed from src/stores/AppStore.js)40
-rw-r--r--src/stores/index.ts13
-rw-r--r--src/stores/lib/Reaction.ts14
-rw-r--r--src/stores/lib/Store.js13
-rw-r--r--src/stores/lib/TypedStore.ts46
5 files changed, 100 insertions, 26 deletions
diff --git a/src/stores/AppStore.js b/src/stores/AppStore.ts
index a8e1ce247..5659460c6 100644
--- a/src/stores/AppStore.js
+++ b/src/stores/AppStore.ts
@@ -14,12 +14,19 @@ import ms from 'ms';
14import { URL } from 'url'; 14import { URL } from 'url';
15import { readJsonSync } from 'fs-extra'; 15import { readJsonSync } from 'fs-extra';
16 16
17import Store from './lib/Store'; 17import { Stores } from 'src/stores.types';
18import { ApiInterface } from 'src/api';
19import { Actions } from 'src/actions/lib/actions';
20import TypedStore from './lib/TypedStore';
18import Request from './lib/Request'; 21import Request from './lib/Request';
19import { CHECK_INTERVAL, DEFAULT_APP_SETTINGS } from '../config'; 22import { CHECK_INTERVAL, DEFAULT_APP_SETTINGS } from '../config';
20import { cleanseJSObject } from '../jsUtils'; 23import { cleanseJSObject } from '../jsUtils';
21import { isMac, isWindows, electronVersion, osRelease } from '../environment'; 24import { isMac, isWindows, electronVersion, osRelease } from '../environment';
22import { ferdiumVersion, userDataPath, ferdiumLocale } from '../environment-remote'; 25import {
26 ferdiumVersion,
27 userDataPath,
28 ferdiumLocale,
29} from '../environment-remote';
23import { generatedTranslations } from '../i18n/translations'; 30import { generatedTranslations } from '../i18n/translations';
24import { getLocale } from '../helpers/i18n-helpers'; 31import { getLocale } from '../helpers/i18n-helpers';
25 32
@@ -45,7 +52,7 @@ const CATALINA_NOTIFICATION_HACK_KEY =
45 52
46const locales = generatedTranslations(); 53const locales = generatedTranslations();
47 54
48export default class AppStore extends Store { 55export default class AppStore extends TypedStore {
49 updateStatusTypes = { 56 updateStatusTypes = {
50 CHECKING: 'CHECKING', 57 CHECKING: 'CHECKING',
51 AVAILABLE: 'AVAILABLE', 58 AVAILABLE: 'AVAILABLE',
@@ -89,10 +96,10 @@ export default class AppStore extends Store {
89 96
90 dictionaries = []; 97 dictionaries = [];
91 98
92 fetchDataInterval = null; 99 fetchDataInterval: null | NodeJS.Timer = null;
93 100
94 constructor(...args) { 101 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
95 super(...args); 102 super(stores, api, actions);
96 103
97 // Register action handlers 104 // Register action handlers
98 this.actions.app.notify.listen(this._notify.bind(this)); 105 this.actions.app.notify.listen(this._notify.bind(this));
@@ -118,7 +125,7 @@ export default class AppStore extends Store {
118 ]); 125 ]);
119 } 126 }
120 127
121 async setup() { 128 async setup(): Promise<void> {
122 this._appStartsCounter(); 129 this._appStartsCounter();
123 // Focus the active service 130 // Focus the active service
124 window.addEventListener('focus', this.actions.service.focusActiveService); 131 window.addEventListener('focus', this.actions.service.focusActiveService);
@@ -162,7 +169,7 @@ export default class AppStore extends Store {
162 setInterval(() => this._checkForUpdates(), CHECK_INTERVAL); 169 setInterval(() => this._checkForUpdates(), CHECK_INTERVAL);
163 // Check for an update in 30s (need a delay to prevent Squirrel Installer lock file issues) 170 // Check for an update in 30s (need a delay to prevent Squirrel Installer lock file issues)
164 setTimeout(() => this._checkForUpdates(), ms('30s')); 171 setTimeout(() => this._checkForUpdates(), ms('30s'));
165 ipcRenderer.on('autoUpdate', (event, data) => { 172 ipcRenderer.on('autoUpdate', (_, data) => {
166 if (this.updateStatus !== this.updateStatusTypes.FAILED) { 173 if (this.updateStatus !== this.updateStatusTypes.FAILED) {
167 if (data.available) { 174 if (data.available) {
168 this.updateStatus = this.updateStatusTypes.AVAILABLE; 175 this.updateStatus = this.updateStatusTypes.AVAILABLE;
@@ -185,7 +192,10 @@ export default class AppStore extends Store {
185 if (data.error) { 192 if (data.error) {
186 if (data.error.message && data.error.message.startsWith('404')) { 193 if (data.error.message && data.error.message.startsWith('404')) {
187 this.updateStatus = this.updateStatusTypes.NOT_AVAILABLE; 194 this.updateStatus = this.updateStatusTypes.NOT_AVAILABLE;
188 console.warn('Updater warning: there seems to be unpublished pre-release(s) available on GitHub', data.error); 195 console.warn(
196 'Updater warning: there seems to be unpublished pre-release(s) available on GitHub',
197 data.error,
198 );
189 } else { 199 } else {
190 console.error('Updater error:', data.error); 200 console.error('Updater error:', data.error);
191 this.updateStatus = this.updateStatusTypes.FAILED; 201 this.updateStatus = this.updateStatusTypes.FAILED;
@@ -195,7 +205,7 @@ export default class AppStore extends Store {
195 }); 205 });
196 206
197 // Handle deep linking (ferdium://) 207 // Handle deep linking (ferdium://)
198 ipcRenderer.on('navigateFromDeepLink', (event, data) => { 208 ipcRenderer.on('navigateFromDeepLink', (_, data) => {
199 debug('Navigate from deep link', data); 209 debug('Navigate from deep link', data);
200 let { url } = data; 210 let { url } = data;
201 if (!url) return; 211 if (!url) return;
@@ -217,7 +227,7 @@ export default class AppStore extends Store {
217 227
218 this.isSystemDarkModeEnabled = nativeTheme.shouldUseDarkColors; 228 this.isSystemDarkModeEnabled = nativeTheme.shouldUseDarkColors;
219 229
220 ipcRenderer.on('isWindowFocused', (event, isFocused) => { 230 ipcRenderer.on('isWindowFocused', (_, isFocused) => {
221 debug('Setting is focused to', isFocused); 231 debug('Setting is focused to', isFocused);
222 this.isFocused = isFocused; 232 this.isFocused = isFocused;
223 }); 233 });
@@ -391,7 +401,11 @@ export default class AppStore extends Store {
391 } 401 }
392 402
393 @action _checkForUpdates() { 403 @action _checkForUpdates() {
394 if (this.isOnline && this.stores.settings.app.automaticUpdates && (isMac || isWindows || process.env.APPIMAGE)) { 404 if (
405 this.isOnline &&
406 this.stores.settings.app.automaticUpdates &&
407 (isMac || isWindows || process.env.APPIMAGE)
408 ) {
395 debug('_checkForUpdates: sending event to autoUpdate:check'); 409 debug('_checkForUpdates: sending event to autoUpdate:check');
396 this.updateStatus = this.updateStatusTypes.CHECKING; 410 this.updateStatus = this.updateStatusTypes.CHECKING;
397 ipcRenderer.send('autoUpdate', { 411 ipcRenderer.send('autoUpdate', {
@@ -526,7 +540,7 @@ export default class AppStore extends Store {
526 } 540 }
527 541
528 _handleLogout() { 542 _handleLogout() {
529 if (!this.stores.user.isLoggedIn) { 543 if (!this.stores.user.isLoggedIn && this.fetchDataInterval !== null) {
530 clearInterval(this.fetchDataInterval); 544 clearInterval(this.fetchDataInterval);
531 } 545 }
532 } 546 }
diff --git a/src/stores/index.ts b/src/stores/index.ts
index 6ad898d85..a5b1a7452 100644
--- a/src/stores/index.ts
+++ b/src/stores/index.ts
@@ -1,3 +1,7 @@
1import { Stores } from 'src/stores.types';
2import { RouterStore } from 'mobx-react-router';
3import { ApiInterface } from 'src/api';
4import { Actions } from 'src/actions/lib/actions';
1import AppStore from './AppStore'; 5import AppStore from './AppStore';
2import UserStore from './UserStore'; 6import UserStore from './UserStore';
3import FeaturesStore from './FeaturesStore'; 7import FeaturesStore from './FeaturesStore';
@@ -12,8 +16,12 @@ import { workspaceStore } from '../features/workspaces';
12import { communityRecipesStore } from '../features/communityRecipes'; 16import { communityRecipesStore } from '../features/communityRecipes';
13import { todosStore } from '../features/todos'; 17import { todosStore } from '../features/todos';
14 18
15export default (api, actions, router) => { 19export default (
16 const stores = {}; 20 api: ApiInterface,
21 actions: Actions,
22 router: RouterStore,
23): Stores => {
24 const stores: Stores | any = {};
17 Object.assign(stores, { 25 Object.assign(stores, {
18 router, 26 router,
19 app: new AppStore(stores, api, actions), 27 app: new AppStore(stores, api, actions),
@@ -37,5 +45,6 @@ export default (api, actions, router) => {
37 stores[name].initialize(); 45 stores[name].initialize();
38 } 46 }
39 } 47 }
48
40 return stores; 49 return stores;
41}; 50};
diff --git a/src/stores/lib/Reaction.ts b/src/stores/lib/Reaction.ts
index 0ca24a6fa..3966c8073 100644
--- a/src/stores/lib/Reaction.ts
+++ b/src/stores/lib/Reaction.ts
@@ -1,24 +1,24 @@
1import { autorun } from 'mobx'; 1import { autorun, IReactionDisposer, IReactionPublic } from 'mobx';
2 2
3export default class Reaction { 3export default class Reaction {
4 reaction; 4 public reaction: (r: IReactionPublic) => any;
5 5
6 isRunning = false; 6 private isRunning: boolean = false;
7 7
8 dispose; 8 public dispose?: IReactionDisposer;
9 9
10 constructor(reaction) { 10 constructor(reaction: any) {
11 this.reaction = reaction; 11 this.reaction = reaction;
12 } 12 }
13 13
14 start() { 14 start(): void {
15 if (!this.isRunning) { 15 if (!this.isRunning) {
16 this.dispose = autorun(this.reaction); 16 this.dispose = autorun(this.reaction);
17 this.isRunning = true; 17 this.isRunning = true;
18 } 18 }
19 } 19 }
20 20
21 stop() { 21 stop(): void {
22 if (this.isRunning) { 22 if (this.isRunning) {
23 this.dispose?.(); 23 this.dispose?.();
24 this.isRunning = false; 24 this.isRunning = false;
diff --git a/src/stores/lib/Store.js b/src/stores/lib/Store.js
index a867c3a46..739a47729 100644
--- a/src/stores/lib/Store.js
+++ b/src/stores/lib/Store.js
@@ -2,12 +2,16 @@ import { computed, observable } from 'mobx';
2import Reaction from './Reaction'; 2import Reaction from './Reaction';
3 3
4export default class Store { 4export default class Store {
5 stores = {}; 5 /** @type Stores */
6 stores;
6 7
7 api = {}; 8 /** @type ApiInterface */
9 api;
8 10
9 actions = {}; 11 /** @type Actions */
12 actions;
10 13
14 /** @type Reaction[] */
11 _reactions = []; 15 _reactions = [];
12 16
13 // status implementation 17 // status implementation
@@ -28,8 +32,9 @@ export default class Store {
28 } 32 }
29 33
30 registerReactions(reactions) { 34 registerReactions(reactions) {
31 for (const reaction of reactions) 35 for (const reaction of reactions) {
32 this._reactions.push(new Reaction(reaction)); 36 this._reactions.push(new Reaction(reaction));
37 }
33 } 38 }
34 39
35 setup() {} 40 setup() {}
diff --git a/src/stores/lib/TypedStore.ts b/src/stores/lib/TypedStore.ts
new file mode 100644
index 000000000..5d8bf3bbd
--- /dev/null
+++ b/src/stores/lib/TypedStore.ts
@@ -0,0 +1,46 @@
1import { computed, IReactionPublic, observable } from 'mobx';
2import { Actions } from 'src/actions/lib/actions';
3import { ApiInterface } from 'src/api';
4import { Stores } from 'src/stores.types';
5import Reaction from './Reaction';
6
7export default abstract class TypedStore {
8 _reactions: Reaction[] = [];
9
10 @observable _status: any = null;
11
12 @computed get actionStatus() {
13 return this._status || [];
14 }
15
16 set actionStatus(status) {
17 this._status = status;
18 }
19
20 constructor(
21 public stores: Stores,
22 public api: ApiInterface,
23 public actions: Actions,
24 ) {}
25
26 registerReactions(reactions: { (r: IReactionPublic): void }[]): void {
27 for (const reaction of reactions) {
28 this._reactions.push(new Reaction(reaction));
29 }
30 }
31
32 public abstract setup(): void;
33
34 initialize(): void {
35 this.setup();
36 for (const reaction of this._reactions) reaction.start();
37 }
38
39 teardown(): void {
40 for (const reaction of this._reactions) reaction.stop();
41 }
42
43 resetStatus(): void {
44 this._status = null;
45 }
46}