Skip to content

Commit b9c7c31

Browse files
authored
Merge pull request #38 from CS-Eevee/feat/localforage
Added localForage for persisting state and offline data storage
2 parents 47f3639 + 548ef40 commit b9c7c31

File tree

8 files changed

+667
-201
lines changed

8 files changed

+667
-201
lines changed

package-lock.json

Lines changed: 633 additions & 174 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"enzyme-adapter-react-16": "^1.2.0",
4747
"eslint-plugin-jest": "^21.21.0",
4848
"konva": "^2.1.7",
49+
"localforage": "^1.7.2",
4950
"lodash.throttle": "^4.1.1",
5051
"prettier": "^1.14.2",
5152
"prop-types": "^15.6.2",

src/actionTypes/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export const LOAD_INIT_DATA = 'LOAD_INIT_DATA';
12
export const ADD_COMPONENT = 'ADD_COMPONENT';
23
export const UPDATE_COMPONENT = 'UPDATE_COMPONENT';
34
export const DELETE_COMPONENT = 'DELETE_COMPONENT';

src/actions/components.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
LOAD_INIT_DATA,
23
ADD_COMPONENT,
34
UPDATE_COMPONENT,
45
DELETE_COMPONENT,
@@ -24,9 +25,21 @@ import {
2425
CHANGE_IMAGE_PATH,
2526
} from '../actionTypes/index';
2627

28+
import { loadState } from '../localStorage';
29+
2730
import createFiles from '../utils/createFiles.util';
2831
import createApplicationUtil from '../utils/createApplication.util';
2932

33+
export const loadInitData = () => (dispatch) => {
34+
loadState()
35+
.then(data => dispatch({
36+
type: LOAD_INIT_DATA,
37+
payload: {
38+
data: data ? data.workspace : {},
39+
},
40+
}));
41+
};
42+
3043
export const addNewChild = (({
3144
id, childIndex, childId,
3245
}) => ({

src/containers/AppContainer.jsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ import MainContainer from './MainContainer.jsx';
77
import RightContainer from './RightContainer.jsx';
88
import convertIdToObjs from '../utils/convertIdsToObjs.util';
99
import theme from '../components/theme';
10+
import { loadInitData } from '../actions/components';
1011

1112
const mapStateToProps = store => ({
1213
components: store.workspace.components,
1314
totalComponents: store.workspace.totalComponents,
1415
focusComponent: store.workspace.focusComponent,
1516
});
1617

18+
const mapDispatchToProps = { loadInitData };
19+
1720
class AppContainer extends Component {
1821
state = {
1922
width: 25,
@@ -34,6 +37,10 @@ class AppContainer extends Component {
3437
}
3538
}
3639

40+
componentDidMount() {
41+
this.props.loadInitData();
42+
}
43+
3744
render() {
3845
const { components, totalComponents, focusComponent } = this.props;
3946
const { width, rightColumnOpen } = this.state;
@@ -66,10 +73,11 @@ class AppContainer extends Component {
6673
}
6774
}
6875

69-
export default connect(mapStateToProps)(AppContainer);
76+
export default connect(mapStateToProps, mapDispatchToProps)(AppContainer);
7077

7178
AppContainer.propTypes = {
7279
components: PropTypes.array.isRequired,
7380
totalComponents: PropTypes.number.isRequired,
7481
focusComponent: PropTypes.object.isRequired,
82+
loadInitData: PropTypes.func.isRequired,
7583
};

src/localStorage.js

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,5 @@
1-
export const loadState = () => {
2-
try {
3-
const serializedState = localStorage.getItem('state');
4-
if (serializedState === null) {
5-
return undefined;
6-
}
7-
return JSON.parse(serializedState);
8-
} catch (err) {
9-
return undefined;
10-
}
11-
};
1+
import localforage from 'localforage';
122

3+
export const saveState = state => localforage.setItem('state', state);
134

14-
export const saveState = (state) => {
15-
try {
16-
const serializedState = JSON.stringify(state);
17-
localStorage.setItem('state', serializedState);
18-
} catch (err) {
19-
// Ignore write errors
20-
}
21-
};
5+
export const loadState = () => localforage.getItem('state');

src/reducers/componentReducer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
LOAD_INIT_DATA,
23
ADD_COMPONENT,
34
UPDATE_COMPONENT,
45
DELETE_COMPONENT,
@@ -41,7 +42,6 @@ import {
4142
deleteProp,
4243
} from '../utils/componentReducer.util';
4344

44-
4545
const initialApplicationState = {
4646
totalComponents: 0,
4747
nextId: 1,
@@ -55,6 +55,8 @@ const initialApplicationState = {
5555

5656
const componentReducer = (state = initialApplicationState, action) => {
5757
switch (action.type) {
58+
case LOAD_INIT_DATA:
59+
return { ...state, ...action.payload.data };
5860
case ADD_COMPONENT:
5961
return addComponent(state, action.payload);
6062
case UPDATE_COMPONENT:

src/store.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import logger from 'redux-logger';
2-
// import throttle from 'lodash.throttle';
2+
import throttle from 'lodash.throttle';
33
import { composeWithDevTools } from 'redux-devtools-extension';
44
import { createStore, applyMiddleware, compose } from 'redux';
55
import thunk from 'redux-thunk';
66
import reducers from './reducers';
7-
// import { loadState, saveState } from './localStorage';
8-
9-
// const persistedState = loadState();
7+
import { saveState } from './localStorage';
108

119
const store = createStore(
1210
reducers,
1311
compose(
1412
applyMiddleware(logger, thunk),
1513
composeWithDevTools(),
16-
)
14+
),
1715
);
1816

19-
// store.subscribe(throttle(() => saveState(store.getState()), 1000));
17+
store.subscribe(throttle(() => saveState(store.getState()), 1000));
2018

2119
export default store;

0 commit comments

Comments
 (0)