clean up tip and search navigation

This commit is contained in:
Jeremy Kauffman 2017-09-17 14:26:55 -04:00
parent ae81843c05
commit c05edc4042
19 changed files with 68 additions and 109 deletions

View file

@ -20,7 +20,7 @@
"electron-rebuild": "^1.5.11" "electron-rebuild": "^1.5.11"
}, },
"lbrySettings": { "lbrySettings": {
"lbrynetDaemonVersion": "0.16.0rc8", "lbrynetDaemonVersion": "0.16.0rc9",
"lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip" "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip"
}, },
"license": "MIT" "license": "MIT"

View file

@ -4,14 +4,6 @@ import { doOpenModal, doShowSnackBar } from "actions/app";
import * as types from "constants/action_types"; import * as types from "constants/action_types";
import * as modals from "constants/modal_types"; import * as modals from "constants/modal_types";
export function doShowTipBox() {
return { type: types.SHOW_TIP_BOX };
}
export function doHideTipBox() {
return { type: types.HIDE_TIP_BOX };
}
export function doSendSupport(amount, claim_id) { export function doSendSupport(amount, claim_id) {
return function(dispatch, getState) { return function(dispatch, getState) {
const state = getState(); const state = getState();
@ -30,7 +22,6 @@ export function doSendSupport(amount, claim_id) {
dispatch({ dispatch({
type: types.SUPPORT_TRANSACTION_COMPLETED, type: types.SUPPORT_TRANSACTION_COMPLETED,
}); });
dispatch(doHideTipBox);
dispatch( dispatch(
doShowSnackBar({ doShowSnackBar({
message: __(`You sent ${amount} LBC as support, Mahalo!`), message: __(`You sent ${amount} LBC as support, Mahalo!`),

View file

@ -1,5 +1,6 @@
import * as types from "constants/action_types"; import * as types from "constants/action_types";
import { import {
computePageFromPath,
selectPageTitle, selectPageTitle,
selectCurrentPage, selectCurrentPage,
selectCurrentParams, selectCurrentParams,
@ -20,9 +21,17 @@ export function doNavigate(path, params = {}, options = {}) {
url += "?" + toQueryString(params); url += "?" + toQueryString(params);
} }
dispatch(doChangePath(url, options)); const state = getState(),
currentPage = selectCurrentPage(state),
nextPage = computePageFromPath(path),
scrollY = options.scrollY;
const pageTitle = selectPageTitle(getState()) + " - LBRY"; if (currentPage != nextPage) {
//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);
}
dispatch({ dispatch({
type: types.HISTORY_NAVIGATE, type: types.HISTORY_NAVIGATE,
@ -45,31 +54,6 @@ export function doAuthNavigate(pathAfterAuth = null, params = {}) {
}; };
} }
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) { export function doHistoryTraverse(dispatch, state, modifier) {
const stack = selectHistoryStack(state), const stack = selectHistoryStack(state),
index = selectHistoryIndex(state) + modifier; index = selectHistoryIndex(state) + modifier;

View file

@ -1,15 +1,13 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { selectPlatform } from "selectors/app";
import { makeSelectFileInfoForUri } from "selectors/file_info"; import { makeSelectFileInfoForUri } from "selectors/file_info";
import { makeSelectCostInfoForUri } from "selectors/cost_info"; import { makeSelectCostInfoForUri } from "selectors/cost_info";
import { doOpenModal } from "actions/app"; import { doOpenModal } from "actions/app";
import { doFetchAvailability } from "actions/availability"; import { doFetchAvailability } from "actions/availability";
import { doOpenFileInShell, doOpenFileInFolder } from "actions/file_info"; import { doOpenFileInShell } from "actions/file_info";
import { makeSelectClaimIsMine } from "selectors/claims"; import { makeSelectClaimIsMine } from "selectors/claims";
import { doPurchaseUri, doLoadVideo, doStartDownload } from "actions/content"; import { doPurchaseUri, doStartDownload } from "actions/content";
import { doNavigate } from "actions/navigation"; import { doNavigate } from "actions/navigation";
import { doShowTipBox } from "actions/claims";
import FileActions from "./view"; import FileActions from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
@ -21,12 +19,11 @@ const select = (state, props) => ({
const perform = dispatch => ({ const perform = dispatch => ({
checkAvailability: uri => dispatch(doFetchAvailability(uri)), checkAvailability: uri => dispatch(doFetchAvailability(uri)),
navigate: (path, params) => dispatch(doNavigate(path, params)),
openInShell: fileInfo => dispatch(doOpenFileInShell(fileInfo)), openInShell: fileInfo => dispatch(doOpenFileInShell(fileInfo)),
openModal: (modal, props) => dispatch(doOpenModal(modal, props)), openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
startDownload: uri => dispatch(doPurchaseUri(uri)), startDownload: uri => dispatch(doPurchaseUri(uri)),
restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)), restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)),
editClaim: claimId => dispatch(doNavigate("/publish", { id: claimId })),
showTipBox: () => dispatch(doShowTipBox()),
}); });
export default connect(select, perform)(FileActions); export default connect(select, perform)(FileActions);

View file

@ -5,19 +5,10 @@ import * as modals from "constants/modal_types";
class FileActions extends React.PureComponent { class FileActions extends React.PureComponent {
render() { render() {
const { const { fileInfo, uri, openModal, claimIsMine } = this.props;
fileInfo,
uri,
openModal,
claimIsMine,
editClaim,
checkAvailability,
} = this.props;
const claimId = fileInfo ? fileInfo.claim_id : null, const claimId = fileInfo ? fileInfo.claim_id : null,
metadata = fileInfo ? fileInfo.metadata : null, showDelete = fileInfo && Object.keys(fileInfo).length > 0;
showMenu = fileInfo && Object.keys(fileInfo).length > 0,
title = metadata ? metadata.title : uri;
return ( return (
<section className="card__actions"> <section className="card__actions">
@ -26,22 +17,25 @@ class FileActions extends React.PureComponent {
button="text" button="text"
icon="icon-edit" icon="icon-edit"
label={__("Edit")} label={__("Edit")}
onClick={() => editClaim(claimId)} navigate="/publish"
navigateParams={{ id: claimId }}
/>} />}
<FileDownloadLink uri={uri} /> <FileDownloadLink uri={uri} />
<Link <Link
button="text" button="text"
icon="icon-gift" icon="icon-gift"
label={__("Support")} label={__("Support")}
onClick={this.props.showTipBox} navigate="/show"
navigateParams={{ uri, tab: "tip" }}
/> />
{showDelete &&
<Link <Link
button="text" button="text"
icon="icon-trash" icon="icon-trash"
label={__("Remove")} label={__("Remove")}
className="card__action--right" className="card__action--right"
onClick={() => openModal(modals.CONFIRM_FILE_REMOVE, { uri })} onClick={() => openModal(modals.CONFIRM_FILE_REMOVE, { uri })}
/> />}
</section> </section>
); );
} }

View file

@ -49,7 +49,17 @@ const FileListSearchResults = props => {
class FileListSearch extends React.PureComponent { class FileListSearch extends React.PureComponent {
componentWillMount() { componentWillMount() {
this.props.search(this.props.query); this.doSearch(this.props);
}
componentWillReceiveProps(props) {
if (props.query != this.props.query) {
this.doSearch(props);
}
}
doSearch(props) {
this.props.search(props.query);
} }
render() { render() {

View file

@ -4,7 +4,7 @@ import { doNavigate } from "actions/navigation";
import Link from "./view"; import Link from "./view";
const perform = dispatch => ({ const perform = dispatch => ({
doNavigate: path => dispatch(doNavigate(path)), doNavigate: (path, params) => dispatch(doNavigate(path, params)),
}); });
export default connect(null, perform)(Link); export default connect(null, perform)(Link);

View file

@ -12,6 +12,7 @@ const Link = props => {
disabled, disabled,
children, children,
navigate, navigate,
navigateParams,
doNavigate, doNavigate,
} = props; } = props;
@ -23,7 +24,7 @@ const Link = props => {
const onClick = !props.onClick && navigate const onClick = !props.onClick && navigate
? () => { ? () => {
doNavigate(navigate); doNavigate(navigate, navigateParams || {});
} }
: props.onClick; : props.onClick;

View file

@ -1,13 +1,12 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { doSendSupport, doHideTipBox } from "actions/claims"; import { doSendSupport } from "actions/claims";
import TipLink from "./view"; import TipLink from "./view";
const select = state => ({}); const select = state => ({});
const perform = dispatch => ({ const perform = dispatch => ({
sendSupport: (amount, claim_id) => dispatch(doSendSupport(amount, claim_id)), sendSupport: (amount, claim_id) => dispatch(doSendSupport(amount, claim_id)),
hideTipBox: () => dispatch(doHideTipBox()),
}); });
export default connect(select, perform)(TipLink); export default connect(select, perform)(TipLink);

View file

@ -17,10 +17,6 @@ class TipLink extends React.PureComponent {
this.props.sendSupport(amount, claim_id); this.props.sendSupport(amount, claim_id);
} }
handleSupportCancelButtonClicked() {
this.props.hideTipBox();
}
handleSupportPriceChange(event) { handleSupportPriceChange(event) {
this.setState({ this.setState({
tipAmount: Number(event.target.value), tipAmount: Number(event.target.value),
@ -28,6 +24,8 @@ class TipLink extends React.PureComponent {
} }
render() { render() {
const { uri } = this.props;
return ( return (
<div className="card__content"> <div className="card__content">
<div className="card__title-primary"> <div className="card__title-primary">
@ -59,7 +57,8 @@ class TipLink extends React.PureComponent {
<Link <Link
label={__("Cancel")} label={__("Cancel")}
button="alt" button="alt"
onClick={this.handleSupportCancelButtonClicked.bind(this)} navigate="/show"
navigateParams={{ uri }}
/> />
</div> </div>
</div> </div>

View file

@ -9,7 +9,6 @@ export const DAEMON_VERSION_MISMATCH = "DAEMON_VERSION_MISMATCH";
export const VOLUME_CHANGED = "VOLUME_CHANGED"; export const VOLUME_CHANGED = "VOLUME_CHANGED";
// Navigation // Navigation
export const CHANGE_PATH = "CHANGE_PATH";
export const CHANGE_AFTER_AUTH_PATH = "CHANGE_AFTER_AUTH_PATH"; export const CHANGE_AFTER_AUTH_PATH = "CHANGE_AFTER_AUTH_PATH";
export const WINDOW_SCROLLED = "WINDOW_SCROLLED"; export const WINDOW_SCROLLED = "WINDOW_SCROLLED";
export const HISTORY_NAVIGATE = "HISTORY_NAVIGATE"; export const HISTORY_NAVIGATE = "HISTORY_NAVIGATE";

View file

@ -9,11 +9,11 @@ import {
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectContentTypeForUri, makeSelectContentTypeForUri,
makeSelectMetadataForUri, makeSelectMetadataForUri,
selectShowTipBox,
} from "selectors/claims"; } from "selectors/claims";
import { makeSelectCostInfoForUri } from "selectors/cost_info"; import { makeSelectCostInfoForUri } from "selectors/cost_info";
import { selectShowNsfw } from "selectors/settings"; import { selectShowNsfw } from "selectors/settings";
import FilePage from "./view"; import FilePage from "./view";
import { makeSelectCurrentParam } from "../../selectors/navigation";
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
@ -21,7 +21,7 @@ const select = (state, props) => ({
costInfo: makeSelectCostInfoForUri(props.uri)(state), costInfo: makeSelectCostInfoForUri(props.uri)(state),
metadata: makeSelectMetadataForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state),
obscureNsfw: !selectShowNsfw(state), obscureNsfw: !selectShowNsfw(state),
showTipBox: selectShowTipBox(state), tab: makeSelectCurrentParam("tab")(state),
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
rewardedContentClaimIds: selectRewardContentClaimIds(state, props), rewardedContentClaimIds: selectRewardContentClaimIds(state, props),
}); });

View file

@ -14,7 +14,6 @@ import DateTime from "component/dateTime";
const FormatItem = props => { const FormatItem = props => {
const { const {
publishedDate,
contentType, contentType,
claim: { height }, claim: { height },
metadata: { language, license }, metadata: { language, license },
@ -43,13 +42,6 @@ const FormatItem = props => {
}; };
class FilePage extends React.PureComponent { class FilePage extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
showTipBox: false,
};
}
componentDidMount() { componentDidMount() {
this.fetchFileInfo(this.props); this.fetchFileInfo(this.props);
this.fetchCostInfo(this.props); this.fetchCostInfo(this.props);
@ -77,11 +69,13 @@ class FilePage extends React.PureComponent {
fileInfo, fileInfo,
metadata, metadata,
contentType, contentType,
tab,
uri, uri,
rewardedContentClaimIds, rewardedContentClaimIds,
showTipBox,
} = this.props; } = this.props;
const showTipBox = tab == "tip";
if (!claim || !metadata) { if (!claim || !metadata) {
return ( return (
<span className="empty">{__("Empty claim or metadata info.")}</span> <span className="empty">{__("Empty claim or metadata info.")}</span>
@ -163,7 +157,7 @@ class FilePage extends React.PureComponent {
/> />
</div> </div>
: ""} : ""}
{showTipBox ? <TipLink claim_id={claim.claim_id} /> : ""} {showTipBox ? <TipLink claim_id={claim.claim_id} uri={uri} /> : ""}
{!showTipBox && {!showTipBox &&
<div className="card__content"> <div className="card__content">
<Link <Link

View file

@ -2,12 +2,8 @@ import * as types from "constants/action_types";
const reducers = {}; const reducers = {};
const buildSupportTransaction = () => ({
tipBoxShown: false,
});
const defaultState = { const defaultState = {
supportTransaction: buildSupportTransaction(), supportTransaction: {},
}; };
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) { reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
@ -232,7 +228,6 @@ reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) {
const newSupportTransaction = Object.assign({}, state.supportTransaction, { const newSupportTransaction = Object.assign({}, state.supportTransaction, {
sendingSupport: false, sendingSupport: false,
error: action.data.error, error: action.data.error,
tipBoxShown: true,
}); });
return Object.assign({}, state, { return Object.assign({}, state, {

View file

@ -24,12 +24,6 @@ reducers[types.DAEMON_READY] = 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) { reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
pathAfterAuth: action.data.path, pathAfterAuth: action.data.path,
@ -38,15 +32,16 @@ reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) {
reducers[types.HISTORY_NAVIGATE] = (state, action) => { reducers[types.HISTORY_NAVIGATE] = (state, action) => {
const { stack, index } = state; const { stack, index } = state;
let newState = {};
const path = action.data.url; const path = action.data.url;
// Check for duplicated let newState = {
currentPath: path,
};
if (action.data.index >= 0) { if (action.data.index >= 0) {
newState.index = action.data.index; newState.index = action.data.index;
} else if (!stack[index] || stack[index].path !== path) { } else if (!stack[index] || stack[index].path !== path) {
// ^ Check for duplicated
newState.stack = [...stack.slice(0, index + 1), { path, scrollY: 0 }]; newState.stack = [...stack.slice(0, index + 1), { path, scrollY: 0 }];
newState.index = newState.stack.length - 1; newState.index = newState.stack.length - 1;
} }

View file

@ -1,5 +1,4 @@
import * as types from "constants/action_types"; import * as types from "constants/action_types";
import lbryuri from "lbryuri";
const reducers = {}; const reducers = {};
const defaultState = {}; const defaultState = {};
@ -9,7 +8,6 @@ reducers[types.SEARCH_STARTED] = function(state, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
searching: true, searching: true,
query: query,
}); });
}; };
@ -31,7 +29,6 @@ reducers[types.SEARCH_COMPLETED] = function(state, action) {
reducers[types.SEARCH_CANCELLED] = function(state, action) { reducers[types.SEARCH_CANCELLED] = function(state, action) {
return Object.assign({}, state, { return Object.assign({}, state, {
searching: false, searching: false,
query: undefined,
}); });
}; };

View file

@ -66,7 +66,7 @@ export const selectAllFetchingChannelClaims = createSelector(
); );
export const makeSelectFetchingChannelClaims = uri => { export const makeSelectFetchingChannelClaims = uri => {
createSelector( return createSelector(
selectAllFetchingChannelClaims, selectAllFetchingChannelClaims,
fetching => fetching && fetching[uri] fetching => fetching && fetching[uri]
); );

View file

@ -10,8 +10,11 @@ export const selectCurrentPath = createSelector(
state => state.currentPath state => state.currentPath
); );
export const computePageFromPath = path =>
path.replace(/^\//, "").split("?")[0];
export const selectCurrentPage = createSelector(selectCurrentPath, path => { export const selectCurrentPage = createSelector(selectCurrentPath, path => {
return path.replace(/^\//, "").split("?")[0]; return computePageFromPath(path);
}); });
export const selectCurrentParams = createSelector(selectCurrentPath, path => { export const selectCurrentParams = createSelector(selectCurrentPath, path => {

View file

@ -8,8 +8,9 @@ import {
export const _selectState = state => state.search || {}; export const _selectState = state => state.search || {};
export const selectSearchQuery = createSelector( export const selectSearchQuery = createSelector(
_selectState, selectCurrentPage,
state => state.query selectCurrentParams,
(page, params) => (page === "search" ? params && params.query : null)
); );
export const selectIsSearching = createSelector( export const selectIsSearching = createSelector(