mirror of
https://git.unlock-music.dev/um/um-react.git
synced 2025-07-07 06:52:07 +08:00
feat: setup redux store for settings
This commit is contained in:
45
src/features/settings/persistSettings.ts
Normal file
45
src/features/settings/persistSettings.ts
Normal 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');
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
31
src/features/settings/settingsSlice.ts
Normal file
31
src/features/settings/settingsSlice.ts
Normal 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;
|
Reference in New Issue
Block a user