Skip to content

Commit

Permalink
fix localstorage bug
Browse files Browse the repository at this point in the history
zurgl committed Dec 20, 2021
1 parent 099a60c commit f863883
Showing 5 changed files with 84 additions and 37 deletions.
22 changes: 16 additions & 6 deletions components/shared/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -3,9 +3,14 @@ import styled from 'styled-components';
import {Row, Col} from 'antd';

import {GlobalContext, globalStateReducer, initGlobalState} from 'context';
import {ChainType, MarkdownForChainIdT, GlobalStateT} from 'types';
import {ChainType, MarkdownForChainIdT, LocalStorageStateT} from 'types';
import {FOOTER_HEIGHT, GRID_LAYOUT, HEADER_HEIGHT} from 'lib/constants';
import {isOneColumnStep, getChainId, mergeState} from 'utils/context';
import {
isOneColumnStep,
getChainId,
prepareGlobalState,
prepareGlobalStateForStorage,
} from 'utils/context';
import {useLocalStorage} from 'hooks';

import Sidebar from './Sidebar';
@@ -20,12 +25,17 @@ type LayoutPropT = {
};

const Layout = ({children, chain, markdown}: LayoutPropT) => {
const [storage, setStorage] = useLocalStorage<GlobalStateT>('figment');
const newState = mergeState(chain.id, storage, initGlobalState);
const [state, dispatch] = useReducer(globalStateReducer, newState);
const [storageState, setStorageState] =
useLocalStorage<LocalStorageStateT>('figment');
const newGlobalState = prepareGlobalState(
storageState,
initGlobalState,
chain.id,
);
const [state, dispatch] = useReducer(globalStateReducer, newGlobalState);

useEffect(() => {
setStorage(state);
setStorageState(prepareGlobalStateForStorage(state));
}, [state, dispatch]);

const isStepOneColumn = isOneColumnStep(state);
9 changes: 1 addition & 8 deletions context/index.tsx
Original file line number Diff line number Diff line change
@@ -84,14 +84,7 @@ export const buildInitialState = (): ProtocolsStateT => {
{} as ProtocolsStateT,
);
};
/*
export const initGlobalState = (currentChainId: CHAINS) => {
return {
currentChainId,
protocols: buildInitialState(),
};
};
*/

export const initGlobalState = {
currentChainId: undefined,
protocols: buildInitialState(),
2 changes: 1 addition & 1 deletion hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ const useLocalStorage = <StateT>(key: string, initialValue?: StateT) => {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
return {};
}
});

5 changes: 5 additions & 0 deletions types/index.ts
Original file line number Diff line number Diff line change
@@ -256,6 +256,11 @@ export type LocalStorageStateT = {

export type LocalStorageProtocolStateT = {
currentStepId: PROTOCOL_STEPS_ID;
steps: {
[Key in PROTOCOL_STEPS_ID]: {
isCompleted: boolean;
};
};
innerState?: InnerStateT;
};

83 changes: 61 additions & 22 deletions utils/context.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import {defaultsDeep, difference, keys, omit} from 'lodash';

import {
GlobalStateT,
CHAINS,
@@ -8,8 +6,69 @@ import {
NETWORKS,
ProtocolStepsT,
ProtocolStepT,
LocalStorageStateT,
} from 'types';

export const prepareGlobalStateForStorage = (
globalState: GlobalStateT,
): LocalStorageStateT => {
const chains = Object.keys(globalState.protocols) as CHAINS[];

return chains.reduce((acc: LocalStorageStateT, el: CHAINS) => {
const stepsId = Object.keys(
globalState.protocols[el].steps,
) as PROTOCOL_STEPS_ID[];
const newSteps = stepsId.reduce((acc0, stepId) => {
// @ts-ignore
acc0[stepId] = {
isCompleted: globalState.protocols[el].steps[stepId].isCompleted,
};
return acc0;
}, {});
acc[el] = {
currentStepId: globalState.protocols[el].currentStepId,
// @ts-ignore
steps: newSteps,
innerState: globalState.protocols[el].innerState,
};
return acc;
}, {} as LocalStorageStateT);
};

export const prepareGlobalState = (
localStorage: LocalStorageStateT,
initialGlobalState: GlobalStateT,
chainId: CHAINS,
): GlobalStateT => {
const chains = Object.keys(initialGlobalState.protocols) as CHAINS[];
const newProtocols = chains.reduce(
(protocols: GlobalStateT['protocols'], chain: CHAINS) => {
const stepsId = Object.keys(
protocols[chain].steps,
) as PROTOCOL_STEPS_ID[];
const newSteps = stepsId.reduce((steps, stepId) => {
steps[stepId] = {
...steps[stepId],
...(localStorage ? localStorage[chain].steps[stepId] : {}),
};
return steps;
}, protocols[chain].steps);
protocols[chain] = {
...initialGlobalState.protocols[chain],
...(localStorage ? localStorage[chain] : {}),
steps: newSteps,
};
return protocols;
},
initialGlobalState.protocols,
);

return {
currentChainId: chainId,
protocols: newProtocols,
};
};

// Global State function, upmost level
export const getChainId = (state: GlobalStateT): CHAINS => {
return state.currentChainId as CHAINS;
@@ -230,23 +289,3 @@ export const getInnerState = (state: GlobalStateT) => {

return {network, ...innerState};
};

export const mergeState = (
chainId: CHAINS,
storedState: GlobalStateT,
initialState: GlobalStateT,
): GlobalStateT => {
const storageProtocols = storedState ? {...storedState.protocols} : {};
const initProtocols = {...initialState.protocols};
const removedKeys = difference(keys(storageProtocols), keys(initProtocols));

return storedState
? ({
currentChainId: chainId,
protocols: omit<any>(
defaultsDeep(storageProtocols, initProtocols),
removedKeys,
),
} as GlobalStateT)
: initialState;
};

0 comments on commit f863883

Please sign in to comment.