save progress in local storage
This commit is contained in:
@@ -17,7 +17,6 @@ import { monacoSetup } from 'lean4web/client/src/monacoSetup';
|
|||||||
|
|
||||||
monacoSetup()
|
monacoSetup()
|
||||||
|
|
||||||
|
|
||||||
const router = createHashRouter([
|
const router = createHashRouter([
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
const KEY = "progress";
|
||||||
|
export function loadState() {
|
||||||
|
try {
|
||||||
|
const serializedState = localStorage.getItem(KEY);
|
||||||
|
if (!serializedState) return undefined;
|
||||||
|
return JSON.parse(serializedState);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveState(state: any) {
|
||||||
|
try {
|
||||||
|
const serializedState = JSON.stringify(state);
|
||||||
|
localStorage.setItem(KEY, serializedState);
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { createSlice } from '@reduxjs/toolkit'
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
import type { PayloadAction } from '@reduxjs/toolkit'
|
import type { PayloadAction } from '@reduxjs/toolkit'
|
||||||
|
import { loadState } from "./localStorage";
|
||||||
|
|
||||||
interface ProgressState {
|
interface ProgressState {
|
||||||
level: {[world: string]: {[level: number]: LevelProgressState}}
|
level: {[world: string]: {[level: number]: LevelProgressState}}
|
||||||
@@ -10,7 +11,7 @@ interface LevelProgressState {
|
|||||||
completed: boolean
|
completed: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialProgressState = { level: {} } as ProgressState
|
const initialProgressState = loadState() ?? { level: {} } as ProgressState
|
||||||
const initalLevelProgressState = {code: "", completed: false} as LevelProgressState
|
const initalLevelProgressState = {code: "", completed: false} as LevelProgressState
|
||||||
|
|
||||||
function addLevelProgress(state, action: PayloadAction<{world: string, level: number}>) {
|
function addLevelProgress(state, action: PayloadAction<{world: string, level: number}>) {
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ import { connection } from '../connection'
|
|||||||
import thunkMiddleware from 'redux-thunk'
|
import thunkMiddleware from 'redux-thunk'
|
||||||
import { apiSlice } from './api'
|
import { apiSlice } from './api'
|
||||||
import { progressSlice } from './progress'
|
import { progressSlice } from './progress'
|
||||||
|
import { saveState } from "./localStorage";
|
||||||
|
import { debounce } from "debounce";
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
[apiSlice.reducerPath]: apiSlice.reducer,
|
[apiSlice.reducerPath]: apiSlice.reducer,
|
||||||
[progressSlice.name]: progressSlice.reducer,
|
[progressSlice.name]: progressSlice.reducer,
|
||||||
},
|
},
|
||||||
|
// Make connection available in thunks:
|
||||||
middleware: getDefaultMiddleware =>
|
middleware: getDefaultMiddleware =>
|
||||||
getDefaultMiddleware({
|
getDefaultMiddleware({
|
||||||
thunk: {
|
thunk: {
|
||||||
@@ -18,6 +20,15 @@ export const store = configureStore({
|
|||||||
}).concat(apiSlice.middleware),
|
}).concat(apiSlice.middleware),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Save progress in local storage
|
||||||
|
store.subscribe(
|
||||||
|
// we use debounce to save the state once each 800ms
|
||||||
|
// for better performances in case multiple changes occur in a short time
|
||||||
|
debounce(() => {
|
||||||
|
saveState(store.getState()[progressSlice.name]);
|
||||||
|
}, 800)
|
||||||
|
);
|
||||||
|
|
||||||
// Infer the `RootState` and `AppDispatch` types from the store itself
|
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||||
export type RootState = ReturnType<typeof store.getState>
|
export type RootState = ReturnType<typeof store.getState>
|
||||||
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
|
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
|
||||||
|
|||||||
Generated
+6
@@ -19,6 +19,7 @@
|
|||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"cytoscape": "^3.23.0",
|
"cytoscape": "^3.23.0",
|
||||||
"cytoscape-klay": "^3.1.4",
|
"cytoscape-klay": "^3.1.4",
|
||||||
|
"debounce": "^1.2.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"lean4web": "github:hhu-adam/lean4web",
|
"lean4web": "github:hhu-adam/lean4web",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
@@ -4202,6 +4203,11 @@
|
|||||||
"url": "https://opencollective.com/date-fns"
|
"url": "https://opencollective.com/date-fns"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/debounce": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.4",
|
"version": "4.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"@types/react-router-dom": "^5.3.3",
|
"@types/react-router-dom": "^5.3.3",
|
||||||
"cytoscape": "^3.23.0",
|
"cytoscape": "^3.23.0",
|
||||||
"cytoscape-klay": "^3.1.4",
|
"cytoscape-klay": "^3.1.4",
|
||||||
|
"debounce": "^1.2.1",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"lean4web": "github:hhu-adam/lean4web",
|
"lean4web": "github:hhu-adam/lean4web",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user