feat: setup redux store for settings

This commit is contained in:
鲁树人
2023-06-03 14:09:11 +01:00
parent 953f0d524d
commit b136bac9b6
9 changed files with 150 additions and 14 deletions

View File

@ -0,0 +1,45 @@
import { debounce } from 'radash';
import { produce } from 'immer';
import type { AppStore } from '~/store';
import { SettingsState, settingsSlice, updateSettings } from './settingsSlice';
import { enumObject } from '~/util/objects';
import { getLogger } from '~/util/logUtils';
const DEFAULT_STORAGE_KEY = 'um-react-settings';
function mergeSettings(settings: SettingsState): SettingsState {
return produce(settingsSlice.getInitialState(), (draft) => {
for (const [k, v] of enumObject(settings.qmc2?.keys)) {
if (typeof v === 'string') {
draft.qmc2.keys[k] = v;
}
}
});
}
export function persistSettings(store: AppStore, storageKey = DEFAULT_STORAGE_KEY) {
let lastSettings: unknown;
try {
const loadedSettings: SettingsState = JSON.parse(localStorage.getItem(storageKey) ?? '');
if (loadedSettings) {
const mergedSettings = mergeSettings(loadedSettings);
store.dispatch(updateSettings(mergedSettings));
getLogger().debug('settings loaded');
}
} catch {
// load failed, ignore.
}
return store.subscribe(
debounce({ delay: 150 }, () => {
const currentSettings = store.getState().settings;
if (lastSettings !== currentSettings) {
lastSettings = currentSettings;
localStorage.setItem(storageKey, JSON.stringify(currentSettings));
getLogger().debug('settings saved');
}
})
);
}

View File

@ -0,0 +1,31 @@
import { createSlice } from '@reduxjs/toolkit';
import type { PayloadAction } from '@reduxjs/toolkit';
export interface QMCSettings {
keys: Record<string, string>; // { [fileName]: ekey }
}
export interface SettingsState {
qmc2: QMCSettings;
}
const initialState: SettingsState = {
qmc2: { keys: {} },
};
export const settingsSlice = createSlice({
name: 'settings',
initialState,
reducers: {
updateSettings: (_state, { payload }: PayloadAction<SettingsState>) => {
return payload;
},
resetConfig: () => {
return initialState;
},
},
});
export const { updateSettings, resetConfig } = settingsSlice.actions;
export default settingsSlice.reducer;