Merge branch 'history_fix'
This commit is contained in:
commit
f6976c3feb
44 changed files with 399 additions and 450 deletions
|
@ -5,18 +5,10 @@ import {
|
||||||
selectUpgradeDownloadPath,
|
selectUpgradeDownloadPath,
|
||||||
selectUpgradeDownloadItem,
|
selectUpgradeDownloadItem,
|
||||||
selectUpgradeFilename,
|
selectUpgradeFilename,
|
||||||
selectPageTitle,
|
|
||||||
selectCurrentPage,
|
|
||||||
selectCurrentParams,
|
|
||||||
selectHistoryBack,
|
|
||||||
selectHistoryForward,
|
|
||||||
} from "selectors/app";
|
} from "selectors/app";
|
||||||
import { doSearch } from "actions/search";
|
|
||||||
import { doFetchDaemonSettings } from "actions/settings";
|
import { doFetchDaemonSettings } from "actions/settings";
|
||||||
import { doAuthenticate } from "actions/user";
|
import { doAuthenticate } from "actions/user";
|
||||||
import { doFileList } from "actions/file_info";
|
import { doFileList } from "actions/file_info";
|
||||||
import { toQueryString } from "util/query_params";
|
|
||||||
import { parseQueryParams } from "util/query_params";
|
|
||||||
|
|
||||||
const { remote, ipcRenderer, shell } = require("electron");
|
const { remote, ipcRenderer, shell } = require("electron");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
@ -24,130 +16,6 @@ const { download } = remote.require("electron-dl");
|
||||||
const fs = remote.require("fs");
|
const fs = remote.require("fs");
|
||||||
const { lbrySettings: config } = require("../../../app/package.json");
|
const { lbrySettings: config } = require("../../../app/package.json");
|
||||||
|
|
||||||
export function doNavigate(path, params = {}, options = {}) {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
if (!path) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let url = path;
|
|
||||||
if (params) url = `${url}?${toQueryString(params)}`;
|
|
||||||
|
|
||||||
dispatch(doChangePath(url));
|
|
||||||
|
|
||||||
const state = getState();
|
|
||||||
const pageTitle = selectPageTitle(state);
|
|
||||||
const historyState = history.state;
|
|
||||||
|
|
||||||
dispatch(
|
|
||||||
doHistoryPush({ params, page: historyState.page + 1 }, pageTitle, url)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doAuthNavigate(pathAfterAuth = null, params = {}) {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
if (pathAfterAuth) {
|
|
||||||
dispatch({
|
|
||||||
type: types.CHANGE_AFTER_AUTH_PATH,
|
|
||||||
data: {
|
|
||||||
path: `${pathAfterAuth}?${toQueryString(params)}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
dispatch(doNavigate("/auth"));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doChangePath(path, options = {}) {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
dispatch({
|
|
||||||
type: types.CHANGE_PATH,
|
|
||||||
data: {
|
|
||||||
path,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const state = getState();
|
|
||||||
const pageTitle = selectPageTitle(state);
|
|
||||||
const scrollY = options.scrollY;
|
|
||||||
|
|
||||||
window.document.title = pageTitle;
|
|
||||||
|
|
||||||
if (scrollY) window.scrollTo(0, scrollY);
|
|
||||||
else window.scrollTo(0, 0);
|
|
||||||
|
|
||||||
const currentPage = selectCurrentPage(state);
|
|
||||||
if (currentPage === "search") {
|
|
||||||
const params = selectCurrentParams(state);
|
|
||||||
dispatch(doSearch(params.query));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doHistoryBack() {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
// 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) {
|
|
||||||
// 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 },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doHistoryPush(currentState, title, relativeUrl) {
|
|
||||||
return function(dispatch, getState) {
|
|
||||||
title += " - LBRY";
|
|
||||||
history.pushState(currentState, title, `#${relativeUrl}`);
|
|
||||||
dispatch({
|
|
||||||
type: types.HISTORY_NAVIGATE,
|
|
||||||
data: {
|
|
||||||
location: 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}`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function doOpenModal(modal) {
|
export function doOpenModal(modal) {
|
||||||
return {
|
return {
|
||||||
type: types.OPEN_MODAL,
|
type: types.OPEN_MODAL,
|
||||||
|
@ -305,25 +173,8 @@ export function doAlertError(errorList) {
|
||||||
|
|
||||||
export function doDaemonReady() {
|
export function doDaemonReady() {
|
||||||
return function(dispatch, getState) {
|
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,
|
|
||||||
`${path}`
|
|
||||||
);
|
|
||||||
dispatch(doAuthenticate());
|
dispatch(doAuthenticate());
|
||||||
dispatch({
|
dispatch({ type: types.DAEMON_READY });
|
||||||
type: types.DAEMON_READY,
|
|
||||||
data: { page },
|
|
||||||
});
|
|
||||||
dispatch(doFetchDaemonSettings());
|
dispatch(doFetchDaemonSettings());
|
||||||
dispatch(doFileList());
|
dispatch(doFileList());
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,8 @@ import {
|
||||||
selectUrisLoading,
|
selectUrisLoading,
|
||||||
selectTotalDownloadProgress,
|
selectTotalDownloadProgress,
|
||||||
} from "selectors/file_info";
|
} from "selectors/file_info";
|
||||||
import { doCloseModal, doHistoryBack } from "actions/app";
|
import { doCloseModal } from "actions/app";
|
||||||
|
import { doHistoryBack } from "actions/navigation";
|
||||||
import setProgressBar from "util/setProgressBar";
|
import setProgressBar from "util/setProgressBar";
|
||||||
import batchActions from "util/batchActions";
|
import batchActions from "util/batchActions";
|
||||||
|
|
||||||
|
|
104
ui/js/actions/navigation.js
Normal file
104
ui/js/actions/navigation.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
import * as types from "constants/action_types";
|
||||||
|
import {
|
||||||
|
selectPageTitle,
|
||||||
|
selectCurrentPage,
|
||||||
|
selectCurrentParams,
|
||||||
|
selectHistoryStack,
|
||||||
|
selectHistoryIndex,
|
||||||
|
} from "selectors/navigation";
|
||||||
|
import { doSearch } from "actions/search";
|
||||||
|
import { toQueryString } from "util/query_params";
|
||||||
|
|
||||||
|
export function doNavigate(path, params = {}, options = {}) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
if (!path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let url = path;
|
||||||
|
if (params && Object.values(params).length) {
|
||||||
|
url += "?" + toQueryString(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(doChangePath(url, options));
|
||||||
|
|
||||||
|
const pageTitle = selectPageTitle(getState()) + " - LBRY";
|
||||||
|
|
||||||
|
dispatch({
|
||||||
|
type: types.HISTORY_NAVIGATE,
|
||||||
|
data: { url, index: options.index },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doAuthNavigate(pathAfterAuth = null, params = {}) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
if (pathAfterAuth) {
|
||||||
|
dispatch({
|
||||||
|
type: types.CHANGE_AFTER_AUTH_PATH,
|
||||||
|
data: {
|
||||||
|
path: `${pathAfterAuth}?${toQueryString(params)}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dispatch(doNavigate("/auth"));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doChangePath(path, options = {}) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
dispatch({
|
||||||
|
type: types.CHANGE_PATH,
|
||||||
|
data: {
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const state = getState();
|
||||||
|
const scrollY = options.scrollY;
|
||||||
|
|
||||||
|
//I wasn't seeing it scroll to the proper position without this -- possibly because the page isn't fully rendered? Not sure - Jeremy
|
||||||
|
setTimeout(() => {
|
||||||
|
window.scrollTo(0, scrollY ? scrollY : 0);
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
const currentPage = selectCurrentPage(state);
|
||||||
|
if (currentPage === "search") {
|
||||||
|
const params = selectCurrentParams(state);
|
||||||
|
dispatch(doSearch(params.query));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doHistoryTraverse(dispatch, state, modifier) {
|
||||||
|
const stack = selectHistoryStack(state),
|
||||||
|
index = selectHistoryIndex(state) + modifier;
|
||||||
|
|
||||||
|
if (index >= 0 && index < stack.length) {
|
||||||
|
const historyItem = stack[index];
|
||||||
|
return dispatch(
|
||||||
|
doNavigate(historyItem.path, {}, { scrollY: historyItem.scrollY, index })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doHistoryBack() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
return doHistoryTraverse(dispatch, getState(), -1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doHistoryForward() {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
return doHistoryTraverse(dispatch, getState(), 1);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doRecordScroll(scroll) {
|
||||||
|
return function(dispatch, getState) {
|
||||||
|
dispatch({
|
||||||
|
type: types.WINDOW_SCROLLED,
|
||||||
|
data: { scrollY: scroll },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ import * as types from "constants/action_types";
|
||||||
import lbryuri from "lbryuri";
|
import lbryuri from "lbryuri";
|
||||||
import lighthouse from "lighthouse";
|
import lighthouse from "lighthouse";
|
||||||
import { doResolveUri } from "actions/content";
|
import { doResolveUri } from "actions/content";
|
||||||
import { doNavigate, doHistoryPush } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { selectCurrentPage } from "selectors/app";
|
import { selectCurrentPage } from "selectors/navigation";
|
||||||
import batchActions from "util/batchActions";
|
import batchActions from "util/batchActions";
|
||||||
|
|
||||||
export function doSearch(query) {
|
export function doSearch(query) {
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { selectPageTitle } from "selectors/navigation";
|
||||||
|
import { selectUser } from "selectors/user";
|
||||||
import {
|
import {
|
||||||
doCheckUpgradeAvailable,
|
doCheckUpgradeAvailable,
|
||||||
doAlertError,
|
doAlertError,
|
||||||
doRecordScroll,
|
|
||||||
} from "actions/app";
|
} from "actions/app";
|
||||||
|
import { doRecordScroll } from "actions/navigation";
|
||||||
import { doFetchRewardedContent } from "actions/content";
|
import { doFetchRewardedContent } from "actions/content";
|
||||||
import { doUpdateBalance } from "actions/wallet";
|
import { doUpdateBalance } from "actions/wallet";
|
||||||
import { selectUser } from "selectors/user";
|
|
||||||
import App from "./view";
|
import App from "./view";
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
pageTitle: selectPageTitle(state),
|
||||||
user: selectUser(state),
|
user: selectUser(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -30,12 +30,22 @@ class App extends React.PureComponent {
|
||||||
this.scrollListener = () => this.props.recordScroll(window.scrollY);
|
this.scrollListener = () => this.props.recordScroll(window.scrollY);
|
||||||
|
|
||||||
window.addEventListener("scroll", this.scrollListener);
|
window.addEventListener("scroll", this.scrollListener);
|
||||||
|
|
||||||
|
this.setTitleFromProps(this.props);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
window.removeEventListener("scroll", this.scrollListener);
|
window.removeEventListener("scroll", this.scrollListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(props) {
|
||||||
|
this.setTitleFromProps(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTitleFromProps(props) {
|
||||||
|
window.document.title = props.pageTitle;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div id="window">
|
<div id="window">
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { selectPlatform } from "selectors/app";
|
import { selectPlatform, selectCurrentModal } from "selectors/app";
|
||||||
import {
|
import {
|
||||||
makeSelectFileInfoForUri,
|
makeSelectFileInfoForUri,
|
||||||
makeSelectDownloadingForUri,
|
makeSelectDownloadingForUri,
|
||||||
makeSelectLoadingForUri,
|
makeSelectLoadingForUri,
|
||||||
} from "selectors/file_info";
|
} from "selectors/file_info";
|
||||||
import { makeSelectIsAvailableForUri } from "selectors/availability";
|
import { makeSelectIsAvailableForUri } from "selectors/availability";
|
||||||
import { selectCurrentModal } from "selectors/app";
|
|
||||||
import { makeSelectCostInfoForUri } from "selectors/cost_info";
|
import { makeSelectCostInfoForUri } from "selectors/cost_info";
|
||||||
import { doCloseModal, doOpenModal } from "actions/app";
|
import { doCloseModal, doOpenModal } from "actions/app";
|
||||||
import { doFetchAvailability } from "actions/availability";
|
import { doFetchAvailability } from "actions/availability";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doResolveUri } from "actions/content";
|
import { doResolveUri } from "actions/content";
|
||||||
import { selectShowNsfw } from "selectors/settings";
|
import { selectShowNsfw } from "selectors/settings";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {
|
||||||
selectCurrentSearchResults,
|
selectCurrentSearchResults,
|
||||||
selectSearchQuery,
|
selectSearchQuery,
|
||||||
} from "selectors/search";
|
} from "selectors/search";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import FileListSearch from "./view";
|
import FileListSearch from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doResolveUri } from "actions/content";
|
import { doResolveUri } from "actions/content";
|
||||||
import {
|
import {
|
||||||
makeSelectClaimForUri,
|
makeSelectClaimForUri,
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatCredits } from "util/formatCredits";
|
import { formatCredits } from "util/formatCredits";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { selectIsBackDisabled, selectIsForwardDisabled } from "selectors/app";
|
import {
|
||||||
|
selectIsBackDisabled,
|
||||||
|
selectIsForwardDisabled,
|
||||||
|
} from "selectors/navigation";
|
||||||
import { selectBalance } from "selectors/wallet";
|
import { selectBalance } from "selectors/wallet";
|
||||||
import { doNavigate, doHistoryBack, doHistoryForward } from "actions/app";
|
import {
|
||||||
|
doNavigate,
|
||||||
|
doHistoryBack,
|
||||||
|
doHistoryForward,
|
||||||
|
} from "actions/navigation";
|
||||||
import Header from "./view";
|
import Header from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import NsfwOverlay from "./view";
|
import NsfwOverlay from "./view";
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
makeSelectRewardByType,
|
makeSelectRewardByType,
|
||||||
makeSelectIsRewardClaimPending,
|
makeSelectIsRewardClaimPending,
|
||||||
} from "selectors/rewards";
|
} from "selectors/rewards";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doClaimRewardType, doClaimRewardClearError } from "actions/rewards";
|
import { doClaimRewardType, doClaimRewardClearError } from "actions/rewards";
|
||||||
import RewardLink from "./view";
|
import RewardLink from "./view";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import Router from "./view.jsx";
|
import Router from "./view.jsx";
|
||||||
import { selectCurrentPage, selectCurrentParams } from "selectors/app.js";
|
import {
|
||||||
|
selectCurrentPage,
|
||||||
|
selectCurrentParams,
|
||||||
|
} from "selectors/navigation.js";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
params: selectCurrentParams(state),
|
params: selectCurrentParams(state),
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate, doRemoveSnackBarSnack } from "actions/app";
|
import { doRemoveSnackBarSnack } from "actions/app";
|
||||||
import { selectSnackBarSnacks } from "selectors/app";
|
import { selectSnackBarSnacks } from "selectors/app";
|
||||||
import SnackBar from "./view";
|
import SnackBar from "./view";
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
navigate: path => dispatch(doNavigate(path)),
|
|
||||||
removeSnack: () => dispatch(doRemoveSnackBarSnack()),
|
removeSnack: () => dispatch(doRemoveSnackBarSnack()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ class SnackBar extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { navigate, snacks, removeSnack } = this.props;
|
const { snacks, removeSnack } = this.props;
|
||||||
|
|
||||||
if (!snacks.length) {
|
if (!snacks.length) {
|
||||||
this._hideTimeout = null; //should be unmounting anyway, but be safe?
|
this._hideTimeout = null; //should be unmounting anyway, but be safe?
|
||||||
|
@ -33,7 +33,7 @@ class SnackBar extends React.PureComponent {
|
||||||
{linkText &&
|
{linkText &&
|
||||||
linkTarget &&
|
linkTarget &&
|
||||||
<Link
|
<Link
|
||||||
onClick={() => navigate(linkTarget)}
|
navigate={linkTarget}
|
||||||
className="snack-bar__action"
|
className="snack-bar__action"
|
||||||
label={linkText}
|
label={linkText}
|
||||||
/>}
|
/>}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { selectCurrentPage, selectHeaderLinks } from "selectors/app";
|
import { selectCurrentPage, selectHeaderLinks } from "selectors/navigation";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import SubHeader from "./view";
|
import SubHeader from "./view";
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doUserIdentityVerify } from "actions/user";
|
import { doUserIdentityVerify } from "actions/user";
|
||||||
import rewards from "rewards";
|
import rewards from "rewards";
|
||||||
import { makeSelectRewardByType } from "selectors/rewards";
|
import { makeSelectRewardByType } from "selectors/rewards";
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doCloseModal } from "actions/app";
|
import { doCloseModal } from "actions/app";
|
||||||
import { doNavigate, doChangeVolume } from "actions/app";
|
import { doChangeVolume } from "actions/app";
|
||||||
import { selectCurrentModal, selectVolume } from "selectors/app";
|
import { selectCurrentModal, selectVolume } from "selectors/app";
|
||||||
import { doPurchaseUri, doLoadVideo } from "actions/content";
|
import { doPurchaseUri, doLoadVideo } from "actions/content";
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import lbryuri from "lbryuri.js";
|
import lbryuri from "lbryuri.js";
|
||||||
import { selectWunderBarAddress, selectWunderBarIcon } from "selectors/search";
|
import { selectWunderBarAddress, selectWunderBarIcon } from "selectors/search";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import Wunderbar from "./view";
|
import Wunderbar from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
export const CHANGE_PATH = "CHANGE_PATH";
|
|
||||||
export const OPEN_MODAL = "OPEN_MODAL";
|
export const OPEN_MODAL = "OPEN_MODAL";
|
||||||
export const CLOSE_MODAL = "CLOSE_MODAL";
|
export const CLOSE_MODAL = "CLOSE_MODAL";
|
||||||
export const HISTORY_NAVIGATE = "HISTORY_NAVIGATE";
|
|
||||||
export const SHOW_SNACKBAR = "SHOW_SNACKBAR";
|
export const SHOW_SNACKBAR = "SHOW_SNACKBAR";
|
||||||
export const REMOVE_SNACKBAR_SNACK = "REMOVE_SNACKBAR_SNACK";
|
export const REMOVE_SNACKBAR_SNACK = "REMOVE_SNACKBAR_SNACK";
|
||||||
export const WINDOW_FOCUSED = "WINDOW_FOCUSED";
|
export const WINDOW_FOCUSED = "WINDOW_FOCUSED";
|
||||||
export const CHANGE_AFTER_AUTH_PATH = "CHANGE_AFTER_AUTH_PATH";
|
|
||||||
export const DAEMON_READY = "DAEMON_READY";
|
export const DAEMON_READY = "DAEMON_READY";
|
||||||
export const DAEMON_VERSION_MATCH = "DAEMON_VERSION_MATCH";
|
export const DAEMON_VERSION_MATCH = "DAEMON_VERSION_MATCH";
|
||||||
export const DAEMON_VERSION_MISMATCH = "DAEMON_VERSION_MISMATCH";
|
export const DAEMON_VERSION_MISMATCH = "DAEMON_VERSION_MISMATCH";
|
||||||
export const VOLUME_CHANGED = "VOLUME_CHANGED";
|
export const VOLUME_CHANGED = "VOLUME_CHANGED";
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
export const CHANGE_PATH = "CHANGE_PATH";
|
||||||
|
export const CHANGE_AFTER_AUTH_PATH = "CHANGE_AFTER_AUTH_PATH";
|
||||||
|
export const WINDOW_SCROLLED = "WINDOW_SCROLLED";
|
||||||
|
export const HISTORY_NAVIGATE = "HISTORY_NAVIGATE";
|
||||||
|
|
||||||
// Upgrades
|
// Upgrades
|
||||||
export const UPGRADE_CANCELLED = "UPGRADE_CANCELLED";
|
export const UPGRADE_CANCELLED = "UPGRADE_CANCELLED";
|
||||||
export const DOWNLOAD_UPGRADE = "DOWNLOAD_UPGRADE";
|
export const DOWNLOAD_UPGRADE = "DOWNLOAD_UPGRADE";
|
||||||
|
|
|
@ -6,9 +6,9 @@ import SnackBar from "component/snackBar";
|
||||||
import { Provider } from "react-redux";
|
import { Provider } from "react-redux";
|
||||||
import store from "store.js";
|
import store from "store.js";
|
||||||
import SplashScreen from "component/splash";
|
import SplashScreen from "component/splash";
|
||||||
import { doChangePath, doNavigate, doDaemonReady } from "actions/app";
|
import { doDaemonReady } from "actions/app";
|
||||||
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doDownloadLanguages } from "actions/settings";
|
import { doDownloadLanguages } from "actions/settings";
|
||||||
import { toQueryString } from "util/query_params";
|
|
||||||
import * as types from "constants/action_types";
|
import * as types from "constants/action_types";
|
||||||
|
|
||||||
const env = ENV;
|
const env = ENV;
|
||||||
|
@ -28,23 +28,6 @@ window.addEventListener("contextmenu", event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
window.addEventListener("popstate", (event, param) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const hash = document.location.hash;
|
|
||||||
let action;
|
|
||||||
|
|
||||||
if (hash !== "") {
|
|
||||||
const url = hash.replace(/^#/, "");
|
|
||||||
const { params, scrollY } = event.state || {};
|
|
||||||
const queryString = toQueryString(params);
|
|
||||||
|
|
||||||
app.store.dispatch(doChangePath(`${url}?${queryString}`, { scrollY }));
|
|
||||||
} else {
|
|
||||||
app.store.dispatch(doChangePath("/discover"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ipcRenderer.on("open-uri-requested", (event, uri) => {
|
ipcRenderer.on("open-uri-requested", (event, uri) => {
|
||||||
if (uri && uri.startsWith("lbry://")) {
|
if (uri && uri.startsWith("lbry://")) {
|
||||||
app.store.dispatch(doNavigate("/show", { uri }));
|
app.store.dispatch(doNavigate("/show", { uri }));
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doCloseModal, doAuthNavigate } from "actions/app";
|
import { doCloseModal } from "actions/app";
|
||||||
|
import { doAuthNavigate } from "actions/navigation";
|
||||||
import { doSetClientSetting } from "actions/settings";
|
import { doSetClientSetting } from "actions/settings";
|
||||||
import { selectUserIsRewardApproved } from "selectors/user";
|
import { selectUserIsRewardApproved } from "selectors/user";
|
||||||
import { selectBalance } from "selectors/wallet";
|
import { selectBalance } from "selectors/wallet";
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doCloseModal, doNavigate } from "actions/app";
|
import { doCloseModal } from "actions/app";
|
||||||
|
import { doNavigate } from "actions/navigation";
|
||||||
import ModalInsufficientCredits from "./view";
|
import ModalInsufficientCredits from "./view";
|
||||||
|
|
||||||
const select = state => ({});
|
const select = state => ({});
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doCloseModal, doHistoryBack } from "actions/app";
|
import { doCloseModal } from "actions/app";
|
||||||
import { doDeleteFileAndGoBack } from "actions/file_info";
|
import { doDeleteFileAndGoBack } from "actions/file_info";
|
||||||
import { makeSelectClaimForUriIsMine } from "selectors/claims";
|
import { makeSelectClaimForUriIsMine } from "selectors/claims";
|
||||||
import batchActions from "util/batchActions";
|
|
||||||
|
|
||||||
import ModalRemoveFile from "./view";
|
import ModalRemoveFile from "./view";
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { selectCurrentModal, selectCurrentPage } from "selectors/app";
|
|
||||||
import { doOpenModal } from "actions/app";
|
import { doOpenModal } from "actions/app";
|
||||||
|
import * as settings from "constants/settings";
|
||||||
|
import { selectCurrentModal } from "selectors/app";
|
||||||
|
import { selectCurrentPage } from "selectors/navigation";
|
||||||
|
import { selectCostForCurrentPageUri } from "selectors/cost_info";
|
||||||
import { makeSelectClientSetting } from "selectors/settings";
|
import { makeSelectClientSetting } from "selectors/settings";
|
||||||
import { selectUser } from "selectors/user";
|
import { selectUser } from "selectors/user";
|
||||||
import { selectCostForCurrentPageUri } from "selectors/cost_info";
|
|
||||||
import * as settings from "constants/settings";
|
|
||||||
import { selectBalance } from "selectors/wallet";
|
import { selectBalance } from "selectors/wallet";
|
||||||
import ModalRouter from "./view";
|
import ModalRouter from "./view";
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { selectPathAfterAuth } from "selectors/app";
|
import { selectPathAfterAuth } from "selectors/navigation";
|
||||||
import {
|
import {
|
||||||
selectAuthenticationIsPending,
|
selectAuthenticationIsPending,
|
||||||
selectEmailToVerify,
|
selectEmailToVerify,
|
||||||
|
|
|
@ -9,8 +9,8 @@ import {
|
||||||
makeSelectClaimsInChannelForCurrentPage,
|
makeSelectClaimsInChannelForCurrentPage,
|
||||||
makeSelectFetchingChannelClaims,
|
makeSelectFetchingChannelClaims,
|
||||||
} from "selectors/claims";
|
} from "selectors/claims";
|
||||||
import { selectCurrentParams } from "selectors/app";
|
import { selectCurrentParams } from "selectors/navigation";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { makeSelectTotalPagesForChannel } from "selectors/content";
|
import { makeSelectTotalPagesForChannel } from "selectors/content";
|
||||||
import ChannelPage from "./view";
|
import ChannelPage from "./view";
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doFetchFileInfo } from "actions/file_info";
|
import { doFetchFileInfo } from "actions/file_info";
|
||||||
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
import { makeSelectFileInfoForUri } from "selectors/file_info";
|
||||||
import { selectRewardContentClaimIds } from "selectors/content";
|
import { selectRewardContentClaimIds } from "selectors/content";
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
selectIsFetchingClaimListMine,
|
selectIsFetchingClaimListMine,
|
||||||
} from "selectors/claims";
|
} from "selectors/claims";
|
||||||
import { doFetchClaimListMine } from "actions/content";
|
import { doFetchClaimListMine } from "actions/content";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doCancelAllResolvingUris } from "actions/content";
|
import { doCancelAllResolvingUris } from "actions/content";
|
||||||
import FileListDownloaded from "./view";
|
import FileListDownloaded from "./view";
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
selectIsFetchingClaimListMine,
|
selectIsFetchingClaimListMine,
|
||||||
} from "selectors/claims";
|
} from "selectors/claims";
|
||||||
import { doClaimRewardType } from "actions/rewards";
|
import { doClaimRewardType } from "actions/rewards";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import { doCancelAllResolvingUris } from "actions/content";
|
import { doCancelAllResolvingUris } from "actions/content";
|
||||||
import FileListPublished from "./view";
|
import FileListPublished from "./view";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { doAuthNavigate } from "actions/app";
|
import { doAuthNavigate } from "actions/navigation";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doFetchAccessToken } from "actions/user";
|
import { doFetchAccessToken } from "actions/user";
|
||||||
import { selectAccessToken, selectUser } from "selectors/user";
|
import { selectAccessToken, selectUser } from "selectors/user";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { doNavigate, doHistoryBack } from "actions/app";
|
import { doNavigate, doHistoryBack } from "actions/navigation";
|
||||||
import { doClaimRewardType } from "actions/rewards";
|
import { doClaimRewardType } from "actions/rewards";
|
||||||
import {
|
import {
|
||||||
selectMyClaims,
|
selectMyClaims,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
selectUnclaimedRewards,
|
selectUnclaimedRewards,
|
||||||
} from "selectors/rewards";
|
} from "selectors/rewards";
|
||||||
import { selectUser } from "selectors/user";
|
import { selectUser } from "selectors/user";
|
||||||
import { doAuthNavigate, doNavigate } from "actions/app";
|
import { doAuthNavigate, doNavigate } from "actions/navigation";
|
||||||
import { doRewardList } from "actions/rewards";
|
import { doRewardList } from "actions/rewards";
|
||||||
import RewardsPage from "./view";
|
import RewardsPage from "./view";
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
selectSearchQuery,
|
selectSearchQuery,
|
||||||
selectCurrentSearchResults,
|
selectCurrentSearchResults,
|
||||||
} from "selectors/search";
|
} from "selectors/search";
|
||||||
import { doNavigate } from "actions/app";
|
import { doNavigate } from "actions/navigation";
|
||||||
import SearchPage from "./view";
|
import SearchPage from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
import * as types from "constants/action_types";
|
import * as types from "constants/action_types";
|
||||||
import * as modalTypes from "constants/modal_types";
|
import * as modalTypes from "constants/modal_types";
|
||||||
|
|
||||||
const currentPath = () => {
|
|
||||||
const hash = document.location.hash;
|
|
||||||
if (hash !== "") return hash.replace(/^#/, "");
|
|
||||||
else return "/discover";
|
|
||||||
};
|
|
||||||
|
|
||||||
const { remote } = require("electron");
|
const { remote } = require("electron");
|
||||||
const application = remote.app;
|
const application = remote.app;
|
||||||
const win = remote.BrowserWindow.getFocusedWindow();
|
const win = remote.BrowserWindow.getFocusedWindow();
|
||||||
|
@ -14,28 +8,18 @@ const win = remote.BrowserWindow.getFocusedWindow();
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
isLoaded: false,
|
isLoaded: false,
|
||||||
isBackDisabled: true,
|
|
||||||
isForwardDisabled: true,
|
|
||||||
currentPath: currentPath(),
|
|
||||||
pathAfterAuth: "/discover",
|
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
upgradeSkipped: sessionStorage.getItem("upgradeSkipped"),
|
upgradeSkipped: sessionStorage.getItem("upgradeSkipped"),
|
||||||
daemonVersionMatched: null,
|
daemonVersionMatched: null,
|
||||||
daemonReady: false,
|
daemonReady: false,
|
||||||
hasSignature: false,
|
hasSignature: false,
|
||||||
badgeNumber: 0,
|
badgeNumber: 0,
|
||||||
history: { index: 0, stack: [] },
|
|
||||||
volume: sessionStorage.getItem("volume") || 1,
|
volume: sessionStorage.getItem("volume") || 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[types.DAEMON_READY] = function(state, action) {
|
reducers[types.DAEMON_READY] = function(state, action) {
|
||||||
const { history } = state;
|
|
||||||
const { page } = action.data;
|
|
||||||
history.stack.push(page);
|
|
||||||
|
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
daemonReady: true,
|
daemonReady: true,
|
||||||
history,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -52,18 +36,6 @@ reducers[types.DAEMON_VERSION_MISMATCH] = function(state, action) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[types.CHANGE_PATH] = function(state, action) {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
currentPath: action.data.path,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) {
|
|
||||||
return Object.assign({}, state, {
|
|
||||||
pathAfterAuth: action.data.path,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[types.UPGRADE_CANCELLED] = function(state, action) {
|
reducers[types.UPGRADE_CANCELLED] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
downloadProgress: null,
|
downloadProgress: null,
|
||||||
|
@ -171,55 +143,6 @@ reducers[types.WINDOW_FOCUSED] = function(state, action) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers[types.HISTORY_NAVIGATE] = (state, action) => {
|
|
||||||
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, {
|
|
||||||
history,
|
|
||||||
isBackDisabled: history.index === 0, // First page
|
|
||||||
isForwardDisabled: history.index === history.stack.length - 1, // Last page
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
reducers[types.VOLUME_CHANGED] = function(state, action) {
|
reducers[types.VOLUME_CHANGED] = function(state, action) {
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
volume: action.data.volume,
|
volume: action.data.volume,
|
||||||
|
|
85
ui/js/reducers/navigation.js
Normal file
85
ui/js/reducers/navigation.js
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import * as types from "constants/action_types";
|
||||||
|
import { parseQueryParams } from "util/query_params";
|
||||||
|
|
||||||
|
const currentPath = () => {
|
||||||
|
const hash = document.location.hash;
|
||||||
|
if (hash !== "") return hash.replace(/^#/, "");
|
||||||
|
else return "/discover";
|
||||||
|
};
|
||||||
|
|
||||||
|
const reducers = {};
|
||||||
|
const defaultState = {
|
||||||
|
currentPath: currentPath(),
|
||||||
|
pathAfterAuth: "/discover",
|
||||||
|
index: 0,
|
||||||
|
stack: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.DAEMON_READY] = function(state, action) {
|
||||||
|
const { currentPath } = state;
|
||||||
|
const params = parseQueryParams(currentPath.split("?")[1] || "");
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
stack: [{ path: currentPath, scrollY: 0 }],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.CHANGE_PATH] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
currentPath: action.data.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) {
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
pathAfterAuth: action.data.path,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.HISTORY_NAVIGATE] = (state, action) => {
|
||||||
|
const { stack, index } = state;
|
||||||
|
|
||||||
|
let newState = {};
|
||||||
|
|
||||||
|
const path = action.data.url,
|
||||||
|
previousIndex = index - 1;
|
||||||
|
|
||||||
|
// Check for duplicated
|
||||||
|
if (action.data.index >= 0) {
|
||||||
|
newState.index = action.data.index;
|
||||||
|
} else if (
|
||||||
|
previousIndex === -1 ||
|
||||||
|
!stack[previousIndex] ||
|
||||||
|
stack[previousIndex].path !== path
|
||||||
|
) {
|
||||||
|
newState.stack = [...stack.slice(0, index + 1), { path, scrollY: 0 }];
|
||||||
|
newState.index = newState.stack.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
history.replaceState(null, null, "#" + path); //this allows currentPath() to retain the URL on reload
|
||||||
|
|
||||||
|
return Object.assign({}, state, newState);
|
||||||
|
};
|
||||||
|
|
||||||
|
reducers[types.WINDOW_SCROLLED] = (state, action) => {
|
||||||
|
const { stack, index } = state;
|
||||||
|
const { scrollY } = action.data;
|
||||||
|
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
stack: state.stack.map((stackItem, itemIndex) => {
|
||||||
|
if (itemIndex !== index) {
|
||||||
|
return stackItem;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...stackItem,
|
||||||
|
scrollY: scrollY,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function reducer(state = defaultState, action) {
|
||||||
|
const handler = reducers[action.type];
|
||||||
|
if (handler) return handler(state, action);
|
||||||
|
return state;
|
||||||
|
}
|
|
@ -1,88 +1,7 @@
|
||||||
import { createSelector } from "reselect";
|
import { createSelector } from "reselect";
|
||||||
import { parseQueryParams, toQueryString } from "util/query_params";
|
|
||||||
import * as settings from "constants/settings.js";
|
|
||||||
import lbryuri from "lbryuri";
|
|
||||||
|
|
||||||
export const _selectState = state => state.app || {};
|
export const _selectState = state => state.app || {};
|
||||||
|
|
||||||
export const selectIsLoaded = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => state.isLoaded
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectCurrentPath = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => state.currentPath
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectCurrentPage = createSelector(selectCurrentPath, path => {
|
|
||||||
return path.replace(/^\//, "").split("?")[0];
|
|
||||||
});
|
|
||||||
|
|
||||||
export const selectCurrentParams = createSelector(selectCurrentPath, path => {
|
|
||||||
if (path === undefined) return {};
|
|
||||||
if (!path.match(/\?/)) return {};
|
|
||||||
|
|
||||||
return parseQueryParams(path.split("?")[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
export const selectPageTitle = createSelector(
|
|
||||||
selectCurrentPage,
|
|
||||||
selectCurrentParams,
|
|
||||||
(page, params) => {
|
|
||||||
switch (page) {
|
|
||||||
case "settings":
|
|
||||||
return __("Settings");
|
|
||||||
case "report":
|
|
||||||
return __("Report");
|
|
||||||
case "wallet":
|
|
||||||
return __("Wallet");
|
|
||||||
case "send":
|
|
||||||
return __("Send Credits");
|
|
||||||
case "receive":
|
|
||||||
return __("Wallet Address");
|
|
||||||
case "backup":
|
|
||||||
return __("Backup Your Wallet");
|
|
||||||
case "rewards":
|
|
||||||
return __("Rewards");
|
|
||||||
case "invite":
|
|
||||||
return __("Invites");
|
|
||||||
case "start":
|
|
||||||
return __("Start");
|
|
||||||
case "publish":
|
|
||||||
return __("Publish");
|
|
||||||
case "help":
|
|
||||||
return __("Help");
|
|
||||||
case "developer":
|
|
||||||
return __("Developer");
|
|
||||||
case "search":
|
|
||||||
return params.query
|
|
||||||
? __("Search results for %s", params.query)
|
|
||||||
: __("Search");
|
|
||||||
case "show": {
|
|
||||||
const parts = [lbryuri.normalize(params.uri)];
|
|
||||||
// If the params has any keys other than "uri"
|
|
||||||
if (Object.keys(params).length > 1) {
|
|
||||||
parts.push(toQueryString(Object.assign({}, params, { uri: null })));
|
|
||||||
}
|
|
||||||
return parts.join("?");
|
|
||||||
}
|
|
||||||
case "downloaded":
|
|
||||||
return __("Downloads & Purchases");
|
|
||||||
case "published":
|
|
||||||
return __("Publishes");
|
|
||||||
case "discover":
|
|
||||||
return __("Home");
|
|
||||||
case false:
|
|
||||||
case null:
|
|
||||||
case "":
|
|
||||||
return "";
|
|
||||||
default:
|
|
||||||
return page[0].toUpperCase() + (page.length > 0 ? page.substr(1) : "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectPlatform = createSelector(
|
export const selectPlatform = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
state => state.platform
|
state => state.platform
|
||||||
|
@ -137,41 +56,6 @@ export const selectDownloadComplete = createSelector(
|
||||||
state => state.upgradeDownloadCompleted
|
state => state.upgradeDownloadCompleted
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
|
||||||
// This contains intentional fall throughs
|
|
||||||
switch (page) {
|
|
||||||
case "wallet":
|
|
||||||
case "history":
|
|
||||||
case "send":
|
|
||||||
case "receive":
|
|
||||||
case "invite":
|
|
||||||
case "rewards":
|
|
||||||
case "backup":
|
|
||||||
return {
|
|
||||||
wallet: __("Overview"),
|
|
||||||
history: __("History"),
|
|
||||||
send: __("Send"),
|
|
||||||
receive: __("Receive"),
|
|
||||||
rewards: __("Rewards"),
|
|
||||||
invite: __("Invites"),
|
|
||||||
};
|
|
||||||
case "downloaded":
|
|
||||||
case "published":
|
|
||||||
return {
|
|
||||||
downloaded: __("Downloaded"),
|
|
||||||
published: __("Published"),
|
|
||||||
};
|
|
||||||
case "settings":
|
|
||||||
case "help":
|
|
||||||
return {
|
|
||||||
settings: __("Settings"),
|
|
||||||
help: __("Help"),
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const selectUpgradeSkipped = createSelector(
|
export const selectUpgradeSkipped = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
state => state.upgradeSkipped
|
state => state.upgradeSkipped
|
||||||
|
@ -222,41 +106,4 @@ export const selectCurrentLanguage = createSelector(
|
||||||
() => app.i18n.getLocale() || "en"
|
() => app.i18n.getLocale() || "en"
|
||||||
);
|
);
|
||||||
|
|
||||||
export const selectPathAfterAuth = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => state.pathAfterAuth
|
|
||||||
);
|
|
||||||
|
|
||||||
export const selectIsBackDisabled = createSelector(
|
|
||||||
_selectState,
|
|
||||||
state => state.isBackDisabled
|
|
||||||
);
|
|
||||||
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export const selectVolume = createSelector(_selectState, state => state.volume);
|
export const selectVolume = createSelector(_selectState, state => state.volume);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSelector } from "reselect";
|
import { createSelector } from "reselect";
|
||||||
import { selectCurrentParams } from "selectors/app";
|
import { selectCurrentParams } from "selectors/navigation";
|
||||||
import lbryuri from "lbryuri";
|
import lbryuri from "lbryuri";
|
||||||
|
|
||||||
const _selectState = state => state.claims || {};
|
const _selectState = state => state.claims || {};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSelector } from "reselect";
|
import { createSelector } from "reselect";
|
||||||
import { selectCurrentParams } from "./app";
|
import { selectCurrentParams } from "selectors/navigation";
|
||||||
|
|
||||||
export const _selectState = state => state.costInfo || {};
|
export const _selectState = state => state.costInfo || {};
|
||||||
|
|
||||||
|
|
129
ui/js/selectors/navigation.js
Normal file
129
ui/js/selectors/navigation.js
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
import { createSelector } from "reselect";
|
||||||
|
import { parseQueryParams, toQueryString } from "util/query_params";
|
||||||
|
import * as settings from "constants/settings.js";
|
||||||
|
import lbryuri from "lbryuri";
|
||||||
|
|
||||||
|
export const _selectState = state => state.navigation || {};
|
||||||
|
|
||||||
|
export const selectCurrentPath = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.currentPath
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectCurrentPage = createSelector(selectCurrentPath, path => {
|
||||||
|
return path.replace(/^\//, "").split("?")[0];
|
||||||
|
});
|
||||||
|
|
||||||
|
export const selectCurrentParams = createSelector(selectCurrentPath, path => {
|
||||||
|
if (path === undefined) return {};
|
||||||
|
if (!path.match(/\?/)) return {};
|
||||||
|
|
||||||
|
return parseQueryParams(path.split("?")[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const selectHeaderLinks = createSelector(selectCurrentPage, page => {
|
||||||
|
// This contains intentional fall throughs
|
||||||
|
switch (page) {
|
||||||
|
case "wallet":
|
||||||
|
case "send":
|
||||||
|
case "receive":
|
||||||
|
case "rewards":
|
||||||
|
case "backup":
|
||||||
|
return {
|
||||||
|
wallet: __("Overview"),
|
||||||
|
send: __("Send"),
|
||||||
|
receive: __("Receive"),
|
||||||
|
rewards: __("Rewards"),
|
||||||
|
};
|
||||||
|
case "downloaded":
|
||||||
|
case "published":
|
||||||
|
return {
|
||||||
|
downloaded: __("Downloaded"),
|
||||||
|
published: __("Published"),
|
||||||
|
};
|
||||||
|
case "settings":
|
||||||
|
case "help":
|
||||||
|
return {
|
||||||
|
settings: __("Settings"),
|
||||||
|
help: __("Help"),
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const selectPageTitle = createSelector(
|
||||||
|
selectCurrentPage,
|
||||||
|
selectCurrentParams,
|
||||||
|
(page, params) => {
|
||||||
|
switch (page) {
|
||||||
|
case "settings":
|
||||||
|
return __("Settings");
|
||||||
|
case "report":
|
||||||
|
return __("Report");
|
||||||
|
case "wallet":
|
||||||
|
return __("Wallet");
|
||||||
|
case "send":
|
||||||
|
return __("Send");
|
||||||
|
case "receive":
|
||||||
|
return __("Receive");
|
||||||
|
case "backup":
|
||||||
|
return __("Backup");
|
||||||
|
case "rewards":
|
||||||
|
return __("Rewards");
|
||||||
|
case "start":
|
||||||
|
return __("Start");
|
||||||
|
case "publish":
|
||||||
|
return __("Publish");
|
||||||
|
case "help":
|
||||||
|
return __("Help");
|
||||||
|
case "developer":
|
||||||
|
return __("Developer");
|
||||||
|
case "search":
|
||||||
|
return params.query
|
||||||
|
? __("Search results for %s", params.query)
|
||||||
|
: __("Search");
|
||||||
|
case "show": {
|
||||||
|
const parts = [lbryuri.normalize(params.uri)];
|
||||||
|
// If the params has any keys other than "uri"
|
||||||
|
if (Object.keys(params).length > 1) {
|
||||||
|
parts.push(toQueryString(Object.assign({}, params, { uri: null })));
|
||||||
|
}
|
||||||
|
return parts.join("?");
|
||||||
|
}
|
||||||
|
case "downloaded":
|
||||||
|
return __("Downloads & Purchases");
|
||||||
|
case "published":
|
||||||
|
return __("Publishes");
|
||||||
|
case "discover":
|
||||||
|
return __("Home");
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectPathAfterAuth = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.pathAfterAuth
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectIsBackDisabled = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.index === 0
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectIsForwardDisabled = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.index === state.stack.length - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectHistoryIndex = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.index
|
||||||
|
);
|
||||||
|
|
||||||
|
export const selectHistoryStack = createSelector(
|
||||||
|
_selectState,
|
||||||
|
state => state.stack
|
||||||
|
);
|
|
@ -1,5 +1,5 @@
|
||||||
import { createSelector } from "reselect";
|
import { createSelector } from "reselect";
|
||||||
import { selectPageTitle, selectCurrentPage } from "selectors/app";
|
import { selectPageTitle, selectCurrentPage } from "selectors/navigation";
|
||||||
|
|
||||||
export const _selectState = state => state.search || {};
|
export const _selectState = state => state.search || {};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { createSelector } from "reselect";
|
import { createSelector } from "reselect";
|
||||||
import { selectCurrentPage, selectDaemonReady } from "selectors/app";
|
|
||||||
|
|
||||||
export const _selectState = state => state.wallet || {};
|
export const _selectState = state => state.wallet || {};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import claimsReducer from "reducers/claims";
|
||||||
import contentReducer from "reducers/content";
|
import contentReducer from "reducers/content";
|
||||||
import costInfoReducer from "reducers/cost_info";
|
import costInfoReducer from "reducers/cost_info";
|
||||||
import fileInfoReducer from "reducers/file_info";
|
import fileInfoReducer from "reducers/file_info";
|
||||||
|
import navigationReducer from "reducers/navigation";
|
||||||
import rewardsReducer from "reducers/rewards";
|
import rewardsReducer from "reducers/rewards";
|
||||||
import searchReducer from "reducers/search";
|
import searchReducer from "reducers/search";
|
||||||
import settingsReducer from "reducers/settings";
|
import settingsReducer from "reducers/settings";
|
||||||
|
@ -13,8 +14,8 @@ import walletReducer from "reducers/wallet";
|
||||||
import { persistStore, autoRehydrate } from "redux-persist";
|
import { persistStore, autoRehydrate } from "redux-persist";
|
||||||
import createCompressor from "redux-persist-transform-compress";
|
import createCompressor from "redux-persist-transform-compress";
|
||||||
import createFilter from "redux-persist-transform-filter";
|
import createFilter from "redux-persist-transform-filter";
|
||||||
import { REHYDRATE } from "redux-persist/constants";
|
//import { REHYDRATE } from "redux-persist/constants";
|
||||||
import createActionBuffer from "redux-action-buffer";
|
//import createActionBuffer from "redux-action-buffer";
|
||||||
|
|
||||||
const localForage = require("localforage");
|
const localForage = require("localforage");
|
||||||
const redux = require("redux");
|
const redux = require("redux");
|
||||||
|
@ -55,6 +56,7 @@ function enableBatching(reducer) {
|
||||||
|
|
||||||
const reducers = redux.combineReducers({
|
const reducers = redux.combineReducers({
|
||||||
app: appReducer,
|
app: appReducer,
|
||||||
|
navigation: navigationReducer,
|
||||||
availability: availabilityReducer,
|
availability: availabilityReducer,
|
||||||
claims: claimsReducer,
|
claims: claimsReducer,
|
||||||
fileInfo: fileInfoReducer,
|
fileInfo: fileInfoReducer,
|
||||||
|
|
Loading…
Add table
Reference in a new issue