From d763b13e44dba14d763f2f15b810d8fcea2b9cda Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Mon, 6 Nov 2017 18:05:12 +0000 Subject: [PATCH] Split into generic and app-specific reducer --- .../lib/components/note-body-viewer.js | 4 +- ReactNativeClient/lib/reducer.js | 106 --------------- ReactNativeClient/root.js | 124 +++++++++++++++++- 3 files changed, 125 insertions(+), 109 deletions(-) diff --git a/ReactNativeClient/lib/components/note-body-viewer.js b/ReactNativeClient/lib/components/note-body-viewer.js index 93ec92547..82af62dda 100644 --- a/ReactNativeClient/lib/components/note-body-viewer.js +++ b/ReactNativeClient/lib/components/note-body-viewer.js @@ -44,8 +44,8 @@ class NoteBodyViewer extends Component { const onCheckboxChange = this.props.onCheckboxChange; const mdOptions = { - onResourceLoaded: function() { - this.forceUpdated(); + onResourceLoaded: () => { + this.forceUpdate(); }, }; diff --git a/ReactNativeClient/lib/reducer.js b/ReactNativeClient/lib/reducer.js index 11e747e03..f62f701fe 100644 --- a/ReactNativeClient/lib/reducer.js +++ b/ReactNativeClient/lib/reducer.js @@ -32,15 +32,6 @@ const defaultState = { windowContentSize: { width: 0, height: 0 }, }; -let navHistory = []; - -function historyCanGoBackTo(route) { - if (route.routeName == 'Note') return false; - if (route.routeName == 'Folder') return false; - - return true; -} - function folderOrNoteDelete(state, action) { let newState = Object.assign({}, state); @@ -121,79 +112,6 @@ const reducer = (state = defaultState, action) => { try { switch (action.type) { - case 'NAV_BACK': - - if (!navHistory.length) break; - - let newAction = null; - while (navHistory.length) { - newAction = navHistory.pop(); - if (newAction.routeName != state.route.routeName) break; - } - - action = newAction ? newAction : navHistory.pop(); - - historyGoingBack = true; - - // Fall throught - - case 'NAV_GO': - - const currentRoute = state.route; - const currentRouteName = currentRoute ? currentRoute.routeName : ''; - - if (!historyGoingBack && historyCanGoBackTo(currentRoute)) { - // If the route *name* is the same (even if the other parameters are different), we - // overwrite the last route in the history with the current one. If the route name - // is different, we push a new history entry. - if (currentRoute.routeName == action.routeName) { - // nothing - } else { - navHistory.push(currentRoute); - } - } - - // HACK: whenever a new screen is loaded, all the previous screens of that type - // are overwritten with the new screen parameters. This is because the way notes - // are currently loaded is not optimal (doesn't retain history properly) so - // this is a simple fix without doing a big refactoring to change the way notes - // are loaded. Might be good enough since going back to different folders - // is probably not a common workflow. - for (let i = 0; i < navHistory.length; i++) { - let n = navHistory[i]; - if (n.routeName == action.routeName) { - navHistory[i] = Object.assign({}, action); - } - } - - if (action.routeName == 'Welcome') navHistory = []; - - //reg.logger().info('Route: ' + currentRouteName + ' => ' + action.routeName); - - newState = Object.assign({}, state); - - if ('noteId' in action) { - newState.selectedNoteId = action.noteId; - } - - if ('folderId' in action) { - newState.selectedFolderId = action.folderId; - newState.notesParentType = 'Folder'; - } - - if ('tagId' in action) { - newState.selectedTagId = action.tagId; - newState.notesParentType = 'Tag'; - } - - if ('itemType' in action) { - newState.selectedItemType = action.itemType; - } - - newState.route = action; - newState.historyCanGoBack = !!navHistory.length; - break; - case 'NOTES_SELECT': newState = Object.assign({}, state); @@ -320,30 +238,6 @@ const reducer = (state = defaultState, action) => { newState = folderOrNoteDelete(state, action); break; - case 'SIDE_MENU_TOGGLE': - - newState = Object.assign({}, state); - newState.showSideMenu = !newState.showSideMenu - break; - - case 'SIDE_MENU_OPEN': - - newState = Object.assign({}, state); - newState.showSideMenu = true - break; - - case 'SIDE_MENU_CLOSE': - - newState = Object.assign({}, state); - newState.showSideMenu = false - break; - - case 'SIDE_MENU_OPEN_PERCENT': - - newState = Object.assign({}, state); - newState.sideMenuOpenPercent = action.value; - break; - case 'SYNC_STARTED': newState = Object.assign({}, state); diff --git a/ReactNativeClient/root.js b/ReactNativeClient/root.js index bdde54dcf..7fce22215 100644 --- a/ReactNativeClient/root.js +++ b/ReactNativeClient/root.js @@ -65,7 +65,129 @@ const generalMiddleware = store => next => async (action) => { return result; } -let store = createStore(reducer, applyMiddleware(generalMiddleware)); +let navHistory = []; + +function historyCanGoBackTo(route) { + if (route.routeName == 'Note') return false; + if (route.routeName == 'Folder') return false; + + return true; +} + +const appReducer = (state = defaultState, action) => { + let newState = state; + let historyGoingBack = false; + + try { + switch (action.type) { + + case 'NAV_BACK': + + if (!navHistory.length) break; + + let newAction = null; + while (navHistory.length) { + newAction = navHistory.pop(); + if (newAction.routeName != state.route.routeName) break; + } + + action = newAction ? newAction : navHistory.pop(); + + historyGoingBack = true; + + // Fall throught + + case 'NAV_GO': + + const currentRoute = state.route; + const currentRouteName = currentRoute ? currentRoute.routeName : ''; + + if (!historyGoingBack && historyCanGoBackTo(currentRoute)) { + // If the route *name* is the same (even if the other parameters are different), we + // overwrite the last route in the history with the current one. If the route name + // is different, we push a new history entry. + if (currentRoute.routeName == action.routeName) { + // nothing + } else { + navHistory.push(currentRoute); + } + } + + // HACK: whenever a new screen is loaded, all the previous screens of that type + // are overwritten with the new screen parameters. This is because the way notes + // are currently loaded is not optimal (doesn't retain history properly) so + // this is a simple fix without doing a big refactoring to change the way notes + // are loaded. Might be good enough since going back to different folders + // is probably not a common workflow. + for (let i = 0; i < navHistory.length; i++) { + let n = navHistory[i]; + if (n.routeName == action.routeName) { + navHistory[i] = Object.assign({}, action); + } + } + + if (action.routeName == 'Welcome') navHistory = []; + + //reg.logger().info('Route: ' + currentRouteName + ' => ' + action.routeName); + + newState = Object.assign({}, state); + + if ('noteId' in action) { + newState.selectedNoteId = action.noteId; + } + + if ('folderId' in action) { + newState.selectedFolderId = action.folderId; + newState.notesParentType = 'Folder'; + } + + if ('tagId' in action) { + newState.selectedTagId = action.tagId; + newState.notesParentType = 'Tag'; + } + + if ('itemType' in action) { + newState.selectedItemType = action.itemType; + } + + newState.route = action; + newState.historyCanGoBack = !!navHistory.length; + break; + + case 'SIDE_MENU_TOGGLE': + + newState = Object.assign({}, state); + newState.showSideMenu = !newState.showSideMenu + break; + + case 'SIDE_MENU_OPEN': + + newState = Object.assign({}, state); + newState.showSideMenu = true + break; + + case 'SIDE_MENU_CLOSE': + + newState = Object.assign({}, state); + newState.showSideMenu = false + break; + + case 'SIDE_MENU_OPEN_PERCENT': + + newState = Object.assign({}, state); + newState.sideMenuOpenPercent = action.value; + break; + + } + } catch (error) { + error.message = 'In reducer: ' + error.message + ' Action: ' + JSON.stringify(action); + throw error; + } + + return reducer(newState, action); +} + +let store = createStore(appReducer, applyMiddleware(generalMiddleware)); async function initialize(dispatch, backButtonHandler) { shimInit();