diff --git a/utils/localStorage.ts b/utils/localStorage.ts new file mode 100644 index 0000000..cbabb36 --- /dev/null +++ b/utils/localStorage.ts @@ -0,0 +1,15 @@ +export const DownloadStateKey = "download_state" + +export function syncLocalStorage(key: string, state: string | T) { + let stringState = ""; + if (typeof state !== "string") { + stringState = JSON.stringify(state) + } else { + stringState = state + } + localStorage.setItem(key, stringState) +} + +export function stateOrStored(key: string, state: T[]){ + return state.length > 0 ? (localStorage.getItem(key) || []) as T[] : [] +} \ No newline at end of file diff --git a/utils/state/Downloads.tsx b/utils/state/Downloads.tsx index 0579991..f982aa5 100644 --- a/utils/state/Downloads.tsx +++ b/utils/state/Downloads.tsx @@ -1,5 +1,6 @@ import React, { createContext, useReducer } from "react"; import { IPackage } from "../../api/getPackages"; +import { DownloadStateKey, stateOrStored, syncLocalStorage } from "../localStorage"; interface IDownload { Package: IPackage; @@ -15,36 +16,43 @@ interface IDownloadContext { } const Downloads: React.Context = createContext(null); +const initialDownloadState = (localStorage.getItem(DownloadStateKey) || []) as IDownload[]; //TODO: abstract into seperate file function downloadsReducer(state: IDownload[], action) { + let newState: IDownload[] = stateOrStored(DownloadStateKey, state); switch (action.type) { case "add": - return [ - ...state, + newState = [ + ...newState, { Package: action.payload, Version: action.payload.Versions[0] }, ]; + break; case "remove": - return state.filter((e) => e.Package.Id !== action.payload.Id); + newState = newState.filter((e) => e.Package.Id !== action.payload.Id); + break; case "version": - const stateClone: IDownload[] = JSON.parse(JSON.stringify(state)); + const stateClone: IDownload[] = JSON.parse(JSON.stringify(newState)); const verIndex = stateClone.findIndex( (e) => e.Package.Id === action.payload.Package.Id ); stateClone[verIndex].Version = action.payload.Version; - return stateClone; - + newState = stateClone; + break; case "clear": + localStorage.clear() return []; default: throw new Error(); } + syncLocalStorage(DownloadStateKey, newState); + return newState; } const DownloadsWrapper = ({ children }) => { - const [state, dispatch] = useReducer(downloadsReducer, []); + const [state, dispatch] = useReducer(downloadsReducer, initialDownloadState); const addPackage = (item: IPackage) => { dispatch({ type: "add", payload: item });