From ae81843c051c668147ea35b881bc4284829c3446 Mon Sep 17 00:00:00 2001 From: hackrush Date: Sat, 16 Sep 2017 16:32:54 +0530 Subject: [PATCH 1/3] Additional tipping fixes/changes - [x] Display empty message on empty filtered Tx list - [ ] Tipping form has to stay open until success is detected(or closed by user) - [ ] Storing the older transaction list, and refreshing the new one in the background. Tip Box shown until valid Txn or manually cancelled Cleanup of show tip box logic --- ui/js/actions/claims.js | 13 ++++++-- ui/js/component/fileActions/index.js | 2 ++ ui/js/component/fileActions/view.jsx | 6 +--- ui/js/component/tipLink/index.js | 3 +- ui/js/component/tipLink/view.jsx | 5 ++-- .../internal/TransactionListBody.jsx | 21 ++++++++++--- ui/js/constants/action_types.js | 2 ++ ui/js/page/file/index.js | 2 ++ ui/js/page/file/view.jsx | 28 ++--------------- ui/js/reducers/claims.js | 30 +++++++++++++++++-- ui/js/selectors/claims.js | 5 ++++ 11 files changed, 75 insertions(+), 42 deletions(-) diff --git a/ui/js/actions/claims.js b/ui/js/actions/claims.js index 71f94852c..e8e45f341 100644 --- a/ui/js/actions/claims.js +++ b/ui/js/actions/claims.js @@ -4,6 +4,14 @@ import { doOpenModal, doShowSnackBar } from "actions/app"; import * as types from "constants/action_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) { return function(dispatch, getState) { const state = getState(); @@ -22,6 +30,7 @@ export function doSendSupport(amount, claim_id) { dispatch({ type: types.SUPPORT_TRANSACTION_COMPLETED, }); + dispatch(doHideTipBox); dispatch( doShowSnackBar({ message: __(`You sent ${amount} LBC as support, Mahalo!`), @@ -32,7 +41,7 @@ export function doSendSupport(amount, claim_id) { } else { dispatch({ type: types.SUPPORT_TRANSACTION_FAILED, - data: { error: results }, + data: { error: results.code }, }); dispatch(doOpenModal(modals.TRANSACTION_FAILED)); } @@ -41,7 +50,7 @@ export function doSendSupport(amount, claim_id) { const errorCallback = error => { dispatch({ type: types.SUPPORT_TRANSACTION_FAILED, - data: { error: error.message }, + data: { error: error.code }, }); dispatch(doOpenModal(modals.TRANSACTION_FAILED)); }; diff --git a/ui/js/component/fileActions/index.js b/ui/js/component/fileActions/index.js index b94e2bbcb..851b28507 100644 --- a/ui/js/component/fileActions/index.js +++ b/ui/js/component/fileActions/index.js @@ -9,6 +9,7 @@ import { doOpenFileInShell, doOpenFileInFolder } from "actions/file_info"; import { makeSelectClaimIsMine } from "selectors/claims"; import { doPurchaseUri, doLoadVideo, doStartDownload } from "actions/content"; import { doNavigate } from "actions/navigation"; +import { doShowTipBox } from "actions/claims"; import FileActions from "./view"; const select = (state, props) => ({ @@ -25,6 +26,7 @@ const perform = dispatch => ({ startDownload: uri => dispatch(doPurchaseUri(uri)), restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)), editClaim: claimId => dispatch(doNavigate("/publish", { id: claimId })), + showTipBox: () => dispatch(doShowTipBox()), }); export default connect(select, perform)(FileActions); diff --git a/ui/js/component/fileActions/view.jsx b/ui/js/component/fileActions/view.jsx index 361338b89..bffcfa664 100644 --- a/ui/js/component/fileActions/view.jsx +++ b/ui/js/component/fileActions/view.jsx @@ -4,10 +4,6 @@ import FileDownloadLink from "component/fileDownloadLink"; import * as modals from "constants/modal_types"; class FileActions extends React.PureComponent { - handleSupportButtonClicked() { - this.props.onTipShow(); - } - render() { const { fileInfo, @@ -37,7 +33,7 @@ class FileActions extends React.PureComponent { button="text" icon="icon-gift" label={__("Support")} - onClick={this.handleSupportButtonClicked.bind(this)} + onClick={this.props.showTipBox} /> ({}); const perform = dispatch => ({ sendSupport: (amount, claim_id) => dispatch(doSendSupport(amount, claim_id)), + hideTipBox: () => dispatch(doHideTipBox()), }); export default connect(select, perform)(TipLink); diff --git a/ui/js/component/tipLink/view.jsx b/ui/js/component/tipLink/view.jsx index 831806d48..00c2639f3 100644 --- a/ui/js/component/tipLink/view.jsx +++ b/ui/js/component/tipLink/view.jsx @@ -7,7 +7,7 @@ class TipLink extends React.PureComponent { super(props); this.state = { - tipAmount: 1.0, + tipAmount: 0.0, }; } @@ -15,11 +15,10 @@ class TipLink extends React.PureComponent { let claim_id = this.props.claim_id; let amount = this.state.tipAmount; this.props.sendSupport(amount, claim_id); - this.props.onTipHide(); } handleSupportCancelButtonClicked() { - this.props.onTipHide(); + this.props.hideTipBox(); } handleSupportPriceChange(event) { diff --git a/ui/js/component/transactionList/internal/TransactionListBody.jsx b/ui/js/component/transactionList/internal/TransactionListBody.jsx index 12beb2e8d..6ad795f05 100644 --- a/ui/js/component/transactionList/internal/TransactionListBody.jsx +++ b/ui/js/component/transactionList/internal/TransactionListBody.jsx @@ -125,13 +125,26 @@ class TransactionTableBody extends React.PureComponent { render() { const { transactions, filter } = this.props; + let transactionList = transactions + .filter(this.filterList, this) + .filter(this.removeFeeTx, this) + .map(this.renderBody, this); + + if (transactionList.length == 0) { + return ( + + + + {__("There are no transactions of this type.")} + + + + ); + } return ( - {transactions - .filter(this.filterList, this) - .filter(this.removeFeeTx, this) - .map(this.renderBody, this)} + {transactionList} ); } diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 5281e6b97..57466b17f 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -136,6 +136,8 @@ export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; export const SUPPORT_TRANSACTION_STARTED = "SUPPORT_TRANSACTION_STARTED"; export const SUPPORT_TRANSACTION_COMPLETED = "SUPPORT_TRANSACTION_COMPLETED"; export const SUPPORT_TRANSACTION_FAILED = "SUPPORT_TRANSACTION_FAILED"; +export const HIDE_TIP_BOX = "HIDE_TIP_BOX"; +export const SHOW_TIP_BOX = "SHOW_TIP_BOX"; //Language export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; diff --git a/ui/js/page/file/index.js b/ui/js/page/file/index.js index d0d1fb476..0154d00a0 100644 --- a/ui/js/page/file/index.js +++ b/ui/js/page/file/index.js @@ -9,6 +9,7 @@ import { makeSelectClaimForUri, makeSelectContentTypeForUri, makeSelectMetadataForUri, + selectShowTipBox, } from "selectors/claims"; import { makeSelectCostInfoForUri } from "selectors/cost_info"; import { selectShowNsfw } from "selectors/settings"; @@ -20,6 +21,7 @@ const select = (state, props) => ({ costInfo: makeSelectCostInfoForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state), obscureNsfw: !selectShowNsfw(state), + showTipBox: selectShowTipBox(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), rewardedContentClaimIds: selectRewardContentClaimIds(state, props), }); diff --git a/ui/js/page/file/view.jsx b/ui/js/page/file/view.jsx index 3e1a2e2f9..f27d0ab01 100644 --- a/ui/js/page/file/view.jsx +++ b/ui/js/page/file/view.jsx @@ -71,18 +71,6 @@ class FilePage extends React.PureComponent { } } - handleTipShow() { - this.setState({ - showTipBox: true, - }); - } - - handleTipHide() { - this.setState({ - showTipBox: false, - }); - } - render() { const { claim, @@ -91,10 +79,9 @@ class FilePage extends React.PureComponent { contentType, uri, rewardedContentClaimIds, + showTipBox, } = this.props; - const { showTipBox } = this.state; - if (!claim || !metadata) { return ( {__("Empty claim or metadata info.")} @@ -156,10 +143,7 @@ class FilePage extends React.PureComponent { : uriIndicator} - + {!showTipBox &&
@@ -179,13 +163,7 @@ class FilePage extends React.PureComponent { />
: ""} - {showTipBox - ? - : ""} + {showTipBox ? : ""} {!showTipBox &&
({ + tipBoxShown: false, +}); + +const defaultState = { + supportTransaction: buildSupportTransaction(), +}; reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) { const { uri, certificate, claim } = action.data; @@ -189,6 +196,22 @@ reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) { }); }; +reducers[types.HIDE_TIP_BOX] = function(state, action) { + return Object.assign({}, state, { + supportTransaction: buildSupportTransaction(), + }); +}; + +reducers[types.SHOW_TIP_BOX] = function(state, action) { + const newSupportTransaction = Object.assign({}, state.supportTransaction, { + tipBoxShown: true, + }); + + return Object.assign({}, state, { + supportTransaction: newSupportTransaction, + }); +}; + reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) { const newSupportTransaction = Object.assign({}, state.supportTransaction, { sendingSupport: true, @@ -200,13 +223,16 @@ reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) { }; reducers[types.SUPPORT_TRANSACTION_COMPLETED] = function(state, action) { - return Object.assign({}, state); + return Object.assign({}, state, { + supportTransaction: buildSupportTransaction(), + }); }; reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) { const newSupportTransaction = Object.assign({}, state.supportTransaction, { sendingSupport: false, error: action.data.error, + tipBoxShown: true, }); return Object.assign({}, state, { diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index ce8ebc8cd..45643722a 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -174,3 +174,8 @@ export const selectMyChannelClaims = createSelector( return claims; } ); + +export const selectShowTipBox = createSelector( + _selectState, + state => state.supportTransaction.tipBoxShown +); From c05edc40426febd95a0a5877ea1b1d63f1f83051 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Sun, 17 Sep 2017 14:26:55 -0400 Subject: [PATCH 2/3] clean up tip and search navigation --- app/package.json | 2 +- ui/js/actions/claims.js | 9 ------ ui/js/actions/navigation.js | 38 +++++++------------------ ui/js/component/fileActions/index.js | 9 ++---- ui/js/component/fileActions/view.jsx | 34 +++++++++------------- ui/js/component/fileListSearch/view.jsx | 12 +++++++- ui/js/component/link/index.js | 2 +- ui/js/component/link/view.jsx | 3 +- ui/js/component/tipLink/index.js | 3 +- ui/js/component/tipLink/view.jsx | 9 +++--- ui/js/constants/action_types.js | 1 - ui/js/page/file/index.js | 4 +-- ui/js/page/file/view.jsx | 14 +++------ ui/js/reducers/claims.js | 7 +---- ui/js/reducers/navigation.js | 15 ++++------ ui/js/reducers/search.js | 3 -- ui/js/selectors/claims.js | 2 +- ui/js/selectors/navigation.js | 5 +++- ui/js/selectors/search.js | 5 ++-- 19 files changed, 68 insertions(+), 109 deletions(-) diff --git a/app/package.json b/app/package.json index e9022a2e9..ec2657777 100644 --- a/app/package.json +++ b/app/package.json @@ -20,7 +20,7 @@ "electron-rebuild": "^1.5.11" }, "lbrySettings": { - "lbrynetDaemonVersion": "0.16.0rc8", + "lbrynetDaemonVersion": "0.16.0rc9", "lbrynetDaemonUrlTemplate": "https://github.com/lbryio/lbry/releases/download/vDAEMONVER/lbrynet-daemon-vDAEMONVER-OSNAME.zip" }, "license": "MIT" diff --git a/ui/js/actions/claims.js b/ui/js/actions/claims.js index e8e45f341..51c50785d 100644 --- a/ui/js/actions/claims.js +++ b/ui/js/actions/claims.js @@ -4,14 +4,6 @@ import { doOpenModal, doShowSnackBar } from "actions/app"; import * as types from "constants/action_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) { return function(dispatch, getState) { const state = getState(); @@ -30,7 +22,6 @@ export function doSendSupport(amount, claim_id) { dispatch({ type: types.SUPPORT_TRANSACTION_COMPLETED, }); - dispatch(doHideTipBox); dispatch( doShowSnackBar({ message: __(`You sent ${amount} LBC as support, Mahalo!`), diff --git a/ui/js/actions/navigation.js b/ui/js/actions/navigation.js index b34a2e876..0ab3a22eb 100644 --- a/ui/js/actions/navigation.js +++ b/ui/js/actions/navigation.js @@ -1,5 +1,6 @@ import * as types from "constants/action_types"; import { + computePageFromPath, selectPageTitle, selectCurrentPage, selectCurrentParams, @@ -20,9 +21,17 @@ export function doNavigate(path, params = {}, options = {}) { 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({ 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) { const stack = selectHistoryStack(state), index = selectHistoryIndex(state) + modifier; diff --git a/ui/js/component/fileActions/index.js b/ui/js/component/fileActions/index.js index 851b28507..75eaeff9a 100644 --- a/ui/js/component/fileActions/index.js +++ b/ui/js/component/fileActions/index.js @@ -1,15 +1,13 @@ import React from "react"; import { connect } from "react-redux"; -import { selectPlatform } from "selectors/app"; import { makeSelectFileInfoForUri } from "selectors/file_info"; import { makeSelectCostInfoForUri } from "selectors/cost_info"; import { doOpenModal } from "actions/app"; import { doFetchAvailability } from "actions/availability"; -import { doOpenFileInShell, doOpenFileInFolder } from "actions/file_info"; +import { doOpenFileInShell } from "actions/file_info"; import { makeSelectClaimIsMine } from "selectors/claims"; -import { doPurchaseUri, doLoadVideo, doStartDownload } from "actions/content"; +import { doPurchaseUri, doStartDownload } from "actions/content"; import { doNavigate } from "actions/navigation"; -import { doShowTipBox } from "actions/claims"; import FileActions from "./view"; const select = (state, props) => ({ @@ -21,12 +19,11 @@ const select = (state, props) => ({ const perform = dispatch => ({ checkAvailability: uri => dispatch(doFetchAvailability(uri)), + navigate: (path, params) => dispatch(doNavigate(path, params)), openInShell: fileInfo => dispatch(doOpenFileInShell(fileInfo)), openModal: (modal, props) => dispatch(doOpenModal(modal, props)), startDownload: uri => dispatch(doPurchaseUri(uri)), restartDownload: (uri, outpoint) => dispatch(doStartDownload(uri, outpoint)), - editClaim: claimId => dispatch(doNavigate("/publish", { id: claimId })), - showTipBox: () => dispatch(doShowTipBox()), }); export default connect(select, perform)(FileActions); diff --git a/ui/js/component/fileActions/view.jsx b/ui/js/component/fileActions/view.jsx index bffcfa664..ecb218228 100644 --- a/ui/js/component/fileActions/view.jsx +++ b/ui/js/component/fileActions/view.jsx @@ -5,19 +5,10 @@ import * as modals from "constants/modal_types"; class FileActions extends React.PureComponent { render() { - const { - fileInfo, - uri, - openModal, - claimIsMine, - editClaim, - checkAvailability, - } = this.props; + const { fileInfo, uri, openModal, claimIsMine } = this.props; const claimId = fileInfo ? fileInfo.claim_id : null, - metadata = fileInfo ? fileInfo.metadata : null, - showMenu = fileInfo && Object.keys(fileInfo).length > 0, - title = metadata ? metadata.title : uri; + showDelete = fileInfo && Object.keys(fileInfo).length > 0; return (
@@ -26,22 +17,25 @@ class FileActions extends React.PureComponent { button="text" icon="icon-edit" label={__("Edit")} - onClick={() => editClaim(claimId)} + navigate="/publish" + navigateParams={{ id: claimId }} />} - openModal(modals.CONFIRM_FILE_REMOVE, { uri })} + navigate="/show" + navigateParams={{ uri, tab: "tip" }} /> + {showDelete && + openModal(modals.CONFIRM_FILE_REMOVE, { uri })} + />}
); } diff --git a/ui/js/component/fileListSearch/view.jsx b/ui/js/component/fileListSearch/view.jsx index 682d07e7c..59884da8e 100644 --- a/ui/js/component/fileListSearch/view.jsx +++ b/ui/js/component/fileListSearch/view.jsx @@ -49,7 +49,17 @@ const FileListSearchResults = props => { class FileListSearch extends React.PureComponent { 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() { diff --git a/ui/js/component/link/index.js b/ui/js/component/link/index.js index 5847c97d9..37340987a 100644 --- a/ui/js/component/link/index.js +++ b/ui/js/component/link/index.js @@ -4,7 +4,7 @@ import { doNavigate } from "actions/navigation"; import Link from "./view"; const perform = dispatch => ({ - doNavigate: path => dispatch(doNavigate(path)), + doNavigate: (path, params) => dispatch(doNavigate(path, params)), }); export default connect(null, perform)(Link); diff --git a/ui/js/component/link/view.jsx b/ui/js/component/link/view.jsx index a30d1a981..1ba8f4b52 100644 --- a/ui/js/component/link/view.jsx +++ b/ui/js/component/link/view.jsx @@ -12,6 +12,7 @@ const Link = props => { disabled, children, navigate, + navigateParams, doNavigate, } = props; @@ -23,7 +24,7 @@ const Link = props => { const onClick = !props.onClick && navigate ? () => { - doNavigate(navigate); + doNavigate(navigate, navigateParams || {}); } : props.onClick; diff --git a/ui/js/component/tipLink/index.js b/ui/js/component/tipLink/index.js index 53ca5e10d..b43f225ac 100644 --- a/ui/js/component/tipLink/index.js +++ b/ui/js/component/tipLink/index.js @@ -1,13 +1,12 @@ import React from "react"; import { connect } from "react-redux"; -import { doSendSupport, doHideTipBox } from "actions/claims"; +import { doSendSupport } from "actions/claims"; import TipLink from "./view"; const select = state => ({}); const perform = dispatch => ({ sendSupport: (amount, claim_id) => dispatch(doSendSupport(amount, claim_id)), - hideTipBox: () => dispatch(doHideTipBox()), }); export default connect(select, perform)(TipLink); diff --git a/ui/js/component/tipLink/view.jsx b/ui/js/component/tipLink/view.jsx index 00c2639f3..81e0aa31a 100644 --- a/ui/js/component/tipLink/view.jsx +++ b/ui/js/component/tipLink/view.jsx @@ -17,10 +17,6 @@ class TipLink extends React.PureComponent { this.props.sendSupport(amount, claim_id); } - handleSupportCancelButtonClicked() { - this.props.hideTipBox(); - } - handleSupportPriceChange(event) { this.setState({ tipAmount: Number(event.target.value), @@ -28,6 +24,8 @@ class TipLink extends React.PureComponent { } render() { + const { uri } = this.props; + return (
@@ -59,7 +57,8 @@ class TipLink extends React.PureComponent {
diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index 57466b17f..d1c75403d 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -9,7 +9,6 @@ export const DAEMON_VERSION_MISMATCH = "DAEMON_VERSION_MISMATCH"; 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"; diff --git a/ui/js/page/file/index.js b/ui/js/page/file/index.js index 0154d00a0..cf81056f0 100644 --- a/ui/js/page/file/index.js +++ b/ui/js/page/file/index.js @@ -9,11 +9,11 @@ import { makeSelectClaimForUri, makeSelectContentTypeForUri, makeSelectMetadataForUri, - selectShowTipBox, } from "selectors/claims"; import { makeSelectCostInfoForUri } from "selectors/cost_info"; import { selectShowNsfw } from "selectors/settings"; import FilePage from "./view"; +import { makeSelectCurrentParam } from "../../selectors/navigation"; const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), @@ -21,7 +21,7 @@ const select = (state, props) => ({ costInfo: makeSelectCostInfoForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state), obscureNsfw: !selectShowNsfw(state), - showTipBox: selectShowTipBox(state), + tab: makeSelectCurrentParam("tab")(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), rewardedContentClaimIds: selectRewardContentClaimIds(state, props), }); diff --git a/ui/js/page/file/view.jsx b/ui/js/page/file/view.jsx index f27d0ab01..73d2ed405 100644 --- a/ui/js/page/file/view.jsx +++ b/ui/js/page/file/view.jsx @@ -14,7 +14,6 @@ import DateTime from "component/dateTime"; const FormatItem = props => { const { - publishedDate, contentType, claim: { height }, metadata: { language, license }, @@ -43,13 +42,6 @@ const FormatItem = props => { }; class FilePage extends React.PureComponent { - constructor(props) { - super(props); - this.state = { - showTipBox: false, - }; - } - componentDidMount() { this.fetchFileInfo(this.props); this.fetchCostInfo(this.props); @@ -77,11 +69,13 @@ class FilePage extends React.PureComponent { fileInfo, metadata, contentType, + tab, uri, rewardedContentClaimIds, - showTipBox, } = this.props; + const showTipBox = tab == "tip"; + if (!claim || !metadata) { return ( {__("Empty claim or metadata info.")} @@ -163,7 +157,7 @@ class FilePage extends React.PureComponent { />
: ""} - {showTipBox ? : ""} + {showTipBox ? : ""} {!showTipBox &&
({ - tipBoxShown: false, -}); - const defaultState = { - supportTransaction: buildSupportTransaction(), + supportTransaction: {}, }; 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, { sendingSupport: false, error: action.data.error, - tipBoxShown: true, }); return Object.assign({}, state, { diff --git a/ui/js/reducers/navigation.js b/ui/js/reducers/navigation.js index 821db9183..1ebcab2c9 100644 --- a/ui/js/reducers/navigation.js +++ b/ui/js/reducers/navigation.js @@ -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) { return Object.assign({}, state, { pathAfterAuth: action.data.path, @@ -38,15 +32,16 @@ reducers[types.CHANGE_AFTER_AUTH_PATH] = function(state, action) { reducers[types.HISTORY_NAVIGATE] = (state, action) => { const { stack, index } = state; - - let newState = {}; - const path = action.data.url; - // Check for duplicated + let newState = { + currentPath: path, + }; + if (action.data.index >= 0) { newState.index = action.data.index; } else if (!stack[index] || stack[index].path !== path) { + // ^ Check for duplicated newState.stack = [...stack.slice(0, index + 1), { path, scrollY: 0 }]; newState.index = newState.stack.length - 1; } diff --git a/ui/js/reducers/search.js b/ui/js/reducers/search.js index be6c3bec7..ed500b987 100644 --- a/ui/js/reducers/search.js +++ b/ui/js/reducers/search.js @@ -1,5 +1,4 @@ import * as types from "constants/action_types"; -import lbryuri from "lbryuri"; const reducers = {}; const defaultState = {}; @@ -9,7 +8,6 @@ reducers[types.SEARCH_STARTED] = function(state, action) { return Object.assign({}, state, { searching: true, - query: query, }); }; @@ -31,7 +29,6 @@ reducers[types.SEARCH_COMPLETED] = function(state, action) { reducers[types.SEARCH_CANCELLED] = function(state, action) { return Object.assign({}, state, { searching: false, - query: undefined, }); }; diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index 45643722a..14ac231fc 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -66,7 +66,7 @@ export const selectAllFetchingChannelClaims = createSelector( ); export const makeSelectFetchingChannelClaims = uri => { - createSelector( + return createSelector( selectAllFetchingChannelClaims, fetching => fetching && fetching[uri] ); diff --git a/ui/js/selectors/navigation.js b/ui/js/selectors/navigation.js index f11f35eb9..b5eb98ade 100644 --- a/ui/js/selectors/navigation.js +++ b/ui/js/selectors/navigation.js @@ -10,8 +10,11 @@ export const selectCurrentPath = createSelector( state => state.currentPath ); +export const computePageFromPath = path => + path.replace(/^\//, "").split("?")[0]; + export const selectCurrentPage = createSelector(selectCurrentPath, path => { - return path.replace(/^\//, "").split("?")[0]; + return computePageFromPath(path); }); export const selectCurrentParams = createSelector(selectCurrentPath, path => { diff --git a/ui/js/selectors/search.js b/ui/js/selectors/search.js index 4e02c2542..9b967d66e 100644 --- a/ui/js/selectors/search.js +++ b/ui/js/selectors/search.js @@ -8,8 +8,9 @@ import { export const _selectState = state => state.search || {}; export const selectSearchQuery = createSelector( - _selectState, - state => state.query + selectCurrentPage, + selectCurrentParams, + (page, params) => (page === "search" ? params && params.query : null) ); export const selectIsSearching = createSelector( From e9b48f0bd6b943b637ef9e220ae5a2d63ced632d Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Sun, 17 Sep 2017 16:33:52 -0400 Subject: [PATCH 3/3] tip clean up and refactor --- ui/js/actions/claims.js | 56 ------------ ui/js/actions/wallet.js | 53 +++++++++++ ui/js/component/fileDetails/index.js | 16 ++++ ui/js/component/fileDetails/view.jsx | 64 +++++++++++++ ui/js/component/tipLink/index.js | 12 --- ui/js/component/tipLink/view.jsx | 69 -------------- ui/js/component/uriIndicator/view.jsx | 27 +++++- ui/js/component/walletSendTip/index.js | 18 ++++ ui/js/component/walletSendTip/view.jsx | 79 ++++++++++++++++ ui/js/constants/action_types.js | 36 ++++---- ui/js/modal/modalRemoveFile/index.js | 7 +- ui/js/modal/modalRemoveFile/view.jsx | 2 +- ui/js/page/file/view.jsx | 120 +++++-------------------- ui/js/reducers/claims.js | 47 +--------- ui/js/reducers/wallet.js | 20 +++++ ui/js/selectors/claims.js | 12 +-- ui/js/selectors/wallet.js | 5 ++ ui/scss/component/_card.scss | 6 ++ 18 files changed, 335 insertions(+), 314 deletions(-) delete mode 100644 ui/js/actions/claims.js create mode 100644 ui/js/component/fileDetails/index.js create mode 100644 ui/js/component/fileDetails/view.jsx delete mode 100644 ui/js/component/tipLink/index.js delete mode 100644 ui/js/component/tipLink/view.jsx create mode 100644 ui/js/component/walletSendTip/index.js create mode 100644 ui/js/component/walletSendTip/view.jsx diff --git a/ui/js/actions/claims.js b/ui/js/actions/claims.js deleted file mode 100644 index 51c50785d..000000000 --- a/ui/js/actions/claims.js +++ /dev/null @@ -1,56 +0,0 @@ -import lbry from "lbry"; -import { selectBalance } from "selectors/wallet"; -import { doOpenModal, doShowSnackBar } from "actions/app"; -import * as types from "constants/action_types"; -import * as modals from "constants/modal_types"; - -export function doSendSupport(amount, claim_id) { - return function(dispatch, getState) { - const state = getState(); - const balance = selectBalance(state); - - if (balance - amount <= 0) { - return dispatch(doOpenModal(modals.INSUFFICIENT_BALANCE)); - } - - dispatch({ - type: types.SUPPORT_TRANSACTION_STARTED, - }); - - const successCallback = results => { - if (results.txid) { - dispatch({ - type: types.SUPPORT_TRANSACTION_COMPLETED, - }); - dispatch( - doShowSnackBar({ - message: __(`You sent ${amount} LBC as support, Mahalo!`), - linkText: __("History"), - linkTarget: __("/wallet"), - }) - ); - } else { - dispatch({ - type: types.SUPPORT_TRANSACTION_FAILED, - data: { error: results.code }, - }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); - } - }; - - const errorCallback = error => { - dispatch({ - type: types.SUPPORT_TRANSACTION_FAILED, - data: { error: error.code }, - }); - dispatch(doOpenModal(modals.TRANSACTION_FAILED)); - }; - - lbry - .wallet_send({ - claim_id: claim_id, - amount: amount, - }) - .then(successCallback, errorCallback); - }; -} diff --git a/ui/js/actions/wallet.js b/ui/js/actions/wallet.js index 025cb1def..0e90266fb 100644 --- a/ui/js/actions/wallet.js +++ b/ui/js/actions/wallet.js @@ -6,6 +6,7 @@ import { selectBalance, } from "selectors/wallet"; import { doOpenModal, doShowSnackBar } from "actions/app"; +import { doNavigate } from "actions/navigation"; import * as modals from "constants/modal_types"; export function doUpdateBalance(balance) { @@ -143,3 +144,55 @@ export function doSetDraftTransactionAddress(address) { data: { address }, }; } + +export function doSendSupport(amount, claim_id, uri) { + return function(dispatch, getState) { + const state = getState(); + const balance = selectBalance(state); + + if (balance - amount <= 0) { + return dispatch(doOpenModal(modals.INSUFFICIENT_BALANCE)); + } + + dispatch({ + type: types.SUPPORT_TRANSACTION_STARTED, + }); + + const successCallback = results => { + if (results.txid) { + dispatch({ + type: types.SUPPORT_TRANSACTION_COMPLETED, + }); + dispatch( + doShowSnackBar({ + message: __(`You sent ${amount} LBC as support, Mahalo!`), + linkText: __("History"), + linkTarget: __("/wallet"), + }) + ); + dispatch(doNavigate("/show", { uri })); + } else { + dispatch({ + type: types.SUPPORT_TRANSACTION_FAILED, + data: { error: results.code }, + }); + dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + } + }; + + const errorCallback = error => { + dispatch({ + type: types.SUPPORT_TRANSACTION_FAILED, + data: { error: error.code }, + }); + dispatch(doOpenModal(modals.TRANSACTION_FAILED)); + }; + + lbry + .wallet_send({ + claim_id: claim_id, + amount: amount, + }) + .then(successCallback, errorCallback); + }; +} diff --git a/ui/js/component/fileDetails/index.js b/ui/js/component/fileDetails/index.js new file mode 100644 index 000000000..385959ed2 --- /dev/null +++ b/ui/js/component/fileDetails/index.js @@ -0,0 +1,16 @@ +import React from "react"; +import { connect } from "react-redux"; +import { + makeSelectClaimForUri, + makeSelectContentTypeForUri, + makeSelectMetadataForUri, +} from "selectors/claims"; +import FileDetails from "./view"; + +const select = (state, props) => ({ + claim: makeSelectClaimForUri(props.uri)(state), + contentType: makeSelectContentTypeForUri(props.uri)(state), + metadata: makeSelectMetadataForUri(props.uri)(state), +}); + +export default connect(select, null)(FileDetails); diff --git a/ui/js/component/fileDetails/view.jsx b/ui/js/component/fileDetails/view.jsx new file mode 100644 index 000000000..dfcc47699 --- /dev/null +++ b/ui/js/component/fileDetails/view.jsx @@ -0,0 +1,64 @@ +import React from "react"; +import ReactMarkdown from "react-markdown"; +import lbry from "lbry.js"; +import FileActions from "component/fileActions"; +import Link from "component/link"; +import DateTime from "component/dateTime"; + +class FileDetails extends React.PureComponent { + render() { + const { claim, contentType, metadata, uri } = this.props; + + if (!claim || !metadata) { + return ( +
+ {__("Empty claim or metadata info.")} +
+ ); + } + + const { description, language, license } = metadata; + const { height } = claim; + const mediaType = lbry.getMediaType(contentType); + + return ( +
+ +
+ +
+
+ + + + + + + + + + + + + + + + +
{__("Published on")}
{__("Content-Type")}{mediaType}
{__("Language")}{language}
{__("License")}{license}
+

+ +

+
+
+ ); + } +} + +export default FileDetails; diff --git a/ui/js/component/tipLink/index.js b/ui/js/component/tipLink/index.js deleted file mode 100644 index b43f225ac..000000000 --- a/ui/js/component/tipLink/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; -import { connect } from "react-redux"; -import { doSendSupport } from "actions/claims"; -import TipLink from "./view"; - -const select = state => ({}); - -const perform = dispatch => ({ - sendSupport: (amount, claim_id) => dispatch(doSendSupport(amount, claim_id)), -}); - -export default connect(select, perform)(TipLink); diff --git a/ui/js/component/tipLink/view.jsx b/ui/js/component/tipLink/view.jsx deleted file mode 100644 index 81e0aa31a..000000000 --- a/ui/js/component/tipLink/view.jsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from "react"; -import Link from "component/link"; -import { FormRow } from "component/form"; - -class TipLink extends React.PureComponent { - constructor(props) { - super(props); - - this.state = { - tipAmount: 0.0, - }; - } - - handleSendButtonClicked() { - let claim_id = this.props.claim_id; - let amount = this.state.tipAmount; - this.props.sendSupport(amount, claim_id); - } - - handleSupportPriceChange(event) { - this.setState({ - tipAmount: Number(event.target.value), - }); - } - - render() { - const { uri } = this.props; - - return ( -
-
-

{__("Support")}

-
-
- {__( - "Support the creator and the success of their content by sending a tip. " - )} - -
-
- this.handleSupportPriceChange(event)} - /> -
-
- - -
-
- ); - } -} - -export default TipLink; diff --git a/ui/js/component/uriIndicator/view.jsx b/ui/js/component/uriIndicator/view.jsx index b69abd591..a6dcb1a50 100644 --- a/ui/js/component/uriIndicator/view.jsx +++ b/ui/js/component/uriIndicator/view.jsx @@ -1,5 +1,7 @@ import React from "react"; import { Icon } from "component/common"; +import Link from "component/link"; +import lbryuri from "lbryuri.js"; class UriIndicator extends React.PureComponent { componentWillMount() { @@ -19,7 +21,7 @@ class UriIndicator extends React.PureComponent { } render() { - const { claim, uri, isResolvingUri } = this.props; + const { claim, link, uri, isResolvingUri } = this.props; if (isResolvingUri && !claim) { return Validating...; @@ -33,21 +35,30 @@ class UriIndicator extends React.PureComponent { channel_name: channelName, has_signature: hasSignature, signature_is_valid: signatureIsValid, + value, } = claim; + const channelClaimId = + value && + value.publisherSignature && + value.publisherSignature.certificateId; if (!hasSignature || !channelName) { return Anonymous; } - let icon, modifier; + let icon, channelLink, modifier; + if (signatureIsValid) { modifier = "valid"; + channelLink = link + ? lbryuri.build({ channelName, claimId: channelClaimId }, false) + : false; } else { icon = "icon-times-circle"; modifier = "invalid"; } - return ( + const inner = ( {channelName} {" "} {!signatureIsValid @@ -58,6 +69,16 @@ class UriIndicator extends React.PureComponent { : ""} ); + + if (!channelLink) { + return inner; + } + + return ( + + {inner} + + ); } } diff --git a/ui/js/component/walletSendTip/index.js b/ui/js/component/walletSendTip/index.js new file mode 100644 index 000000000..6d3275321 --- /dev/null +++ b/ui/js/component/walletSendTip/index.js @@ -0,0 +1,18 @@ +import React from "react"; +import { connect } from "react-redux"; +import { doSendSupport } from "actions/wallet"; +import WalletSendTip from "./view"; +import { makeSelectTitleForUri } from "selectors/claims"; +import { selectIsSendingSupport } from "selectors/wallet"; + +const select = (state, props) => ({ + isPending: selectIsSendingSupport(state), + title: makeSelectTitleForUri(props.uri)(state), +}); + +const perform = dispatch => ({ + sendSupport: (amount, claim_id, uri) => + dispatch(doSendSupport(amount, claim_id, uri)), +}); + +export default connect(select, perform)(WalletSendTip); diff --git a/ui/js/component/walletSendTip/view.jsx b/ui/js/component/walletSendTip/view.jsx new file mode 100644 index 000000000..9b8ce0338 --- /dev/null +++ b/ui/js/component/walletSendTip/view.jsx @@ -0,0 +1,79 @@ +import React from "react"; +import Link from "component/link"; +import { FormRow } from "component/form"; +import UriIndicator from "component/uriIndicator"; + +class WalletSendTip extends React.PureComponent { + constructor(props) { + super(props); + + this.state = { + amount: 0.0, + }; + } + + handleSendButtonClicked() { + const { claim_id, uri } = this.props; + let amount = this.state.amount; + this.props.sendSupport(amount, claim_id, uri); + } + + handleSupportPriceChange(event) { + this.setState({ + amount: Number(event.target.value), + }); + } + + render() { + const { errorMessage, isPending, title, uri } = this.props; + + return ( +
+
+

{__("Support")}

+
+
+ + {__( + 'This will appear as a tip for "%s" located at %s.', + title, + uri + ) + " "} + + + } + placeholder="1.00" + onChange={event => this.handleSupportPriceChange(event)} + /> +
+ + +
+
+
+ ); + } +} + +export default WalletSendTip; diff --git a/ui/js/constants/action_types.js b/ui/js/constants/action_types.js index d1c75403d..a4cb1afaa 100644 --- a/ui/js/constants/action_types.js +++ b/ui/js/constants/action_types.js @@ -39,8 +39,11 @@ export const SEND_TRANSACTION_STARTED = "SEND_TRANSACTION_STARTED"; export const SEND_TRANSACTION_COMPLETED = "SEND_TRANSACTION_COMPLETED"; export const SEND_TRANSACTION_FAILED = "SEND_TRANSACTION_FAILED"; export const FETCH_BLOCK_SUCCESS = "FETCH_BLOCK_SUCCESS"; +export const SUPPORT_TRANSACTION_STARTED = "SUPPORT_TRANSACTION_STARTED"; +export const SUPPORT_TRANSACTION_COMPLETED = "SUPPORT_TRANSACTION_COMPLETED"; +export const SUPPORT_TRANSACTION_FAILED = "SUPPORT_TRANSACTION_FAILED"; -// Content +// Claims export const FETCH_FEATURED_CONTENT_STARTED = "FETCH_FEATURED_CONTENT_STARTED"; export const FETCH_FEATURED_CONTENT_COMPLETED = "FETCH_FEATURED_CONTENT_COMPLETED"; @@ -56,6 +59,19 @@ export const FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = export const FETCH_CLAIM_LIST_MINE_STARTED = "FETCH_CLAIM_LIST_MINE_STARTED"; export const FETCH_CLAIM_LIST_MINE_COMPLETED = "FETCH_CLAIM_LIST_MINE_COMPLETED"; +export const ABANDON_CLAIM_STARTED = "ABANDON_CLAIM_STARTED"; +export const ABANDON_CLAIM_SUCCEEDED = "ABANDON_CLAIM_SUCCEEDED"; +export const FETCH_CHANNEL_LIST_MINE_STARTED = + "FETCH_CHANNEL_LIST_MINE_STARTED"; +export const FETCH_CHANNEL_LIST_MINE_COMPLETED = + "FETCH_CHANNEL_LIST_MINE_COMPLETED"; +export const CREATE_CHANNEL_STARTED = "CREATE_CHANNEL_STARTED"; +export const CREATE_CHANNEL_COMPLETED = "CREATE_CHANNEL_COMPLETED"; +export const PUBLISH_STARTED = "PUBLISH_STARTED"; +export const PUBLISH_COMPLETED = "PUBLISH_COMPLETED"; +export const PUBLISH_FAILED = "PUBLISH_FAILED"; + +// Files export const FILE_LIST_STARTED = "FILE_LIST_STARTED"; export const FILE_LIST_SUCCEEDED = "FILE_LIST_SUCCEEDED"; export const FETCH_FILE_INFO_STARTED = "FETCH_FILE_INFO_STARTED"; @@ -72,17 +88,6 @@ export const PLAY_VIDEO_STARTED = "PLAY_VIDEO_STARTED"; export const FETCH_AVAILABILITY_STARTED = "FETCH_AVAILABILITY_STARTED"; export const FETCH_AVAILABILITY_COMPLETED = "FETCH_AVAILABILITY_COMPLETED"; export const FILE_DELETE = "FILE_DELETE"; -export const ABANDON_CLAIM_STARTED = "ABANDON_CLAIM_STARTED"; -export const ABANDON_CLAIM_SUCCEEDED = "ABANDON_CLAIM_SUCCEEDED"; -export const FETCH_CHANNEL_LIST_MINE_STARTED = - "FETCH_CHANNEL_LIST_MINE_STARTED"; -export const FETCH_CHANNEL_LIST_MINE_COMPLETED = - "FETCH_CHANNEL_LIST_MINE_COMPLETED"; -export const CREATE_CHANNEL_STARTED = "CREATE_CHANNEL_STARTED"; -export const CREATE_CHANNEL_COMPLETED = "CREATE_CHANNEL_COMPLETED"; -export const PUBLISH_STARTED = "PUBLISH_STARTED"; -export const PUBLISH_COMPLETED = "PUBLISH_COMPLETED"; -export const PUBLISH_FAILED = "PUBLISH_FAILED"; // Search export const SEARCH_STARTED = "SEARCH_STARTED"; @@ -131,13 +136,6 @@ export const CLAIM_REWARD_FAILURE = "CLAIM_REWARD_FAILURE"; export const CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR"; export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; -// Supports -export const SUPPORT_TRANSACTION_STARTED = "SUPPORT_TRANSACTION_STARTED"; -export const SUPPORT_TRANSACTION_COMPLETED = "SUPPORT_TRANSACTION_COMPLETED"; -export const SUPPORT_TRANSACTION_FAILED = "SUPPORT_TRANSACTION_FAILED"; -export const HIDE_TIP_BOX = "HIDE_TIP_BOX"; -export const SHOW_TIP_BOX = "SHOW_TIP_BOX"; - //Language export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED"; diff --git a/ui/js/modal/modalRemoveFile/index.js b/ui/js/modal/modalRemoveFile/index.js index 8c00f383e..39ae89ceb 100644 --- a/ui/js/modal/modalRemoveFile/index.js +++ b/ui/js/modal/modalRemoveFile/index.js @@ -2,16 +2,13 @@ import React from "react"; import { connect } from "react-redux"; import { doCloseModal } from "actions/app"; import { doDeleteFileAndGoBack } from "actions/file_info"; -import { - makeSelectMetadataForUri, - makeSelectClaimIsMine, -} from "selectors/claims"; +import { makeSelectTitleForUri, makeSelectClaimIsMine } from "selectors/claims"; import { makeSelectFileInfoForUri } from "selectors/file_info"; import ModalRemoveFile from "./view"; const select = (state, props) => ({ claimIsMine: makeSelectClaimIsMine(props.uri)(state), - metadata: makeSelectMetadataForUri(props.uri)(state), + title: makeSelectTitleForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), }); diff --git a/ui/js/modal/modalRemoveFile/view.jsx b/ui/js/modal/modalRemoveFile/view.jsx index f646c5400..c18acb6f2 100644 --- a/ui/js/modal/modalRemoveFile/view.jsx +++ b/ui/js/modal/modalRemoveFile/view.jsx @@ -30,7 +30,7 @@ class ModalRemoveFile extends React.PureComponent { closeModal, deleteFile, fileInfo: { outpoint }, - metadata: { title }, + title, } = this.props; const { deleteChecked, abandonClaimChecked } = this.state; diff --git a/ui/js/page/file/view.jsx b/ui/js/page/file/view.jsx index 73d2ed405..35209ae18 100644 --- a/ui/js/page/file/view.jsx +++ b/ui/js/page/file/view.jsx @@ -1,45 +1,13 @@ import React from "react"; -import ReactMarkdown from "react-markdown"; import lbry from "lbry.js"; import lbryuri from "lbryuri.js"; import Video from "component/video"; -import TipLink from "component/tipLink"; import { Thumbnail } from "component/common"; import FilePrice from "component/filePrice"; -import FileActions from "component/fileActions"; -import Link from "component/link"; +import FileDetails from "component/fileDetails"; import UriIndicator from "component/uriIndicator"; import IconFeatured from "component/iconFeatured"; -import DateTime from "component/dateTime"; - -const FormatItem = props => { - const { - contentType, - claim: { height }, - metadata: { language, license }, - } = props; - - const mediaType = lbry.getMediaType(contentType); - - return ( - - - - - - - - - - - - - - - -
{__("Published on")}
{__("Content-Type")}{mediaType}
{__("Language")}{language}
{__("License")}{license}
- ); -}; +import WalletSendTip from "component/walletSendTip"; class FilePage extends React.PureComponent { componentDidMount() { @@ -82,24 +50,7 @@ class FilePage extends React.PureComponent { ); } - const { - txid, - nout, - channel_name: channelName, - has_signature: hasSignature, - signature_is_valid: signatureIsValid, - value, - } = claim; - - const outpoint = txid + ":" + nout; const title = metadata.title; - const channelClaimId = claim.value && claim.value.publisherSignature - ? claim.value.publisherSignature.certificateId - : null; - const channelUri = signatureIsValid && hasSignature && channelName - ? lbryuri.build({ channelName, claimId: channelClaimId }, false) - : null; - const uriIndicator = ; const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); const mediaType = lbry.getMediaType(contentType); const player = require("render-media"); @@ -109,7 +60,7 @@ class FilePage extends React.PureComponent { mediaType === "audio"; return ( -
+
{isPlayable ?
-
- {!fileInfo || fileInfo.written_bytes <= 0 - ? - - {isRewardContent && {" "}} - - : null} -

{title}

-
- {channelUri - ? - this.props.navigate("/show", { uri: channelUri })} - > - {uriIndicator} - - : uriIndicator} -
- -
- {!showTipBox && -
- + {(!tab || tab === "details") && +
+ {" "} {" "} +
+ {!fileInfo || fileInfo.written_bytes <= 0 + ? + + {isRewardContent && {" "}} + + : null} +

{title}

+
+ +
+
+
} + {tab === "tip" && + }
- {metadata && claim && !showTipBox - ?
- -
- : ""} - {showTipBox ? : ""} - {!showTipBox && -
- -
}
-
+
); } } diff --git a/ui/js/reducers/claims.js b/ui/js/reducers/claims.js index ae80f1712..f18433cdc 100644 --- a/ui/js/reducers/claims.js +++ b/ui/js/reducers/claims.js @@ -2,9 +2,7 @@ import * as types from "constants/action_types"; const reducers = {}; -const defaultState = { - supportTransaction: {}, -}; +const defaultState = {}; reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) { const { uri, certificate, claim } = action.data; @@ -192,49 +190,6 @@ reducers[types.CREATE_CHANNEL_COMPLETED] = function(state, action) { }); }; -reducers[types.HIDE_TIP_BOX] = function(state, action) { - return Object.assign({}, state, { - supportTransaction: buildSupportTransaction(), - }); -}; - -reducers[types.SHOW_TIP_BOX] = function(state, action) { - const newSupportTransaction = Object.assign({}, state.supportTransaction, { - tipBoxShown: true, - }); - - return Object.assign({}, state, { - supportTransaction: newSupportTransaction, - }); -}; - -reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) { - const newSupportTransaction = Object.assign({}, state.supportTransaction, { - sendingSupport: true, - }); - - return Object.assign({}, state, { - supportTransaction: newSupportTransaction, - }); -}; - -reducers[types.SUPPORT_TRANSACTION_COMPLETED] = function(state, action) { - return Object.assign({}, state, { - supportTransaction: buildSupportTransaction(), - }); -}; - -reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) { - const newSupportTransaction = Object.assign({}, state.supportTransaction, { - sendingSupport: false, - error: action.data.error, - }); - - return Object.assign({}, state, { - supportTransaction: newSupportTransaction, - }); -}; - export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/ui/js/reducers/wallet.js b/ui/js/reducers/wallet.js index e704222a6..7cc53b54a 100644 --- a/ui/js/reducers/wallet.js +++ b/ui/js/reducers/wallet.js @@ -15,6 +15,7 @@ const defaultState = { receiveAddress: address, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), + sendingSupport: false, }; reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) { @@ -125,6 +126,25 @@ reducers[types.SEND_TRANSACTION_FAILED] = function(state, action) { }); }; +reducers[types.SUPPORT_TRANSACTION_STARTED] = function(state, action) { + return Object.assign({}, state, { + sendingSupport: true, + }); +}; + +reducers[types.SUPPORT_TRANSACTION_COMPLETED] = function(state, action) { + return Object.assign({}, state, { + sendingSupport: false, + }); +}; + +reducers[types.SUPPORT_TRANSACTION_FAILED] = function(state, action) { + return Object.assign({}, state, { + error: action.data.error, + sendingSupport: false, + }); +}; + reducers[types.FETCH_BLOCK_SUCCESS] = (state, action) => { const { block, block: { height } } = action.data, blocks = Object.assign({}, state.blocks); diff --git a/ui/js/selectors/claims.js b/ui/js/selectors/claims.js index 14ac231fc..61fd5fdc2 100644 --- a/ui/js/selectors/claims.js +++ b/ui/js/selectors/claims.js @@ -97,6 +97,13 @@ export const makeSelectMetadataForUri = uri => { }); }; +export const makeSelectTitleForUri = uri => { + return createSelector( + makeSelectMetadataForUri(uri), + metadata => metadata && metadata.title + ); +}; + export const makeSelectContentTypeForUri = uri => { return createSelector(makeSelectClaimForUri(uri), claim => { const source = @@ -174,8 +181,3 @@ export const selectMyChannelClaims = createSelector( return claims; } ); - -export const selectShowTipBox = createSelector( - _selectState, - state => state.supportTransaction.tipBoxShown -); diff --git a/ui/js/selectors/wallet.js b/ui/js/selectors/wallet.js index ab7e22e07..7469c2f48 100644 --- a/ui/js/selectors/wallet.js +++ b/ui/js/selectors/wallet.js @@ -61,6 +61,11 @@ export const selectIsFetchingTransactions = createSelector( state => state.fetchingTransactions ); +export const selectIsSendingSupport = createSelector( + _selectState, + state => state.sendingSupport +); + export const selectReceiveAddress = createSelector( _selectState, state => state.receiveAddress diff --git a/ui/scss/component/_card.scss b/ui/scss/component/_card.scss index e5dff4e73..0562b4040 100644 --- a/ui/scss/component/_card.scss +++ b/ui/scss/component/_card.scss @@ -7,6 +7,9 @@ border-radius: var(--card-radius); margin-bottom: var(--card-margin); overflow: auto; + + //below added to prevent scrollbar on long titles when show page loads, would prefer a cleaner CSS solution + overflow-x: hidden; } .card--obscured { @@ -62,6 +65,9 @@ .card__content { margin-top: var(--card-margin); margin-bottom: var(--card-margin); + table:not(:last-child) { + margin-bottom: var(--card-margin); + } } $font-size-subtext-multiple: 0.82; .card__subtext {