Merge remote-tracking branch 'origin/history'
This commit is contained in:
commit
bcf86dfc16
8 changed files with 178 additions and 16 deletions
|
@ -10,10 +10,10 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
||||||
### Added
|
### Added
|
||||||
* Added a new component, `FormFieldPrice` which is now used in Publish and Settings
|
* Added a new component, `FormFieldPrice` which is now used in Publish and Settings
|
||||||
* Added wallet backup guide reference
|
* Added wallet backup guide reference
|
||||||
|
* Added feature: forward history
|
||||||
*
|
*
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
* Updated to daemon [0.15](https://github.com/lbryio/lbry/releases). Most relevant changes for app are improved announcing of content and a fix for the daemon getting stuck running.
|
|
||||||
* Some form field refactoring as we progress towards form sanity.
|
* Some form field refactoring as we progress towards form sanity.
|
||||||
* When an "Open" button is clicked on a show page, if the file fails to open, the app will try to open the file's folder.
|
* When an "Open" button is clicked on a show page, if the file fails to open, the app will try to open the file's folder.
|
||||||
* Removed confusing placeholder text from email input
|
* Removed confusing placeholder text from email input
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
selectPageTitle,
|
selectPageTitle,
|
||||||
selectCurrentPage,
|
selectCurrentPage,
|
||||||
selectCurrentParams,
|
selectCurrentParams,
|
||||||
|
selectHistoryBack,
|
||||||
|
selectHistoryForward,
|
||||||
} from "selectors/app";
|
} from "selectors/app";
|
||||||
import { doSearch } from "actions/search";
|
import { doSearch } from "actions/search";
|
||||||
import { doFetchDaemonSettings } from "actions/settings";
|
import { doFetchDaemonSettings } from "actions/settings";
|
||||||
|
@ -31,7 +33,11 @@ export function doNavigate(path, params = {}, options = {}) {
|
||||||
|
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const pageTitle = selectPageTitle(state);
|
const pageTitle = selectPageTitle(state);
|
||||||
dispatch(doHistoryPush({ params }, pageTitle, url));
|
const historyState = history.state;
|
||||||
|
|
||||||
|
dispatch(
|
||||||
|
doHistoryPush({ params, page: historyState.page + 1 }, pageTitle, url)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,10 +83,35 @@ export function doChangePath(path, options = {}) {
|
||||||
|
|
||||||
export function doHistoryBack() {
|
export function doHistoryBack() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
if (!history.state) return;
|
// Get back history from stack
|
||||||
if (history.state.index === 0) return;
|
const back = selectHistoryBack(getState());
|
||||||
|
|
||||||
history.back();
|
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 },
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +119,12 @@ export function doHistoryPush(currentState, title, relativeUrl) {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
title += " - LBRY";
|
title += " - LBRY";
|
||||||
history.pushState(currentState, title, `#${relativeUrl}`);
|
history.pushState(currentState, title, `#${relativeUrl}`);
|
||||||
|
dispatch({
|
||||||
|
type: types.HISTORY_NAVIGATE,
|
||||||
|
data: {
|
||||||
|
location: relativeUrl,
|
||||||
|
},
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,10 +303,22 @@ export function doDaemonReady() {
|
||||||
return function(dispatch, getState) {
|
return function(dispatch, getState) {
|
||||||
const path = window.location.hash || "#/discover";
|
const path = window.location.hash || "#/discover";
|
||||||
const params = parseQueryParams(path.split("?")[1] || "");
|
const params = parseQueryParams(path.split("?")[1] || "");
|
||||||
history.replaceState({ params, index: 0 }, document.title, `${path}`);
|
|
||||||
|
// 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());
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { formatCredits } from "utils";
|
import { formatCredits } from "utils";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { selectIsBackDisabled, selectIsForwardDisabled } from "selectors/app";
|
||||||
import { selectBalance } from "selectors/wallet";
|
import { selectBalance } from "selectors/wallet";
|
||||||
import { doNavigate, doHistoryBack } from "actions/app";
|
import { doNavigate, doHistoryBack, doHistoryForward } from "actions/app";
|
||||||
import Header from "./view";
|
import Header from "./view";
|
||||||
|
|
||||||
const select = state => ({
|
const select = state => ({
|
||||||
|
isBackDisabled: selectIsBackDisabled(state),
|
||||||
|
isForwardDisabled: selectIsForwardDisabled(state),
|
||||||
balance: formatCredits(selectBalance(state), 1),
|
balance: formatCredits(selectBalance(state), 1),
|
||||||
publish: __("Publish"),
|
publish: __("Publish"),
|
||||||
});
|
});
|
||||||
|
@ -13,6 +16,7 @@ const select = state => ({
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
navigate: path => dispatch(doNavigate(path)),
|
navigate: path => dispatch(doNavigate(path)),
|
||||||
back: () => dispatch(doHistoryBack()),
|
back: () => dispatch(doHistoryBack()),
|
||||||
|
forward: () => dispatch(doHistoryForward()),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(Header);
|
export default connect(select, perform)(Header);
|
||||||
|
|
|
@ -3,12 +3,34 @@ import Link from "component/link";
|
||||||
import WunderBar from "component/wunderbar";
|
import WunderBar from "component/wunderbar";
|
||||||
|
|
||||||
export const Header = props => {
|
export const Header = props => {
|
||||||
const { balance, back, navigate, publish } = props;
|
const {
|
||||||
|
balance,
|
||||||
|
back,
|
||||||
|
forward,
|
||||||
|
isBackDisabled,
|
||||||
|
isForwardDisabled,
|
||||||
|
navigate,
|
||||||
|
publish,
|
||||||
|
} = props;
|
||||||
return (
|
return (
|
||||||
<header id="header">
|
<header id="header">
|
||||||
<div className="header__item">
|
<div className="header__item">
|
||||||
<Link onClick={back} button="alt button--flat" icon="icon-arrow-left" title={__("Back")} />
|
<Link
|
||||||
|
onClick={back}
|
||||||
|
disabled={isBackDisabled}
|
||||||
|
button="alt button--flat"
|
||||||
|
icon="icon-arrow-left"
|
||||||
|
title={__("Back")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="header__item">
|
||||||
|
<Link
|
||||||
|
onClick={forward}
|
||||||
|
disabled={isForwardDisabled}
|
||||||
|
button="alt button--flat"
|
||||||
|
icon="icon-arrow-right"
|
||||||
|
title={__("Forward")}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="header__item">
|
<div className="header__item">
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
export const CHANGE_PATH = "CHANGE_PATH";
|
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_BACK = "HISTORY_BACK";
|
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";
|
||||||
|
@ -112,5 +112,4 @@ export const CLAIM_REWARD_STARTED = "CLAIM_REWARD_STARTED";
|
||||||
export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS";
|
export const CLAIM_REWARD_SUCCESS = "CLAIM_REWARD_SUCCESS";
|
||||||
export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE";
|
export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE";
|
||||||
export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
|
export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
|
||||||
export const FETCH_REWARD_CONTENT_COMPLETED =
|
export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED";
|
||||||
"FETCH_REWARD_CONTENT_COMPLETED";
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
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";
|
||||||
import lbry from "lbry";
|
|
||||||
|
|
||||||
const currentPath = () => {
|
const currentPath = () => {
|
||||||
const hash = document.location.hash;
|
const hash = document.location.hash;
|
||||||
|
@ -15,6 +14,8 @@ const win = remote.BrowserWindow.getFocusedWindow();
|
||||||
const reducers = {};
|
const reducers = {};
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
isLoaded: false,
|
isLoaded: false,
|
||||||
|
isBackDisabled: true,
|
||||||
|
isForwardDisabled: true,
|
||||||
currentPath: currentPath(),
|
currentPath: currentPath(),
|
||||||
pathAfterAuth: "/discover",
|
pathAfterAuth: "/discover",
|
||||||
platform: process.platform,
|
platform: process.platform,
|
||||||
|
@ -23,11 +24,17 @@ const defaultState = {
|
||||||
daemonReady: false,
|
daemonReady: false,
|
||||||
hasSignature: false,
|
hasSignature: false,
|
||||||
badgeNumber: 0,
|
badgeNumber: 0,
|
||||||
|
history: { index: 0, stack: [] },
|
||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -163,6 +170,55 @@ 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
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export default function reducer(state = defaultState, action) {
|
export default function reducer(state = defaultState, action) {
|
||||||
const handler = reducers[action.type];
|
const handler = reducers[action.type];
|
||||||
if (handler) return handler(state, action);
|
if (handler) return handler(state, action);
|
||||||
|
|
|
@ -216,3 +216,35 @@ export const selectPathAfterAuth = createSelector(
|
||||||
_selectState,
|
_selectState,
|
||||||
state => state.pathAfterAuth
|
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];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -105,7 +105,7 @@ p
|
||||||
|
|
||||||
.disabled {
|
.disabled {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.7;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.truncated-text {
|
.truncated-text {
|
||||||
|
|
Loading…
Add table
Reference in a new issue