mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-22 17:08:55 +00:00
Redux: Persist language selection to local storage via middleware and create pattern for future persistence.
This commit is contained in:
parent
27cb5fbee0
commit
cbf2fd39d0
@ -1,3 +1,4 @@
|
|||||||
|
//flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux';
|
import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux';
|
||||||
@ -12,9 +13,11 @@ import createSagaMiddleware from 'redux-saga';
|
|||||||
import notificationsSaga from './sagas/notifications';
|
import notificationsSaga from './sagas/notifications';
|
||||||
import ensSaga from './sagas/ens';
|
import ensSaga from './sagas/ens';
|
||||||
import walletSaga from './sagas/wallet';
|
import walletSaga from './sagas/wallet';
|
||||||
|
import { initialState as configInitialState } from 'reducers/config';
|
||||||
|
import throttle from 'lodash/throttle';
|
||||||
// application styles
|
// application styles
|
||||||
import 'assets/styles/etherwallet-master.less';
|
import 'assets/styles/etherwallet-master.less';
|
||||||
|
import { saveState, loadStatePropertyOrEmptyObject } from 'utils/localStorage';
|
||||||
|
|
||||||
let store;
|
let store;
|
||||||
|
|
||||||
@ -34,10 +37,32 @@ const configureStore = () => {
|
|||||||
middleware = applyMiddleware(sagaMiddleware, routerMiddleware(history));
|
middleware = applyMiddleware(sagaMiddleware, routerMiddleware(history));
|
||||||
}
|
}
|
||||||
|
|
||||||
store = createStore(RootReducer, void 0, middleware);
|
const persistedConfigInitialState = {
|
||||||
|
config: {
|
||||||
|
...configInitialState,
|
||||||
|
...loadStatePropertyOrEmptyObject('config')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const completePersistedInitialState = {
|
||||||
|
...persistedConfigInitialState
|
||||||
|
};
|
||||||
|
|
||||||
|
store = createStore(RootReducer, completePersistedInitialState, middleware);
|
||||||
sagaMiddleware.run(notificationsSaga);
|
sagaMiddleware.run(notificationsSaga);
|
||||||
sagaMiddleware.run(ensSaga);
|
sagaMiddleware.run(ensSaga);
|
||||||
sagaMiddleware.run(walletSaga);
|
sagaMiddleware.run(walletSaga);
|
||||||
|
|
||||||
|
store.subscribe(
|
||||||
|
throttle(() => {
|
||||||
|
saveState({
|
||||||
|
config: {
|
||||||
|
languageSelection: store.getState().config.languageSelection
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
1000
|
||||||
|
);
|
||||||
return store;
|
return store;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ export type State = {
|
|||||||
nodeSelection: string
|
nodeSelection: string
|
||||||
};
|
};
|
||||||
|
|
||||||
const initialState: State = {
|
export const initialState: State = {
|
||||||
languageSelection: languages[0].sign,
|
languageSelection: languages[0].sign,
|
||||||
nodeSelection: Object.keys(NODES)[0]
|
nodeSelection: Object.keys(NODES)[0]
|
||||||
};
|
};
|
||||||
|
33
common/utils/localStorage.js
Normal file
33
common/utils/localStorage.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
export const REDUX_STATE = 'REDUX_STATE';
|
||||||
|
|
||||||
|
export const loadState = () => {
|
||||||
|
try {
|
||||||
|
const serializedState = localStorage.getItem(REDUX_STATE);
|
||||||
|
if (serializedState === null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return JSON.parse(serializedState);
|
||||||
|
} catch (err) {
|
||||||
|
// TODO - log warning? or bubble?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const saveState = state => {
|
||||||
|
try {
|
||||||
|
const serializedState = JSON.stringify(state);
|
||||||
|
localStorage.setItem(REDUX_STATE, serializedState);
|
||||||
|
} catch (err) {
|
||||||
|
// TODO - log warning? or bubble?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const loadStatePropertyOrEmptyObject = (key: string): Object => {
|
||||||
|
const localStorageState = loadState();
|
||||||
|
if (localStorageState) {
|
||||||
|
if (localStorageState.hasOwnProperty(key)) {
|
||||||
|
return localStorageState[key];
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
21
spec/mocks/localStorage.js
Normal file
21
spec/mocks/localStorage.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export default class LocalStorageMock {
|
||||||
|
constructor() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.store = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
getItem(key) {
|
||||||
|
return this.store[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
setItem(key, value) {
|
||||||
|
this.store[key] = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeItem(key) {
|
||||||
|
delete this.store[key];
|
||||||
|
}
|
||||||
|
}
|
38
spec/utils/localStorage.spec.js
Normal file
38
spec/utils/localStorage.spec.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import LocalStorageMock from '../mocks/localStorage';
|
||||||
|
import {
|
||||||
|
loadState,
|
||||||
|
saveState,
|
||||||
|
loadStatePropertyOrEmptyObject,
|
||||||
|
REDUX_STATE
|
||||||
|
} from '../../common/utils/localStorage';
|
||||||
|
|
||||||
|
window.localStorage = new LocalStorageMock();
|
||||||
|
|
||||||
|
describe('saveState', () => {
|
||||||
|
it('should serialize and persist state to local storage under key: "REDUX_STATE"', () => {
|
||||||
|
const persistMe = {
|
||||||
|
foo: 'bar'
|
||||||
|
};
|
||||||
|
saveState(persistMe);
|
||||||
|
expect(JSON.parse(localStorage.getItem(REDUX_STATE))).toEqual(persistMe);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('loadStage', () => {
|
||||||
|
it('should return local storage under KEY: "REDUX_STATE"', () => {
|
||||||
|
const exValue = 'foo';
|
||||||
|
localStorage.setItem(REDUX_STATE, JSON.stringify(exValue));
|
||||||
|
expect(loadState()).toEqual(exValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('loadStatePropertyOrEmptyObject', () => {
|
||||||
|
it('should return property of object from local storage under KEY: "REDUX_STATE"', () => {
|
||||||
|
const serializeThis = {
|
||||||
|
one: 'foo',
|
||||||
|
two: 'bar'
|
||||||
|
};
|
||||||
|
saveState(serializeThis);
|
||||||
|
expect(loadStatePropertyOrEmptyObject('one')).toEqual(serializeThis.one);
|
||||||
|
});
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user