From 739bf6adf57b8711aa0d4c0d7e031ba2da36275f Mon Sep 17 00:00:00 2001 From: 6ea86b96 <6ea86b96@gmail.com> Date: Wed, 19 Jul 2017 15:35:03 +0700 Subject: [PATCH] Use history API to retain scrollY when navigating back --- ui/js/actions/app.js | 31 ++++++++++++++++++++++++++----- ui/js/component/app/index.js | 7 ++++++- ui/js/component/app/view.jsx | 8 ++++++++ ui/js/main.js | 4 ++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/ui/js/actions/app.js b/ui/js/actions/app.js index 35049d435..ae894ca90 100644 --- a/ui/js/actions/app.js +++ b/ui/js/actions/app.js @@ -33,11 +33,11 @@ export function doNavigate(path, params = {}) { const state = getState(); const pageTitle = selectPageTitle(state); - dispatch(doHistoryPush(params, pageTitle, url)); + dispatch(doHistoryPush({ params }, pageTitle, url)); }; } -export function doChangePath(path) { +export function doChangePath(path, options = {}) { return function(dispatch, getState) { dispatch({ type: types.CHANGE_PATH, @@ -48,8 +48,12 @@ export function doChangePath(path) { const state = getState(); const pageTitle = selectPageTitle(state); + const scrollY = options.scrollY; + window.document.title = pageTitle; - window.scrollTo(0, 0); + + if (scrollY) window.scrollTo(0, scrollY); + else window.scrollTo(0, 0); const currentPage = selectCurrentPage(state); if (currentPage === "search") { @@ -67,10 +71,26 @@ export function doHistoryBack() { }; } -export function doHistoryPush(params, title, relativeUrl) { +export function doHistoryPush(currentState, title, relativeUrl) { return function(dispatch, getState) { title += " - LBRY"; - history.pushState(params, title, `#${relativeUrl}`); + history.pushState(currentState, title, `#${relativeUrl}`); + }; +} + +export function doRecordScroll(scroll) { + return function(dispatch, getState) { + const state = getState(); + const historyState = history.state; + + if (!historyState) return; + + historyState.scrollY = scroll; + history.replaceState( + historyState, + document.title, + `#${state.app.currentPath}` + ); }; } @@ -219,6 +239,7 @@ export function doAlertError(errorList) { export function doDaemonReady() { return function(dispatch, getState) { + history.replaceState({}, document.title, `#/discover`); dispatch(doAuthenticate()); dispatch({ type: types.DAEMON_READY, diff --git a/ui/js/component/app/index.js b/ui/js/component/app/index.js index 4c966cb56..0653e6266 100644 --- a/ui/js/component/app/index.js +++ b/ui/js/component/app/index.js @@ -2,7 +2,11 @@ import React from "react"; import { connect } from "react-redux"; import { selectCurrentModal } from "selectors/app"; -import { doCheckUpgradeAvailable, doAlertError } from "actions/app"; +import { + doCheckUpgradeAvailable, + doAlertError, + doRecordScroll, +} from "actions/app"; import { doUpdateBalance } from "actions/wallet"; import App from "./view"; @@ -14,6 +18,7 @@ const perform = dispatch => ({ alertError: errorList => dispatch(doAlertError(errorList)), checkUpgradeAvailable: () => dispatch(doCheckUpgradeAvailable()), updateBalance: balance => dispatch(doUpdateBalance(balance)), + recordScroll: scrollPosition => dispatch(doRecordScroll(scrollPosition)), }); export default connect(select, perform)(App); diff --git a/ui/js/component/app/view.jsx b/ui/js/component/app/view.jsx index bc8264f21..857bd7cf6 100644 --- a/ui/js/component/app/view.jsx +++ b/ui/js/component/app/view.jsx @@ -21,6 +21,14 @@ class App extends React.PureComponent { lbry.balanceSubscribe(balance => { this.props.updateBalance(balance); }); + + this.scrollListener = () => this.props.recordScroll(window.scrollY); + + window.addEventListener("scroll", this.scrollListener); + } + + componentWillUnmount() { + window.removeEventListener("scroll", this.scrollListener); } render() { diff --git a/ui/js/main.js b/ui/js/main.js index 9bef9aae1..041611c30 100644 --- a/ui/js/main.js +++ b/ui/js/main.js @@ -37,10 +37,10 @@ window.addEventListener("popstate", (event, param) => { if (hash !== "") { const url = hash.split("#")[1]; - const params = event.state; + const { params, scrollY } = event.state || {}; const queryString = toQueryString(params); - app.store.dispatch(doChangePath(`${url}?${queryString}`)); + app.store.dispatch(doChangePath(`${url}?${queryString}`, { scrollY })); } else { app.store.dispatch(doChangePath("/discover")); }