diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index a96a9d96c..e70e9767f 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -1,8 +1,6 @@ import * as types from "constants/action_types"; import lbry from "lbry"; import { - selectIsBackDisabled, - selectIsForwardDisabled, selectUpdateUrl, selectUpgradeDownloadPath, selectUpgradeDownloadItem, @@ -10,6 +8,8 @@ import { selectPageTitle, selectCurrentPage, selectCurrentParams, + selectHistoryBack, + selectHistoryForward, } from "selectors/app"; import { doSearch } from "actions/search"; import { doFetchDaemonSettings } from "actions/settings"; @@ -34,6 +34,7 @@ export function doNavigate(path, params = {}, options = {}) { const state = getState(); const pageTitle = selectPageTitle(state); const historyState = history.state; + dispatch( doHistoryPush({ params, page: historyState.page + 1 }, pageTitle, url) ); @@ -82,19 +83,35 @@ export function doChangePath(path, options = {}) { export function doHistoryBack() { return function(dispatch, getState) { - if (!selectIsBackDisabled(getState())) { - history.back(); - dispatch({ type: types.HISTORY_NAVIGATE }); + // Get back history from stack + const back = selectHistoryBack(getState()); + + if (back) { + // Set location + dispatch(doChangePath(back.location)); + + dispatch({ + type: types.HISTORY_NAVIGATE, + data: { page: back }, + }); } }; } export function doHistoryForward() { return function(dispatch, getState) { - // if (!selectIsForwardDisabled(getState())) { - history.forward(); - dispatch({ type: types.HISTORY_NAVIGATE }); - // } + // Get forward history from stack + const forward = selectHistoryForward(getState()); + + if (forward) { + // Set location + dispatch(doChangePath(forward.location)); + + dispatch({ + type: types.HISTORY_NAVIGATE, + data: { page: forward }, + }); + } }; } @@ -102,7 +119,12 @@ export function doHistoryPush(currentState, title, relativeUrl) { return function(dispatch, getState) { title += " - LBRY"; history.pushState(currentState, title, `#${relativeUrl}`); - dispatch({ type: types.HISTORY_NAVIGATE }); + dispatch({ + type: types.HISTORY_NAVIGATE, + data: { + location: relativeUrl, + }, + }); }; } @@ -281,6 +303,13 @@ export function doDaemonReady() { return function(dispatch, getState) { const path = window.location.hash || "#/discover"; const params = parseQueryParams(path.split("?")[1] || ""); + + // Get first page + const page = { + index: 0, + location: path.replace(/^#/, ""), + }; + history.replaceState( { params, is_first_page: true, page: 1 }, document.title, @@ -289,6 +318,7 @@ export function doDaemonReady() { dispatch(doAuthenticate()); dispatch({ type: types.DAEMON_READY, + data: { page }, }); dispatch(doFetchDaemonSettings()); dispatch(doFileList()); diff --git a/ui/js/reducers/app.js b/ui/js/reducers/app.js index bca90028c..d9e529d0f 100644 --- a/ui/js/reducers/app.js +++ b/ui/js/reducers/app.js @@ -24,11 +24,17 @@ const defaultState = { daemonReady: false, hasSignature: false, badgeNumber: 0, + history: { index: 0, stack: [] }, }; reducers[types.DAEMON_READY] = function(state, action) { + const { history } = state; + const { page } = action.data; + history.stack.push(page); + return Object.assign({}, state, { daemonReady: true, + history, }); }; @@ -165,12 +171,51 @@ reducers[types.WINDOW_FOCUSED] = function(state, action) { }; reducers[types.HISTORY_NAVIGATE] = (state, action) => { - console.log(history.state); - console.log(history.length); - console.log(history.state.page === history.length); + let page = false; + let location = false; + + // Get history from state + const { history } = state; + + if (action.data.page) { + // Get page + page = action.data.page; + } else if (action.data.location) { + // Get new location + location = action.data.location; + } + + // Add new location to stack + if (location) { + const lastItem = history.stack.length - 1; + + // Check for duplicated + let is_duplicate = lastItem > -1 + ? history.stack[lastItem].location === location + : false; + + if (!is_duplicate) { + // Create new page + page = { + index: history.stack.length, + location, + }; + + // Update index + history.index = history.stack.length; + + // Add to stack + history.stack.push(page); + } + } else if (page) { + // Update index + history.index = page.index; + } + return Object.assign({}, state, { - isBackDisabled: history.state.page === 1, - isForwardDisabled: history.state.page > history.length, + history, + isBackDisabled: history.index === 0, // First page + isForwardDisabled: history.index === history.stack.length - 1, // Last page }); }; diff --git a/ui/js/selectors/app.js b/ui/js/selectors/app.js index 552908874..80e66466d 100644 --- a/ui/js/selectors/app.js +++ b/ui/js/selectors/app.js @@ -226,3 +226,25 @@ export const selectIsForwardDisabled = createSelector( _selectState, state => state.isForwardDisabled ); + +export const selectHistoryBack = createSelector(_selectState, state => { + const { history } = state; + const index = history.index - 1; + + // Check if page exists + if (index > -1) { + // Get back history + return history.stack[index]; + } +}); + +export const selectHistoryForward = createSelector(_selectState, state => { + const { history } = state; + const index = history.index + 1; + + // Check if page exists + if (index <= history.stack.length) { + // Get forward history + return history.stack[index]; + } +});