aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores
diff options
context:
space:
mode:
authorLibravatar Ricardo Cino <ricardo@cino.io>2022-06-24 21:25:05 +0200
committerLibravatar Vijay Aravamudhan <vraravam@users.noreply.github.com>2022-06-25 05:50:00 +0530
commit2d71e61e46394d75d9f52ba1f4c273ed6d3c9cfd (patch)
tree7c0172945f962609637d03e7de885a254dbec8a4 /src/stores
parentchore: improve todo menu behaviour on fresh install (#359) (diff)
downloadferdium-app-2d71e61e46394d75d9f52ba1f4c273ed6d3c9cfd.tar.gz
ferdium-app-2d71e61e46394d75d9f52ba1f4c273ed6d3c9cfd.tar.zst
ferdium-app-2d71e61e46394d75d9f52ba1f4c273ed6d3c9cfd.zip
chore: convert the last few stores to typescript
Diffstat (limited to 'src/stores')
-rw-r--r--src/stores/SettingsStore.ts (renamed from src/stores/SettingsStore.js)23
-rw-r--r--src/stores/UIStore.ts (renamed from src/stores/UIStore.js)38
-rw-r--r--src/stores/UserStore.ts (renamed from src/stores/UserStore.js)150
-rw-r--r--src/stores/lib/Store.js54
4 files changed, 116 insertions, 149 deletions
diff --git a/src/stores/SettingsStore.js b/src/stores/SettingsStore.ts
index 7afecd9df..524f2e50c 100644
--- a/src/stores/SettingsStore.js
+++ b/src/stores/SettingsStore.ts
@@ -2,6 +2,9 @@ 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 { Stores } from 'src/stores.types';
6import { ApiInterface } from 'src/api';
7import { Actions } from 'src/actions/lib/actions';
5import { 8import {
6 DEFAULT_APP_SETTINGS, 9 DEFAULT_APP_SETTINGS,
7 FILE_SYSTEM_SETTINGS_TYPES, 10 FILE_SYSTEM_SETTINGS_TYPES,
@@ -9,11 +12,11 @@ import {
9} from '../config'; 12} from '../config';
10import { hash } from '../helpers/password-helpers'; 13import { hash } from '../helpers/password-helpers';
11import Request from './lib/Request'; 14import Request from './lib/Request';
12import Store from './lib/Store'; 15import TypedStore from './lib/TypedStore';
13 16
14const debug = require('../preload-safe-debug')('Ferdium:SettingsStore'); 17const debug = require('../preload-safe-debug')('Ferdium:SettingsStore');
15 18
16export default class SettingsStore extends Store { 19export default class SettingsStore extends TypedStore {
17 @observable updateAppSettingsRequest = new Request( 20 @observable updateAppSettingsRequest = new Request(
18 this.api.local, 21 this.api.local,
19 'updateAppSettings', 22 'updateAppSettings',
@@ -28,15 +31,15 @@ export default class SettingsStore extends Store {
28 proxy: {}, 31 proxy: {},
29 }; 32 };
30 33
31 constructor(...args) { 34 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
32 super(...args); 35 super(stores, api, actions);
33 36
34 // Register action handlers 37 // Register action handlers
35 this.actions.settings.update.listen(this._update.bind(this)); 38 this.actions.settings.update.listen(this._update.bind(this));
36 this.actions.settings.remove.listen(this._remove.bind(this)); 39 this.actions.settings.remove.listen(this._remove.bind(this));
37 } 40 }
38 41
39 async setup() { 42 async setup(): Promise<void> {
40 await this._migrate(); 43 await this._migrate();
41 44
42 reaction( 45 reaction(
@@ -81,7 +84,7 @@ export default class SettingsStore extends Store {
81 } 84 }
82 }); 85 });
83 86
84 ipcRenderer.on('appSettings', (event, resp) => { 87 ipcRenderer.on('appSettings', (_, resp) => {
85 // Lock on startup if enabled in settings 88 // Lock on startup if enabled in settings
86 if ( 89 if (
87 !this.loaded && 90 !this.loaded &&
@@ -143,7 +146,7 @@ export default class SettingsStore extends Store {
143 }; 146 };
144 } 147 }
145 148
146 @action async _update({ type, data }) { 149 @action async _update({ type, data }): Promise<void> {
147 const appSettings = this.all; 150 const appSettings = this.all;
148 if (!this.fileSystemSettingsTypes.includes(type)) { 151 if (!this.fileSystemSettingsTypes.includes(type)) {
149 debug('Update settings', type, data, this.all); 152 debug('Update settings', type, data, this.all);
@@ -159,7 +162,7 @@ export default class SettingsStore extends Store {
159 } 162 }
160 } 163 }
161 164
162 @action async _remove({ type, key }) { 165 @action async _remove({ type, key }): Promise<void> {
163 if (type === 'app') return; // app keys can't be deleted 166 if (type === 'app') return; // app keys can't be deleted
164 167
165 const appSettings = this.all[type]; 168 const appSettings = this.all[type];
@@ -173,7 +176,7 @@ export default class SettingsStore extends Store {
173 } 176 }
174 } 177 }
175 178
176 _ensureMigrationAndMarkDone(migrationName, callback) { 179 _ensureMigrationAndMarkDone(migrationName: string, callback: Function): void {
177 if (!this.all.migration[migrationName]) { 180 if (!this.all.migration[migrationName]) {
178 callback(); 181 callback();
179 182
@@ -187,7 +190,7 @@ export default class SettingsStore extends Store {
187 } 190 }
188 191
189 // Helper 192 // Helper
190 async _migrate() { 193 async _migrate(): Promise<void> {
191 this._ensureMigrationAndMarkDone('password-hashing', () => { 194 this._ensureMigrationAndMarkDone('password-hashing', () => {
192 if (this.stores.settings.app.lockedPassword !== '') { 195 if (this.stores.settings.app.lockedPassword !== '') {
193 const legacySettings = localStorage.getItem('app') || {}; 196 const legacySettings = localStorage.getItem('app') || {};
diff --git a/src/stores/UIStore.js b/src/stores/UIStore.ts
index 091b9b8eb..306b14cb1 100644
--- a/src/stores/UIStore.js
+++ b/src/stores/UIStore.ts
@@ -1,17 +1,19 @@
1import { action, observable, computed, reaction } from 'mobx'; 1import { action, observable, computed, reaction } from 'mobx';
2import { nativeTheme } from '@electron/remote'; 2import { nativeTheme } from '@electron/remote';
3 3
4import { theme, ThemeType } from '../themes'; 4import { Stores } from 'src/stores.types';
5import Store from './lib/Store'; 5import { ApiInterface } from 'src/api';
6import { Actions } from 'src/actions/lib/actions';
7import { Theme, theme, ThemeType } from '../themes';
8import TypedStore from './lib/TypedStore';
6 9
7export default class UIStore extends Store { 10export default class UIStore extends TypedStore {
8 @observable showServicesUpdatedInfoBar = false; 11 @observable showServicesUpdatedInfoBar = false;
9 12
10 @observable isOsDarkThemeActive = nativeTheme.shouldUseDarkColors; 13 @observable isOsDarkThemeActive = nativeTheme.shouldUseDarkColors;
11 14
12 constructor(...args) { 15 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
13 super(...args); 16 super(stores, api, actions);
14
15 // Register action handlers 17 // Register action handlers
16 this.actions.ui.openSettings.listen(this._openSettings.bind(this)); 18 this.actions.ui.openSettings.listen(this._openSettings.bind(this));
17 this.actions.ui.closeSettings.listen(this._closeSettings.bind(this)); 19 this.actions.ui.closeSettings.listen(this._closeSettings.bind(this));
@@ -26,7 +28,7 @@ export default class UIStore extends Store {
26 }); 28 });
27 } 29 }
28 30
29 setup() { 31 setup(): void {
30 reaction( 32 reaction(
31 () => this.isDarkThemeActive, 33 () => this.isDarkThemeActive,
32 () => { 34 () => {
@@ -74,15 +76,15 @@ export default class UIStore extends Store {
74 ); 76 );
75 } 77 }
76 78
77 @computed get isSplitModeActive() { 79 @computed get isSplitModeActive(): boolean {
78 return this.stores.settings.app.splitMode; 80 return this.stores.settings.app.splitMode;
79 } 81 }
80 82
81 @computed get splitColumnsNo() { 83 @computed get splitColumnsNo(): number {
82 return this.stores.settings.app.splitColumns; 84 return this.stores.settings.app.splitColumns;
83 } 85 }
84 86
85 @computed get theme() { 87 @computed get theme(): Theme {
86 const themeId = 88 const themeId =
87 this.isDarkThemeActive || this.stores.settings.app.darkMode 89 this.isDarkThemeActive || this.stores.settings.app.darkMode
88 ? ThemeType.dark 90 ? ThemeType.dark
@@ -92,16 +94,16 @@ export default class UIStore extends Store {
92 } 94 }
93 95
94 // Actions 96 // Actions
95 @action _openSettings({ path = '/settings' }) { 97 @action _openSettings({ path = '/settings' }): void {
96 const settingsPath = path !== '/settings' ? `/settings/${path}` : path; 98 const settingsPath = path !== '/settings' ? `/settings/${path}` : path;
97 this.stores.router.push(settingsPath); 99 this.stores.router.push(settingsPath);
98 } 100 }
99 101
100 @action _closeSettings() { 102 @action _closeSettings(): void {
101 this.stores.router.push('/'); 103 this.stores.router.push('/');
102 } 104 }
103 105
104 @action _toggleServiceUpdatedInfoBar({ visible }) { 106 @action _toggleServiceUpdatedInfoBar({ visible }): void {
105 let visibility = visible; 107 let visibility = visible;
106 if (visibility === null) { 108 if (visibility === null) {
107 visibility = !this.showServicesUpdatedInfoBar; 109 visibility = !this.showServicesUpdatedInfoBar;
@@ -110,7 +112,7 @@ export default class UIStore extends Store {
110 } 112 }
111 113
112 // Reactions 114 // Reactions
113 _setupThemeInDOM() { 115 _setupThemeInDOM(): void {
114 if (!this.isDarkThemeActive) { 116 if (!this.isDarkThemeActive) {
115 document.body.classList.remove('theme__dark'); 117 document.body.classList.remove('theme__dark');
116 } else { 118 } else {
@@ -118,16 +120,16 @@ export default class UIStore extends Store {
118 } 120 }
119 } 121 }
120 122
121 _setupModeInDOM() { 123 _setupModeInDOM(): void {
122 if (!this.isSplitModeActive) { 124 if (!this.isSplitModeActive) {
123 document.body.classList.remove('mode__split'); 125 document.body.classList.remove('mode__split');
124 } else { 126 } else {
125 document.body.classList.add('mode__split'); 127 document.body.classList.add('mode__split');
126 document.body.dataset.columns = this.splitColumnsNo; 128 document.body.dataset.columns = this.splitColumnsNo.toString();
127 } 129 }
128 } 130 }
129 131
130 _setupColumnsInDOM() { 132 _setupColumnsInDOM(): void {
131 document.body.dataset.columns = this.splitColumnsNo; 133 document.body.dataset.columns = this.splitColumnsNo.toString();
132 } 134 }
133} 135}
diff --git a/src/stores/UserStore.js b/src/stores/UserStore.ts
index 661c03e2c..616ff29a6 100644
--- a/src/stores/UserStore.js
+++ b/src/stores/UserStore.ts
@@ -4,83 +4,94 @@ import jwt from 'jsonwebtoken';
4import localStorage from 'mobx-localstorage'; 4import localStorage from 'mobx-localstorage';
5import { ipcRenderer } from 'electron'; 5import { ipcRenderer } from 'electron';
6 6
7import { ApiInterface } from 'src/api';
8import { Actions } from 'src/actions/lib/actions';
9import { Stores } from 'src/stores.types';
7import { TODOS_PARTITION_ID } from '../config'; 10import { TODOS_PARTITION_ID } from '../config';
8import { isDevMode } from '../environment-remote'; 11import { isDevMode } from '../environment-remote';
9import Store from './lib/Store';
10import Request from './lib/Request'; 12import Request from './lib/Request';
11import CachedRequest from './lib/CachedRequest'; 13import CachedRequest from './lib/CachedRequest';
14import TypedStore from './lib/TypedStore';
12 15
13const debug = require('../preload-safe-debug')('Ferdium:UserStore'); 16const debug = require('../preload-safe-debug')('Ferdium:UserStore');
14 17
15// TODO: split stores into UserStore and AuthStore 18// TODO: split stores into UserStore and AuthStore
16export default class UserStore extends Store { 19export default class UserStore extends TypedStore {
17 BASE_ROUTE = '/auth'; 20 BASE_ROUTE: string = '/auth';
18 21
19 WELCOME_ROUTE = `${this.BASE_ROUTE}/welcome`; 22 WELCOME_ROUTE: string = `${this.BASE_ROUTE}/welcome`;
20 23
21 LOGIN_ROUTE = `${this.BASE_ROUTE}/login`; 24 LOGIN_ROUTE: string = `${this.BASE_ROUTE}/login`;
22 25
23 LOGOUT_ROUTE = `${this.BASE_ROUTE}/logout`; 26 LOGOUT_ROUTE: string = `${this.BASE_ROUTE}/logout`;
24 27
25 SIGNUP_ROUTE = `${this.BASE_ROUTE}/signup`; 28 SIGNUP_ROUTE: string = `${this.BASE_ROUTE}/signup`;
26 29
27 SETUP_ROUTE = `${this.BASE_ROUTE}/signup/setup`; 30 SETUP_ROUTE: string = `${this.BASE_ROUTE}/signup/setup`;
28 31
29 IMPORT_ROUTE = `${this.BASE_ROUTE}/signup/import`; 32 IMPORT_ROUTE: string = `${this.BASE_ROUTE}/signup/import`;
30 33
31 INVITE_ROUTE = `${this.BASE_ROUTE}/signup/invite`; 34 INVITE_ROUTE: string = `${this.BASE_ROUTE}/signup/invite`;
32 35
33 PASSWORD_ROUTE = `${this.BASE_ROUTE}/password`; 36 PASSWORD_ROUTE: string = `${this.BASE_ROUTE}/password`;
34 37
35 CHANGE_SERVER_ROUTE = `${this.BASE_ROUTE}/server`; 38 CHANGE_SERVER_ROUTE: string = `${this.BASE_ROUTE}/server`;
36 39
37 @observable loginRequest = new Request(this.api.user, 'login'); 40 @observable loginRequest: Request = new Request(this.api.user, 'login');
38 41
39 @observable signupRequest = new Request(this.api.user, 'signup'); 42 @observable signupRequest: Request = new Request(this.api.user, 'signup');
40 43
41 @observable passwordRequest = new Request(this.api.user, 'password'); 44 @observable passwordRequest: Request = new Request(this.api.user, 'password');
42 45
43 @observable inviteRequest = new Request(this.api.user, 'invite'); 46 @observable inviteRequest: Request = new Request(this.api.user, 'invite');
44 47
45 @observable getUserInfoRequest = new CachedRequest(this.api.user, 'getInfo'); 48 @observable getUserInfoRequest: CachedRequest = new CachedRequest(
49 this.api.user,
50 'getInfo',
51 );
46 52
47 @observable updateUserInfoRequest = new Request(this.api.user, 'updateInfo'); 53 @observable updateUserInfoRequest: Request = new Request(
54 this.api.user,
55 'updateInfo',
56 );
48 57
49 @observable getLegacyServicesRequest = new CachedRequest( 58 @observable getLegacyServicesRequest: CachedRequest = new CachedRequest(
50 this.api.user, 59 this.api.user,
51 'getLegacyServices', 60 'getLegacyServices',
52 ); 61 );
53 62
54 @observable deleteAccountRequest = new CachedRequest(this.api.user, 'delete'); 63 @observable deleteAccountRequest: CachedRequest = new CachedRequest(
55 64 this.api.user,
56 @observable isImportLegacyServicesExecuting = false; 65 'delete',
66 );
57 67
58 @observable isImportLegacyServicesCompleted = false; 68 @observable isImportLegacyServicesExecuting: boolean = false;
59 69
60 @observable isLoggingOut = false; 70 @observable isImportLegacyServicesCompleted: boolean = false;
61 71
62 @observable id; 72 @observable isLoggingOut: boolean = false;
63 73
64 @observable authToken = localStorage.getItem('authToken') || null; 74 @observable id: string | null | undefined;
65 75
66 @observable accountType; 76 @observable authToken: string | null =
77 localStorage.getItem('authToken') || null;
67 78
68 @observable hasCompletedSignup = false; 79 @observable accountType: string | undefined;
69 80
70 @observable userData = {}; 81 @observable hasCompletedSignup: boolean = false;
71 82
72 @observable actionStatus = []; 83 @observable userData: object = {};
73 84
74 logoutReasonTypes = { 85 logoutReasonTypes = {
75 SERVER: 'SERVER', 86 SERVER: 'SERVER',
76 }; 87 };
77 88
78 @observable logoutReason = null; 89 @observable logoutReason: string | null = null;
79 90
80 fetchUserInfoInterval = null; 91 fetchUserInfoInterval = null;
81 92
82 constructor(...args) { 93 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
83 super(...args); 94 super(stores, api, actions);
84 95
85 // Register action handlers 96 // Register action handlers
86 this.actions.user.login.listen(this._login.bind(this)); 97 this.actions.user.login.listen(this._login.bind(this));
@@ -104,54 +115,58 @@ export default class UserStore extends Store {
104 ]); 115 ]);
105 } 116 }
106 117
107 setup() { 118 setup(): void {
108 // Data migration 119 // Data migration
109 this._migrateUserLocale(); 120 this._migrateUserLocale();
110 } 121 }
111 122
112 // Routes 123 // Routes
113 get loginRoute() { 124 get loginRoute(): string {
114 return this.LOGIN_ROUTE; 125 return this.LOGIN_ROUTE;
115 } 126 }
116 127
117 get logoutRoute() { 128 get logoutRoute(): string {
118 return this.LOGOUT_ROUTE; 129 return this.LOGOUT_ROUTE;
119 } 130 }
120 131
121 get signupRoute() { 132 get signupRoute(): string {
122 return this.SIGNUP_ROUTE; 133 return this.SIGNUP_ROUTE;
123 } 134 }
124 135
125 get setupRoute() { 136 get setupRoute(): string {
126 return this.SETUP_ROUTE; 137 return this.SETUP_ROUTE;
127 } 138 }
128 139
129 get inviteRoute() { 140 get inviteRoute(): string {
130 return this.INVITE_ROUTE; 141 return this.INVITE_ROUTE;
131 } 142 }
132 143
133 get importRoute() { 144 get importRoute(): string {
134 return this.IMPORT_ROUTE; 145 return this.IMPORT_ROUTE;
135 } 146 }
136 147
137 get passwordRoute() { 148 get passwordRoute(): string {
138 return this.PASSWORD_ROUTE; 149 return this.PASSWORD_ROUTE;
139 } 150 }
140 151
141 get changeServerRoute() { 152 get changeServerRoute(): string {
142 return this.CHANGE_SERVER_ROUTE; 153 return this.CHANGE_SERVER_ROUTE;
143 } 154 }
144 155
145 // Data 156 // Data
146 @computed get isLoggedIn() { 157 @computed get isLoggedIn(): boolean {
147 return Boolean(localStorage.getItem('authToken')); 158 return Boolean(localStorage.getItem('authToken'));
148 } 159 }
149 160
150 @computed get isTokenExpired() { 161 @computed get isTokenExpired(): boolean {
151 if (!this.authToken) return false; 162 if (!this.authToken) return false;
163 const parsedToken = this._parseToken(this.authToken);
152 164
153 const { tokenExpiry } = this._parseToken(this.authToken); 165 return (
154 return this.authToken !== null && moment(tokenExpiry).isBefore(moment()); 166 parsedToken !== false &&
167 this.authToken !== null &&
168 moment(parsedToken.tokenExpiry).isBefore(moment())
169 );
155 } 170 }
156 171
157 @computed get data() { 172 @computed get data() {
@@ -160,23 +175,23 @@ export default class UserStore extends Store {
160 return this.getUserInfoRequest.execute().result || {}; 175 return this.getUserInfoRequest.execute().result || {};
161 } 176 }
162 177
163 @computed get team() { 178 @computed get team(): any {
164 return this.data.team || null; 179 return this.data.team || null;
165 } 180 }
166 181
167 @computed get legacyServices() { 182 @computed get legacyServices(): any {
168 return this.getLegacyServicesRequest.execute() || {}; 183 return this.getLegacyServicesRequest.execute() || {};
169 } 184 }
170 185
171 // Actions 186 // Actions
172 @action async _login({ email, password }) { 187 @action async _login({ email, password }): Promise<void> {
173 const authToken = await this.loginRequest.execute(email, password)._promise; 188 const authToken = await this.loginRequest.execute(email, password)._promise;
174 this._setUserData(authToken); 189 this._setUserData(authToken);
175 190
176 this.stores.router.push('/'); 191 this.stores.router.push('/');
177 } 192 }
178 193
179 @action _tokenLogin(authToken) { 194 @action _tokenLogin(authToken: string): void {
180 this._setUserData(authToken); 195 this._setUserData(authToken);
181 196
182 this.stores.router.push('/'); 197 this.stores.router.push('/');
@@ -191,7 +206,7 @@ export default class UserStore extends Store {
191 company, 206 company,
192 plan, 207 plan,
193 currency, 208 currency,
194 }) { 209 }): Promise<void> {
195 const authToken = await this.signupRequest.execute({ 210 const authToken = await this.signupRequest.execute({
196 firstname, 211 firstname,
197 lastname, 212 lastname,
@@ -211,14 +226,14 @@ export default class UserStore extends Store {
211 this.stores.router.push(this.SETUP_ROUTE); 226 this.stores.router.push(this.SETUP_ROUTE);
212 } 227 }
213 228
214 @action async _retrievePassword({ email }) { 229 @action async _retrievePassword({ email }): Promise<void> {
215 const request = this.passwordRequest.execute(email); 230 const request = this.passwordRequest.execute(email);
216 231
217 await request._promise; 232 await request._promise;
218 this.actionStatus = request.result.status || []; 233 this.actionStatus = request.result.status || [];
219 } 234 }
220 235
221 @action async _invite({ invites }) { 236 @action async _invite({ invites }): Promise<void> {
222 const data = invites.filter(invite => invite.email !== ''); 237 const data = invites.filter(invite => invite.email !== '');
223 238
224 const response = await this.inviteRequest.execute(data)._promise; 239 const response = await this.inviteRequest.execute(data)._promise;
@@ -231,7 +246,7 @@ export default class UserStore extends Store {
231 } 246 }
232 } 247 }
233 248
234 @action async _update({ userData }) { 249 @action async _update({ userData }): Promise<void> {
235 if (!this.isLoggedIn) return; 250 if (!this.isLoggedIn) return;
236 251
237 const response = await this.updateUserInfoRequest.execute(userData) 252 const response = await this.updateUserInfoRequest.execute(userData)
@@ -241,11 +256,11 @@ export default class UserStore extends Store {
241 this.actionStatus = response.status || []; 256 this.actionStatus = response.status || [];
242 } 257 }
243 258
244 @action _resetStatus() { 259 @action _resetStatus(): void {
245 this.actionStatus = []; 260 this.actionStatus = [];
246 } 261 }
247 262
248 @action _logout() { 263 @action _logout(): void {
249 // workaround mobx issue 264 // workaround mobx issue
250 localStorage.removeItem('authToken'); 265 localStorage.removeItem('authToken');
251 window.localStorage.removeItem('authToken'); 266 window.localStorage.removeItem('authToken');
@@ -260,7 +275,7 @@ export default class UserStore extends Store {
260 } 275 }
261 } 276 }
262 277
263 @action async _importLegacyServices({ services }) { 278 @action async _importLegacyServices({ services }): Promise<void> {
264 this.isImportLegacyServicesExecuting = true; 279 this.isImportLegacyServicesExecuting = true;
265 280
266 // Reduces recipe duplicates 281 // Reduces recipe duplicates
@@ -289,12 +304,12 @@ export default class UserStore extends Store {
289 this.isImportLegacyServicesCompleted = true; 304 this.isImportLegacyServicesCompleted = true;
290 } 305 }
291 306
292 @action async _delete() { 307 @action async _delete(): Promise<void> {
293 this.deleteAccountRequest.execute(); 308 this.deleteAccountRequest.execute();
294 } 309 }
295 310
296 // This is a mobx autorun which forces the user to login if not authenticated 311 // This is a mobx autorun which forces the user to login if not authenticated
297 _requireAuthenticatedUser = () => { 312 _requireAuthenticatedUser = (): void => {
298 if (this.isTokenExpired) { 313 if (this.isTokenExpired) {
299 this._logout(); 314 this._logout();
300 } 315 }
@@ -328,13 +343,13 @@ export default class UserStore extends Store {
328 }; 343 };
329 344
330 // Reactions 345 // Reactions
331 async _getUserData() { 346 async _getUserData(): Promise<void> {
332 if (this.isLoggedIn) { 347 if (this.isLoggedIn) {
333 let data; 348 let data;
334 try { 349 try {
335 data = await this.getUserInfoRequest.execute()._promise; 350 data = await this.getUserInfoRequest.execute()._promise;
336 } catch { 351 } catch {
337 return false; 352 return;
338 } 353 }
339 354
340 // We need to set the beta flag for the SettingsStore 355 // We need to set the beta flag for the SettingsStore
@@ -364,9 +379,9 @@ export default class UserStore extends Store {
364 } 379 }
365 } 380 }
366 381
367 _setUserData(authToken) { 382 _setUserData(authToken: any): void {
368 const data = this._parseToken(authToken); 383 const data = this._parseToken(authToken);
369 if (data.authToken) { 384 if (data !== false && data.authToken) {
370 localStorage.setItem('authToken', data.authToken); 385 localStorage.setItem('authToken', data.authToken);
371 386
372 this.authToken = data.authToken; 387 this.authToken = data.authToken;
@@ -377,20 +392,21 @@ export default class UserStore extends Store {
377 } 392 }
378 } 393 }
379 394
380 getAuthURL(url) { 395 getAuthURL(url: string): string {
381 const parsedUrl = new URL(url); 396 const parsedUrl = new URL(url);
382 const params = new URLSearchParams(parsedUrl.search.slice(1)); 397 const params = new URLSearchParams(parsedUrl.search.slice(1));
383 398
384 params.append('authToken', this.authToken); 399 // TODO: Remove the neccesity for `as string`
400 params.append('authToken', this.authToken as string);
385 401
386 return `${parsedUrl.origin}${parsedUrl.pathname}?${params.toString()}`; 402 return `${parsedUrl.origin}${parsedUrl.pathname}?${params.toString()}`;
387 } 403 }
388 404
389 async _migrateUserLocale() { 405 async _migrateUserLocale(): Promise<void> {
390 try { 406 try {
391 await this.getUserInfoRequest._promise; 407 await this.getUserInfoRequest._promise;
392 } catch { 408 } catch {
393 return false; 409 return;
394 } 410 }
395 411
396 if (!this.data.locale) { 412 if (!this.data.locale) {
diff --git a/src/stores/lib/Store.js b/src/stores/lib/Store.js
deleted file mode 100644
index 739a47729..000000000
--- a/src/stores/lib/Store.js
+++ /dev/null
@@ -1,54 +0,0 @@
1import { computed, observable } from 'mobx';
2import Reaction from './Reaction';
3
4export default class Store {
5 /** @type Stores */
6 stores;
7
8 /** @type ApiInterface */
9 api;
10
11 /** @type Actions */
12 actions;
13
14 /** @type Reaction[] */
15 _reactions = [];
16
17 // status implementation
18 @observable _status = null;
19
20 @computed get actionStatus() {
21 return this._status || [];
22 }
23
24 set actionStatus(status) {
25 this._status = status;
26 }
27
28 constructor(stores, api, actions) {
29 this.stores = stores;
30 this.api = api;
31 this.actions = actions;
32 }
33
34 registerReactions(reactions) {
35 for (const reaction of reactions) {
36 this._reactions.push(new Reaction(reaction));
37 }
38 }
39
40 setup() {}
41
42 initialize() {
43 this.setup();
44 for (const reaction of this._reactions) reaction.start();
45 }
46
47 teardown() {
48 for (const reaction of this._reactions) reaction.stop();
49 }
50
51 resetStatus() {
52 this._status = null;
53 }
54}