From 5b5dabc84e811c169e3edb2aebf4e56e95f054fd Mon Sep 17 00:00:00 2001 From: Tilman Vatteroth Date: Thu, 8 Jun 2023 14:05:11 +0200 Subject: [PATCH] fix: increase type safety of local storage settings Signed-off-by: Tilman Vatteroth --- .../application-loader/initializers/index.ts | 10 +++++ frontend/src/redux/editor/methods.ts | 33 ++++----------- frontend/src/redux/editor/reducers.ts | 40 ++++++++++++++++--- frontend/src/redux/editor/types.ts | 6 +++ 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/frontend/src/components/application-loader/initializers/index.ts b/frontend/src/components/application-loader/initializers/index.ts index 95e398875..82d197664 100644 --- a/frontend/src/components/application-loader/initializers/index.ts +++ b/frontend/src/components/application-loader/initializers/index.ts @@ -9,6 +9,7 @@ import { isDevMode, isTestMode } from '../../../utils/test-modes' import { fetchAndSetUser } from '../../login-page/auth/utils' import { loadDarkMode } from './load-dark-mode' import { setUpI18n } from './setupI18n' +import { loadFromLocalStorage } from '../../../redux/editor/methods' const logger = new Logger('Application Loader') @@ -62,9 +63,18 @@ export const createSetUpTaskList = (): InitTask[] => { name: 'Load history state', task: refreshHistoryState }, + { + name: 'Load preferences', + task: loadFromLocalStorageAsync + }, { name: 'Add Delay', task: customDelay } ] } + +const loadFromLocalStorageAsync = (): Promise => { + loadFromLocalStorage() + return Promise.resolve() +} diff --git a/frontend/src/redux/editor/methods.ts b/frontend/src/redux/editor/methods.ts index 5baf9f541..9b5e11271 100644 --- a/frontend/src/redux/editor/methods.ts +++ b/frontend/src/redux/editor/methods.ts @@ -4,9 +4,8 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { store } from '..' -import { Logger } from '../../utils/logger' import type { - EditorConfig, + LoadFromLocalStorageAction, SetEditorLigaturesAction, SetEditorLineWrappingAction, SetEditorSmartPasteAction, @@ -14,29 +13,6 @@ import type { } from './types' import { EditorConfigActionType } from './types' -const log = new Logger('Redux > Editor') - -export const loadFromLocalStorage = (): EditorConfig | undefined => { - try { - const stored = window.localStorage.getItem('editorConfig') - if (!stored) { - return undefined - } - return JSON.parse(stored) as EditorConfig - } catch (_) { - return undefined - } -} - -export const saveToLocalStorage = (editorConfig: EditorConfig): void => { - try { - const json = JSON.stringify(editorConfig) - localStorage.setItem('editorConfig', json) - } catch (error) { - log.error('Error while saving editor config in local storage', error) - } -} - export const setEditorSyncScroll = (syncScroll: boolean): void => { const action: SetEditorSyncScrollAction = { type: EditorConfigActionType.SET_SYNC_SCROLL, @@ -68,3 +44,10 @@ export const setEditorSmartPaste = (smartPaste: boolean): void => { } store.dispatch(action) } + +export const loadFromLocalStorage = (): void => { + const action: LoadFromLocalStorageAction = { + type: EditorConfigActionType.LOAD_FROM_LOCAL_STORAGE + } + store.dispatch(action) +} diff --git a/frontend/src/redux/editor/reducers.ts b/frontend/src/redux/editor/reducers.ts index f8c67d224..dd5cb240a 100644 --- a/frontend/src/redux/editor/reducers.ts +++ b/frontend/src/redux/editor/reducers.ts @@ -3,10 +3,12 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { loadFromLocalStorage, saveToLocalStorage } from './methods' import type { EditorConfig, EditorConfigActions } from './types' import { EditorConfigActionType } from './types' import type { Reducer } from 'redux' +import { Logger } from '../../utils/logger' + +const logger = new Logger('EditorConfig Local Storage') const initialState: EditorConfig = { ligatures: true, @@ -16,16 +18,14 @@ const initialState: EditorConfig = { lineWrapping: true } -const getInitialState = (): EditorConfig => { - return { ...initialState, ...loadFromLocalStorage() } -} - export const EditorConfigReducer: Reducer = ( - state: EditorConfig = getInitialState(), + state: EditorConfig = initialState, action: EditorConfigActions ) => { let newState: EditorConfig switch (action.type) { + case EditorConfigActionType.LOAD_FROM_LOCAL_STORAGE: + return loadFromLocalStorage() ?? initialState case EditorConfigActionType.SET_SYNC_SCROLL: newState = { ...state, @@ -65,3 +65,31 @@ export const EditorConfigReducer: Reducer = ( return state } } + +export const loadFromLocalStorage = (): EditorConfig | undefined => { + try { + const stored = window.localStorage.getItem('editorConfig') + if (!stored) { + return undefined + } + const storedConfiguration = JSON.parse(stored) as Record + return { + ligatures: storedConfiguration?.ligatures === true ?? true, + syncScroll: storedConfiguration?.syncScroll === true ?? true, + smartPaste: storedConfiguration?.smartPaste === true ?? true, + spellCheck: storedConfiguration?.spellCheck === true ?? false, + lineWrapping: storedConfiguration?.lineWrapping === true ?? true + } + } catch (_) { + return undefined + } +} + +export const saveToLocalStorage = (editorConfig: EditorConfig): void => { + try { + const json = JSON.stringify(editorConfig) + localStorage.setItem('editorConfig', json) + } catch (error) { + logger.error('Error while saving editor config in local storage', error) + } +} diff --git a/frontend/src/redux/editor/types.ts b/frontend/src/redux/editor/types.ts index 5599fb8c5..e64a5b638 100644 --- a/frontend/src/redux/editor/types.ts +++ b/frontend/src/redux/editor/types.ts @@ -8,6 +8,7 @@ import type { Action } from 'redux' export enum EditorConfigActionType { SET_EDITOR_VIEW_MODE = 'editor/view-mode/set', SET_SYNC_SCROLL = 'editor/syncScroll/set', + LOAD_FROM_LOCAL_STORAGE = 'editor/preferences/load', SET_LIGATURES = 'editor/preferences/setLigatures', SET_LINE_WRAPPING = 'editor/preferences/setLineWrapping', SET_SMART_PASTE = 'editor/preferences/setSmartPaste', @@ -28,6 +29,11 @@ export type EditorConfigActions = | SetEditorSmartPasteAction | SetEditorLineWrappingAction | SetSpellCheckAction + | LoadFromLocalStorageAction + +export interface LoadFromLocalStorageAction extends Action { + type: EditorConfigActionType.LOAD_FROM_LOCAL_STORAGE +} export interface SetEditorLineWrappingAction extends Action { type: EditorConfigActionType.SET_LINE_WRAPPING