diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/I18n.tsx | 2 | ||||
-rw-r--r-- | src/containers/auth/ImportScreen.tsx | 12 | ||||
-rw-r--r-- | src/containers/auth/LockedScreen.tsx | 22 | ||||
-rw-r--r-- | src/containers/auth/PasswordScreen.tsx | 10 | ||||
-rw-r--r-- | src/electron-util.ts | 4 | ||||
-rw-r--r-- | src/enforce-macos-app-location.ts | 2 | ||||
-rw-r--r-- | src/environment-remote.ts | 22 | ||||
-rw-r--r-- | src/environment.ts | 16 | ||||
-rw-r--r-- | src/routes.tsx | 5 | ||||
-rw-r--r-- | src/stores.types.ts | 37 | ||||
-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.js | 54 |
14 files changed, 186 insertions, 211 deletions
diff --git a/src/I18n.tsx b/src/I18n.tsx index f5e157d97..1be6ab23d 100644 --- a/src/I18n.tsx +++ b/src/I18n.tsx | |||
@@ -17,7 +17,7 @@ type Props = { | |||
17 | }; | 17 | }; |
18 | 18 | ||
19 | class I18N extends Component<Props> { | 19 | class I18N extends Component<Props> { |
20 | componentDidUpdate() { | 20 | componentDidUpdate(): void { |
21 | window['ferdium'].menu.rebuild(); | 21 | window['ferdium'].menu.rebuild(); |
22 | } | 22 | } |
23 | 23 | ||
diff --git a/src/containers/auth/ImportScreen.tsx b/src/containers/auth/ImportScreen.tsx index 756a2e59c..8d318cb2d 100644 --- a/src/containers/auth/ImportScreen.tsx +++ b/src/containers/auth/ImportScreen.tsx | |||
@@ -1,17 +1,17 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
2 | import { inject, observer } from 'mobx-react'; | 2 | import { inject, observer } from 'mobx-react'; |
3 | import { RouterStore } from 'mobx-react-router'; | 3 | import { RouterStore } from 'mobx-react-router'; |
4 | import { UserStore } from 'src/stores.types'; | ||
4 | import Import from '../../components/auth/Import'; | 5 | import Import from '../../components/auth/Import'; |
5 | import UserStore from '../../stores/UserStore'; | ||
6 | 6 | ||
7 | interface IProps { | 7 | interface IProps { |
8 | actions: { | 8 | actions: { |
9 | user: UserStore, | 9 | user: UserStore; |
10 | }, | 10 | }; |
11 | stores: { | 11 | stores: { |
12 | user: UserStore, | 12 | user: UserStore; |
13 | router: RouterStore, | 13 | router: RouterStore; |
14 | } | 14 | }; |
15 | } | 15 | } |
16 | 16 | ||
17 | class ImportScreen extends Component<IProps> { | 17 | class ImportScreen extends Component<IProps> { |
diff --git a/src/containers/auth/LockedScreen.tsx b/src/containers/auth/LockedScreen.tsx index e6bb5e8e4..500bff0d6 100644 --- a/src/containers/auth/LockedScreen.tsx +++ b/src/containers/auth/LockedScreen.tsx | |||
@@ -1,20 +1,20 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import { inject, observer } from 'mobx-react'; | 2 | import { inject, observer } from 'mobx-react'; |
3 | import { SettingsStore } from 'src/stores.types'; | ||
3 | import Locked from '../../components/auth/Locked'; | 4 | import Locked from '../../components/auth/Locked'; |
4 | import SettingsStore from '../../stores/SettingsStore'; | ||
5 | 5 | ||
6 | import { hash } from '../../helpers/password-helpers'; | 6 | import { hash } from '../../helpers/password-helpers'; |
7 | import UserStore from '../../stores/UserStore'; | 7 | import UserStore from '../../stores/UserStore'; |
8 | 8 | ||
9 | interface IProps { | 9 | interface IProps { |
10 | actions: { | 10 | actions: { |
11 | settings: SettingsStore, | 11 | settings: SettingsStore; |
12 | }, | 12 | }; |
13 | stores: { | 13 | stores: { |
14 | settings: SettingsStore, | 14 | settings: SettingsStore; |
15 | user: UserStore, | 15 | user: UserStore; |
16 | } | 16 | }; |
17 | }; | 17 | } |
18 | 18 | ||
19 | class LockedScreen extends Component<IProps> { | 19 | class LockedScreen extends Component<IProps> { |
20 | state = { | 20 | state = { |
@@ -28,7 +28,7 @@ class LockedScreen extends Component<IProps> { | |||
28 | this.unlock = this.unlock.bind(this); | 28 | this.unlock = this.unlock.bind(this); |
29 | } | 29 | } |
30 | 30 | ||
31 | onSubmit(values) { | 31 | onSubmit(values): void { |
32 | const { password } = values; | 32 | const { password } = values; |
33 | 33 | ||
34 | let correctPassword = this.props.stores.settings.all.app.lockedPassword; | 34 | let correctPassword = this.props.stores.settings.all.app.lockedPassword; |
@@ -52,7 +52,7 @@ class LockedScreen extends Component<IProps> { | |||
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | unlock() { | 55 | unlock(): void { |
56 | this.props.actions.settings.update({ | 56 | this.props.actions.settings.update({ |
57 | type: 'app', | 57 | type: 'app', |
58 | data: { | 58 | data: { |
@@ -61,7 +61,7 @@ class LockedScreen extends Component<IProps> { | |||
61 | }); | 61 | }); |
62 | } | 62 | } |
63 | 63 | ||
64 | render() { | 64 | render(): ReactElement { |
65 | const { stores } = this.props; | 65 | const { stores } = this.props; |
66 | const { useTouchIdToUnlock } = this.props.stores.settings.all.app; | 66 | const { useTouchIdToUnlock } = this.props.stores.settings.all.app; |
67 | 67 | ||
diff --git a/src/containers/auth/PasswordScreen.tsx b/src/containers/auth/PasswordScreen.tsx index 864a11fa7..d88549712 100644 --- a/src/containers/auth/PasswordScreen.tsx +++ b/src/containers/auth/PasswordScreen.tsx | |||
@@ -1,15 +1,15 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
2 | import { inject, observer } from 'mobx-react'; | 2 | import { inject, observer } from 'mobx-react'; |
3 | import { UserStore } from 'src/stores.types'; | ||
3 | import Password from '../../components/auth/Password'; | 4 | import Password from '../../components/auth/Password'; |
4 | import UserStore from '../../stores/UserStore'; | ||
5 | 5 | ||
6 | interface IProps { | 6 | interface IProps { |
7 | actions: { | 7 | actions: { |
8 | user: UserStore, | 8 | user: UserStore; |
9 | }, | 9 | }; |
10 | stores: { | 10 | stores: { |
11 | user: UserStore, | 11 | user: UserStore; |
12 | } | 12 | }; |
13 | }; | 13 | }; |
14 | 14 | ||
15 | class PasswordScreen extends Component<IProps> { | 15 | class PasswordScreen extends Component<IProps> { |
diff --git a/src/electron-util.ts b/src/electron-util.ts index 4576de9a6..6250366dc 100644 --- a/src/electron-util.ts +++ b/src/electron-util.ts | |||
@@ -3,7 +3,7 @@ | |||
3 | import * as electron from 'electron'; | 3 | import * as electron from 'electron'; |
4 | import { initialize, enable } from '@electron/remote/main'; | 4 | import { initialize, enable } from '@electron/remote/main'; |
5 | 5 | ||
6 | export const initializeRemote = () => { | 6 | export const initializeRemote = (): void => { |
7 | if (process.type !== 'browser') { | 7 | if (process.type !== 'browser') { |
8 | throw new Error( | 8 | throw new Error( |
9 | 'The remote api must be initialized from the main process.', | 9 | 'The remote api must be initialized from the main process.', |
@@ -13,7 +13,7 @@ export const initializeRemote = () => { | |||
13 | initialize(); | 13 | initialize(); |
14 | }; | 14 | }; |
15 | 15 | ||
16 | export const enableWebContents = (webContents: electron.WebContents) => { | 16 | export const enableWebContents = (webContents: electron.WebContents): void => { |
17 | enable(webContents); | 17 | enable(webContents); |
18 | }; | 18 | }; |
19 | 19 | ||
diff --git a/src/enforce-macos-app-location.ts b/src/enforce-macos-app-location.ts index 882a4664b..3661d08a5 100644 --- a/src/enforce-macos-app-location.ts +++ b/src/enforce-macos-app-location.ts | |||
@@ -4,7 +4,7 @@ import { isMac } from './environment'; | |||
4 | import { isDevMode } from './environment-remote'; | 4 | import { isDevMode } from './environment-remote'; |
5 | import { api } from './electron-util'; | 5 | import { api } from './electron-util'; |
6 | 6 | ||
7 | export function enforceMacOSAppLocation() { | 7 | export function enforceMacOSAppLocation(): void { |
8 | if (isDevMode || !isMac || api.app.isInApplicationsFolder()) { | 8 | if (isDevMode || !isMac || api.app.isInApplicationsFolder()) { |
9 | return; | 9 | return; |
10 | } | 10 | } |
diff --git a/src/environment-remote.ts b/src/environment-remote.ts index 298004b90..0cd5d2ce4 100644 --- a/src/environment-remote.ts +++ b/src/environment-remote.ts | |||
@@ -26,8 +26,8 @@ import { | |||
26 | import * as buildInfo from './buildInfo.json'; | 26 | import * as buildInfo from './buildInfo.json'; |
27 | 27 | ||
28 | export const { app } = electronApi; | 28 | export const { app } = electronApi; |
29 | export const ferdiumVersion = app.getVersion(); | 29 | export const ferdiumVersion: string = app.getVersion(); |
30 | export const ferdiumLocale = app.getLocale(); | 30 | export const ferdiumLocale: string = app.getLocale(); |
31 | 31 | ||
32 | // Set app directory before loading user modules | 32 | // Set app directory before loading user modules |
33 | if (process.env.FERDIUM_APPDATA_DIR != null) { | 33 | if (process.env.FERDIUM_APPDATA_DIR != null) { |
@@ -44,7 +44,7 @@ if (process.env.FERDIUM_APPDATA_DIR != null) { | |||
44 | app.setPath('userData', join(app.getPath('appData'), app.name)); | 44 | app.setPath('userData', join(app.getPath('appData'), app.name)); |
45 | } | 45 | } |
46 | 46 | ||
47 | export const isDevMode = | 47 | export const isDevMode: boolean = |
48 | process.env.ELECTRON_IS_DEV !== undefined | 48 | process.env.ELECTRON_IS_DEV !== undefined |
49 | ? Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1 | 49 | ? Number.parseInt(process.env.ELECTRON_IS_DEV, 10) === 1 |
50 | : !app.isPackaged; | 50 | : !app.isPackaged; |
@@ -52,11 +52,11 @@ if (isDevMode) { | |||
52 | app.setPath('userData', join(app.getPath('appData'), `${app.name}Dev`)); | 52 | app.setPath('userData', join(app.getPath('appData'), `${app.name}Dev`)); |
53 | } | 53 | } |
54 | 54 | ||
55 | export function userDataPath(...segments: string[]) { | 55 | export function userDataPath(...segments: string[]): string { |
56 | return join(app.getPath('userData'), ...[segments].flat()); | 56 | return join(app.getPath('userData'), ...[segments].flat()); |
57 | } | 57 | } |
58 | 58 | ||
59 | export function userDataRecipesPath(...segments: string[]) { | 59 | export function userDataRecipesPath(...segments: string[]): string { |
60 | return userDataPath('recipes', ...[segments].flat()); | 60 | return userDataPath('recipes', ...[segments].flat()); |
61 | } | 61 | } |
62 | 62 | ||
@@ -84,13 +84,13 @@ if (!isDevMode || (isDevMode && useLiveAPI)) { | |||
84 | todos = PRODUCTION_TODOS_FRONTEND_URL; | 84 | todos = PRODUCTION_TODOS_FRONTEND_URL; |
85 | } | 85 | } |
86 | 86 | ||
87 | export const API = api; | 87 | export const API: string = api; |
88 | export const API_VERSION = 'v1'; | 88 | export const API_VERSION: string = 'v1'; |
89 | export const WS_API = wsApi; | 89 | export const WS_API: string = wsApi; |
90 | export const WEBSITE = web; | 90 | export const WEBSITE: string = web; |
91 | export const TODOS_FRONTEND = todos; | 91 | export const TODOS_FRONTEND: string = todos; |
92 | 92 | ||
93 | export function aboutAppDetails() { | 93 | export function aboutAppDetails(): string { |
94 | return [ | 94 | return [ |
95 | `Version: ${ferdiumVersion}`, | 95 | `Version: ${ferdiumVersion}`, |
96 | `Electron: ${electronVersion}`, | 96 | `Electron: ${electronVersion}`, |
diff --git a/src/environment.ts b/src/environment.ts index 7208b16b6..271bc7571 100644 --- a/src/environment.ts +++ b/src/environment.ts | |||
@@ -6,18 +6,18 @@ export const isMac = process.platform === 'darwin'; | |||
6 | export const isWindows = process.platform === 'win32'; | 6 | export const isWindows = process.platform === 'win32'; |
7 | export const isLinux = process.platform === 'linux'; | 7 | export const isLinux = process.platform === 'linux'; |
8 | 8 | ||
9 | export const electronVersion = process.versions.electron; | 9 | export const electronVersion: string = process.versions.electron; |
10 | export const chromeVersion = process.versions.chrome; | 10 | export const chromeVersion: string = process.versions.chrome; |
11 | export const nodeVersion = process.versions.node; | 11 | export const nodeVersion: string = process.versions.node; |
12 | 12 | ||
13 | export const osArch = arch(); | 13 | export const osArch: string = arch(); |
14 | export const osRelease = release(); | 14 | export const osRelease: string = release(); |
15 | export const is64Bit = osArch.match(/64/); | 15 | export const is64Bit: RegExpMatchArray | null = osArch.match(/64/); |
16 | 16 | ||
17 | // for accelerator, show the shortform that electron/OS understands | 17 | // for accelerator, show the shortform that electron/OS understands |
18 | // for tooltip, show symbol | 18 | // for tooltip, show symbol |
19 | const ctrlKey = isMac ? '⌘' : 'Ctrl'; | 19 | const ctrlKey: string = isMac ? '⌘' : 'Ctrl'; |
20 | const cmdKey = isMac ? 'Cmd' : 'Ctrl'; | 20 | const cmdKey: string = isMac ? 'Cmd' : 'Ctrl'; |
21 | 21 | ||
22 | export const altKey = (isAccelerator = true) => | 22 | export const altKey = (isAccelerator = true) => |
23 | !isAccelerator && isMac ? '⌥' : 'Alt'; | 23 | !isAccelerator && isMac ? '⌥' : 'Alt'; |
diff --git a/src/routes.tsx b/src/routes.tsx index b8f649740..490d13ee8 100644 --- a/src/routes.tsx +++ b/src/routes.tsx | |||
@@ -1,4 +1,4 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, ReactElement } from 'react'; |
2 | import { inject, observer } from 'mobx-react'; | 2 | import { inject, observer } from 'mobx-react'; |
3 | import { Router, Route, IndexRedirect } from 'react-router'; | 3 | import { Router, Route, IndexRedirect } from 'react-router'; |
4 | 4 | ||
@@ -31,8 +31,7 @@ type Props = { | |||
31 | }; | 31 | }; |
32 | 32 | ||
33 | class Routes extends Component<Props> { | 33 | class Routes extends Component<Props> { |
34 | render() { | 34 | render(): ReactElement { |
35 | |||
36 | const { history } = this.props; | 35 | const { history } = this.props; |
37 | 36 | ||
38 | return ( | 37 | return ( |
diff --git a/src/stores.types.ts b/src/stores.types.ts index 24eefc416..1899db92c 100644 --- a/src/stores.types.ts +++ b/src/stores.types.ts | |||
@@ -2,6 +2,7 @@ import Workspace from './features/workspaces/models/Workspace'; | |||
2 | import Recipe from './models/Recipe'; | 2 | import Recipe from './models/Recipe'; |
3 | import Service from './models/Service'; | 3 | import Service from './models/Service'; |
4 | import User from './models/User'; | 4 | import User from './models/User'; |
5 | import { Request } from './stores/lib/Request'; | ||
5 | import { CachedRequest } from './stores/lib/CachedRequest'; | 6 | import { CachedRequest } from './stores/lib/CachedRequest'; |
6 | import Reaction from './stores/lib/Reaction'; | 7 | import Reaction from './stores/lib/Reaction'; |
7 | 8 | ||
@@ -98,6 +99,7 @@ interface AppStore extends TypedStore { | |||
98 | isSystemDarkModeEnabled: () => void; | 99 | isSystemDarkModeEnabled: () => void; |
99 | isSystemMuteOverridden: () => void; | 100 | isSystemMuteOverridden: () => void; |
100 | locale: () => void; | 101 | locale: () => void; |
102 | lockedPassword: string; | ||
101 | reloadAfterResume: boolean; | 103 | reloadAfterResume: boolean; |
102 | reloadAfterResumeTime: number; | 104 | reloadAfterResumeTime: number; |
103 | searchEngine: string; | 105 | searchEngine: string; |
@@ -192,7 +194,7 @@ interface RouterStore { | |||
192 | 194 | ||
193 | export interface ServicesStore extends TypedStore { | 195 | export interface ServicesStore extends TypedStore { |
194 | clearCacheRequest: () => void; | 196 | clearCacheRequest: () => void; |
195 | createServiceRequest: () => void; | 197 | createServiceRequest: CachedRequest; |
196 | deleteServiceRequest: () => void; | 198 | deleteServiceRequest: () => void; |
197 | allServicesRequest: CachedRequest; | 199 | allServicesRequest: CachedRequest; |
198 | filterNeedle: string; | 200 | filterNeedle: string; |
@@ -216,7 +218,9 @@ interface ISettings { | |||
216 | [key: string]: any; | 218 | [key: string]: any; |
217 | } | 219 | } |
218 | 220 | ||
219 | interface SettingsStore extends TypedStore { | 221 | export interface SettingsStore extends TypedStore { |
222 | update: (value: any) => void; | ||
223 | remove: (value: any) => void; | ||
220 | fileSystemSettingsTypes: any[]; | 224 | fileSystemSettingsTypes: any[]; |
221 | loaded: boolean; | 225 | loaded: boolean; |
222 | updateAppSettingsRequest: () => void; | 226 | updateAppSettingsRequest: () => void; |
@@ -247,6 +251,7 @@ interface TodosStore extends TypedStore { | |||
247 | isFeatureEnabledByUser: () => void; | 251 | isFeatureEnabledByUser: () => void; |
248 | isTodoUrlValid: () => void; | 252 | isTodoUrlValid: () => void; |
249 | isTodosPanelForceHidden: () => void; | 253 | isTodosPanelForceHidden: () => void; |
254 | isTodosEnabled: boolean; | ||
250 | isTodosPanelVisible: () => void; | 255 | isTodosPanelVisible: () => void; |
251 | isUsingPredefinedTodoServer: () => void; | 256 | isUsingPredefinedTodoServer: () => void; |
252 | settings: { | 257 | settings: { |
@@ -274,7 +279,7 @@ interface UIStore extends TypedStore { | |||
274 | theme: () => void; | 279 | theme: () => void; |
275 | } | 280 | } |
276 | 281 | ||
277 | interface UserStore extends TypedStore { | 282 | export interface UserStore extends TypedStore { |
278 | BASE_ROUTE: '/auth'; | 283 | BASE_ROUTE: '/auth'; |
279 | CHANGE_SERVER_ROUTE: '/auth/server'; | 284 | CHANGE_SERVER_ROUTE: '/auth/server'; |
280 | IMPORT_ROUTE: '/auth/signup/import'; | 285 | IMPORT_ROUTE: '/auth/signup/import'; |
@@ -293,30 +298,34 @@ interface UserStore extends TypedStore { | |||
293 | getUserInfoRequest: CachedRequest; | 298 | getUserInfoRequest: CachedRequest; |
294 | hasCompletedSignup: () => void; | 299 | hasCompletedSignup: () => void; |
295 | id: () => void; | 300 | id: () => void; |
301 | importLegacyServices: () => Promise<void>; | ||
296 | inviteRequest: () => void; | 302 | inviteRequest: () => void; |
297 | isImportLegacyServicesCompleted: () => void; | 303 | isImportLegacyServicesCompleted: boolean; |
298 | isImportLegacyServicesExecuting: () => void; | 304 | isImportLegacyServicesExecuting: boolean; |
299 | isLoggingOut: () => void; | 305 | isLoggingOut: () => void; |
300 | loginRequest: () => void; | 306 | loginRequest: () => void; |
301 | logoutReason: () => void; | 307 | logoutReason: () => void; |
302 | logoutReasonTypes: { SERVER: 'SERVER' }; | 308 | logoutReasonTypes: { SERVER: 'SERVER' }; |
303 | passwordRequest: () => void; | 309 | passwordRequest: Request; |
310 | retrievePassword: Promise<void> | ||
304 | signupRequest: () => void; | 311 | signupRequest: () => void; |
305 | updateUserInfoRequest: () => void; | 312 | updateUserInfoRequest: () => void; |
306 | userData: () => void; | 313 | userData: () => void; |
307 | _requireAuthenticatedUser: () => void; | 314 | _requireAuthenticatedUser: () => void; |
315 | _importLegacyServices: () => void; | ||
316 | _retrievePassword: () => void; | ||
308 | changeServerRoute: () => void; | 317 | changeServerRoute: () => void; |
309 | data: User; | 318 | data: User; |
310 | importRoute: () => void; | 319 | importRoute: string; |
311 | inviteRoute: () => void; | 320 | inviteRoute: string; |
312 | isLoggedIn: boolean; | 321 | isLoggedIn: boolean; |
313 | isTokenExpired: () => boolean; | 322 | isTokenExpired: boolean; |
314 | legacyServices: () => void; | 323 | legacyServices: () => void; |
315 | loginRoute: () => void; | 324 | loginRoute: string; |
316 | logoutRoute: () => void; | 325 | logoutRoute: string; |
317 | passwordRoute: () => void; | 326 | passwordRoute: string; |
318 | setupRoute: () => void; | 327 | setupRoute: string; |
319 | signupRoute: () => void; | 328 | signupRoute: string; |
320 | team: () => void; | 329 | team: () => void; |
321 | } | 330 | } |
322 | 331 | ||
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'; | |||
2 | import { getCurrentWindow } from '@electron/remote'; | 2 | import { getCurrentWindow } from '@electron/remote'; |
3 | import { action, computed, observable, reaction } from 'mobx'; | 3 | import { action, computed, observable, reaction } from 'mobx'; |
4 | import localStorage from 'mobx-localstorage'; | 4 | import localStorage from 'mobx-localstorage'; |
5 | import { Stores } from 'src/stores.types'; | ||
6 | import { ApiInterface } from 'src/api'; | ||
7 | import { Actions } from 'src/actions/lib/actions'; | ||
5 | import { | 8 | import { |
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'; |
10 | import { hash } from '../helpers/password-helpers'; | 13 | import { hash } from '../helpers/password-helpers'; |
11 | import Request from './lib/Request'; | 14 | import Request from './lib/Request'; |
12 | import Store from './lib/Store'; | 15 | import TypedStore from './lib/TypedStore'; |
13 | 16 | ||
14 | const debug = require('../preload-safe-debug')('Ferdium:SettingsStore'); | 17 | const debug = require('../preload-safe-debug')('Ferdium:SettingsStore'); |
15 | 18 | ||
16 | export default class SettingsStore extends Store { | 19 | export 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 @@ | |||
1 | import { action, observable, computed, reaction } from 'mobx'; | 1 | import { action, observable, computed, reaction } from 'mobx'; |
2 | import { nativeTheme } from '@electron/remote'; | 2 | import { nativeTheme } from '@electron/remote'; |
3 | 3 | ||
4 | import { theme, ThemeType } from '../themes'; | 4 | import { Stores } from 'src/stores.types'; |
5 | import Store from './lib/Store'; | 5 | import { ApiInterface } from 'src/api'; |
6 | import { Actions } from 'src/actions/lib/actions'; | ||
7 | import { Theme, theme, ThemeType } from '../themes'; | ||
8 | import TypedStore from './lib/TypedStore'; | ||
6 | 9 | ||
7 | export default class UIStore extends Store { | 10 | export 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'; | |||
4 | import localStorage from 'mobx-localstorage'; | 4 | import localStorage from 'mobx-localstorage'; |
5 | import { ipcRenderer } from 'electron'; | 5 | import { ipcRenderer } from 'electron'; |
6 | 6 | ||
7 | import { ApiInterface } from 'src/api'; | ||
8 | import { Actions } from 'src/actions/lib/actions'; | ||
9 | import { Stores } from 'src/stores.types'; | ||
7 | import { TODOS_PARTITION_ID } from '../config'; | 10 | import { TODOS_PARTITION_ID } from '../config'; |
8 | import { isDevMode } from '../environment-remote'; | 11 | import { isDevMode } from '../environment-remote'; |
9 | import Store from './lib/Store'; | ||
10 | import Request from './lib/Request'; | 12 | import Request from './lib/Request'; |
11 | import CachedRequest from './lib/CachedRequest'; | 13 | import CachedRequest from './lib/CachedRequest'; |
14 | import TypedStore from './lib/TypedStore'; | ||
12 | 15 | ||
13 | const debug = require('../preload-safe-debug')('Ferdium:UserStore'); | 16 | const 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 |
16 | export default class UserStore extends Store { | 19 | export 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 @@ | |||
1 | import { computed, observable } from 'mobx'; | ||
2 | import Reaction from './Reaction'; | ||
3 | |||
4 | export 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 | } | ||