tip clean up and refactor

This commit is contained in:
Jeremy Kauffman 2017-09-17 16:33:52 -04:00
parent c05edc4042
commit e9b48f0bd6
18 changed files with 335 additions and 314 deletions

View file

@ -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);
};
}

View file

@ -6,6 +6,7 @@ import {
selectBalance, selectBalance,
} from "selectors/wallet"; } from "selectors/wallet";
import { doOpenModal, doShowSnackBar } from "actions/app"; import { doOpenModal, doShowSnackBar } from "actions/app";
import { doNavigate } from "actions/navigation";
import * as modals from "constants/modal_types"; import * as modals from "constants/modal_types";
export function doUpdateBalance(balance) { export function doUpdateBalance(balance) {
@ -143,3 +144,55 @@ export function doSetDraftTransactionAddress(address) {
data: { 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);
};
}

View file

@ -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);

View file

@ -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 (
<div className="card__content">
<span className="empty">{__("Empty claim or metadata info.")}</span>
</div>
);
}
const { description, language, license } = metadata;
const { height } = claim;
const mediaType = lbry.getMediaType(contentType);
return (
<div>
<FileActions uri={uri} />
<div className="card__content card__subtext card__subtext--allow-newlines">
<ReactMarkdown
source={description || ""}
escapeHtml={true}
disallowedTypes={["Heading", "HtmlInline", "HtmlBlock"]}
/>
</div>
<div className="card__content">
<table className="table-standard table-stretch">
<tbody>
<tr>
<td>{__("Published on")}</td>
<td><DateTime block={height} /></td>
</tr>
<tr>
<td>{__("Content-Type")}</td><td>{mediaType}</td>
</tr>
<tr>
<td>{__("Language")}</td><td>{language}</td>
</tr>
<tr>
<td>{__("License")}</td><td>{license}</td>
</tr>
</tbody>
</table>
<p>
<Link
href={`https://lbry.io/dmca?claim_id=${claim.claim_id}`}
label={__("report")}
/>
</p>
</div>
</div>
);
}
}
export default FileDetails;

View file

@ -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);

View file

@ -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 (
<div className="card__content">
<div className="card__title-primary">
<h4>{__("Support")}</h4>
</div>
<div className="card__content">
{__(
"Support the creator and the success of their content by sending a tip. "
)}
<Link label={__("Learn more")} href="https://lbry.io/faq/tipping" />
</div>
<div className="card__content">
<FormRow
label={__("Amount")}
postfix={__("LBC")}
min="0"
step="0.1"
type="number"
placeholder="1.00"
onChange={event => this.handleSupportPriceChange(event)}
/>
</div>
<div className="card__actions">
<Link
label={__("Send")}
button="primary"
onClick={this.handleSendButtonClicked.bind(this)}
/>
<Link
label={__("Cancel")}
button="alt"
navigate="/show"
navigateParams={{ uri }}
/>
</div>
</div>
);
}
}
export default TipLink;

View file

@ -1,5 +1,7 @@
import React from "react"; import React from "react";
import { Icon } from "component/common"; import { Icon } from "component/common";
import Link from "component/link";
import lbryuri from "lbryuri.js";
class UriIndicator extends React.PureComponent { class UriIndicator extends React.PureComponent {
componentWillMount() { componentWillMount() {
@ -19,7 +21,7 @@ class UriIndicator extends React.PureComponent {
} }
render() { render() {
const { claim, uri, isResolvingUri } = this.props; const { claim, link, uri, isResolvingUri } = this.props;
if (isResolvingUri && !claim) { if (isResolvingUri && !claim) {
return <span className="empty">Validating...</span>; return <span className="empty">Validating...</span>;
@ -33,21 +35,30 @@ class UriIndicator extends React.PureComponent {
channel_name: channelName, channel_name: channelName,
has_signature: hasSignature, has_signature: hasSignature,
signature_is_valid: signatureIsValid, signature_is_valid: signatureIsValid,
value,
} = claim; } = claim;
const channelClaimId =
value &&
value.publisherSignature &&
value.publisherSignature.certificateId;
if (!hasSignature || !channelName) { if (!hasSignature || !channelName) {
return <span className="empty">Anonymous</span>; return <span className="empty">Anonymous</span>;
} }
let icon, modifier; let icon, channelLink, modifier;
if (signatureIsValid) { if (signatureIsValid) {
modifier = "valid"; modifier = "valid";
channelLink = link
? lbryuri.build({ channelName, claimId: channelClaimId }, false)
: false;
} else { } else {
icon = "icon-times-circle"; icon = "icon-times-circle";
modifier = "invalid"; modifier = "invalid";
} }
return ( const inner = (
<span> <span>
{channelName} {" "} {channelName} {" "}
{!signatureIsValid {!signatureIsValid
@ -58,6 +69,16 @@ class UriIndicator extends React.PureComponent {
: ""} : ""}
</span> </span>
); );
if (!channelLink) {
return inner;
}
return (
<Link navigate="/show" navigateParams={{ uri: channelLink }}>
{inner}
</Link>
);
} }
} }

View file

@ -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);

View file

@ -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 (
<div>
<div className="card__title-primary">
<h1>{__("Support")} <UriIndicator uri={uri} /></h1>
</div>
<div className="card__content">
<FormRow
label={__("Amount")}
postfix={__("LBC")}
min="0"
step="0.1"
type="number"
errorMessage={errorMessage}
helper={
<span>
{__(
'This will appear as a tip for "%s" located at %s.',
title,
uri
) + " "}
<Link
label={__("Learn more")}
href="https://lbry.io/faq/tipping"
/>
</span>
}
placeholder="1.00"
onChange={event => this.handleSupportPriceChange(event)}
/>
<div className="form-row-submit">
<Link
label={__("Send")}
button="primary"
disabled={isPending}
onClick={this.handleSendButtonClicked.bind(this)}
/>
<Link
label={__("Cancel")}
button="alt"
navigate="/show"
navigateParams={{ uri }}
/>
</div>
</div>
</div>
);
}
}
export default WalletSendTip;

View file

@ -39,8 +39,11 @@ export const SEND_TRANSACTION_STARTED = "SEND_TRANSACTION_STARTED";
export const SEND_TRANSACTION_COMPLETED = "SEND_TRANSACTION_COMPLETED"; export const SEND_TRANSACTION_COMPLETED = "SEND_TRANSACTION_COMPLETED";
export const SEND_TRANSACTION_FAILED = "SEND_TRANSACTION_FAILED"; export const SEND_TRANSACTION_FAILED = "SEND_TRANSACTION_FAILED";
export const FETCH_BLOCK_SUCCESS = "FETCH_BLOCK_SUCCESS"; 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_STARTED = "FETCH_FEATURED_CONTENT_STARTED";
export const FETCH_FEATURED_CONTENT_COMPLETED = export const FETCH_FEATURED_CONTENT_COMPLETED =
"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_STARTED = "FETCH_CLAIM_LIST_MINE_STARTED";
export const FETCH_CLAIM_LIST_MINE_COMPLETED = export const FETCH_CLAIM_LIST_MINE_COMPLETED =
"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_STARTED = "FILE_LIST_STARTED";
export const FILE_LIST_SUCCEEDED = "FILE_LIST_SUCCEEDED"; export const FILE_LIST_SUCCEEDED = "FILE_LIST_SUCCEEDED";
export const FETCH_FILE_INFO_STARTED = "FETCH_FILE_INFO_STARTED"; 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_STARTED = "FETCH_AVAILABILITY_STARTED";
export const FETCH_AVAILABILITY_COMPLETED = "FETCH_AVAILABILITY_COMPLETED"; export const FETCH_AVAILABILITY_COMPLETED = "FETCH_AVAILABILITY_COMPLETED";
export const FILE_DELETE = "FILE_DELETE"; 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 // Search
export const SEARCH_STARTED = "SEARCH_STARTED"; 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 CLAIM_REWARD_CLEAR_ERROR = "CLAIM_REWARD_CLEAR_ERROR";
export const FETCH_REWARD_CONTENT_COMPLETED = "FETCH_REWARD_CONTENT_COMPLETED"; 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 //Language
export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED"; export const DOWNLOAD_LANGUAGE_SUCCEEDED = "DOWNLOAD_LANGUAGE_SUCCEEDED";
export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED"; export const DOWNLOAD_LANGUAGE_FAILED = "DOWNLOAD_LANGUAGE_FAILED";

View file

@ -2,16 +2,13 @@ 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 { doDeleteFileAndGoBack } from "actions/file_info"; import { doDeleteFileAndGoBack } from "actions/file_info";
import { import { makeSelectTitleForUri, makeSelectClaimIsMine } from "selectors/claims";
makeSelectMetadataForUri,
makeSelectClaimIsMine,
} from "selectors/claims";
import { makeSelectFileInfoForUri } from "selectors/file_info"; import { makeSelectFileInfoForUri } from "selectors/file_info";
import ModalRemoveFile from "./view"; import ModalRemoveFile from "./view";
const select = (state, props) => ({ const select = (state, props) => ({
claimIsMine: makeSelectClaimIsMine(props.uri)(state), claimIsMine: makeSelectClaimIsMine(props.uri)(state),
metadata: makeSelectMetadataForUri(props.uri)(state), title: makeSelectTitleForUri(props.uri)(state),
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
}); });

View file

@ -30,7 +30,7 @@ class ModalRemoveFile extends React.PureComponent {
closeModal, closeModal,
deleteFile, deleteFile,
fileInfo: { outpoint }, fileInfo: { outpoint },
metadata: { title }, title,
} = this.props; } = this.props;
const { deleteChecked, abandonClaimChecked } = this.state; const { deleteChecked, abandonClaimChecked } = this.state;

View file

@ -1,45 +1,13 @@
import React from "react"; import React from "react";
import ReactMarkdown from "react-markdown";
import lbry from "lbry.js"; import lbry from "lbry.js";
import lbryuri from "lbryuri.js"; import lbryuri from "lbryuri.js";
import Video from "component/video"; import Video from "component/video";
import TipLink from "component/tipLink";
import { Thumbnail } from "component/common"; import { Thumbnail } from "component/common";
import FilePrice from "component/filePrice"; import FilePrice from "component/filePrice";
import FileActions from "component/fileActions"; import FileDetails from "component/fileDetails";
import Link from "component/link";
import UriIndicator from "component/uriIndicator"; import UriIndicator from "component/uriIndicator";
import IconFeatured from "component/iconFeatured"; import IconFeatured from "component/iconFeatured";
import DateTime from "component/dateTime"; import WalletSendTip from "component/walletSendTip";
const FormatItem = props => {
const {
contentType,
claim: { height },
metadata: { language, license },
} = props;
const mediaType = lbry.getMediaType(contentType);
return (
<table className="table-standard table-stretch">
<tbody>
<tr>
<td>{__("Published on")}</td><td><DateTime block={height} /></td>
</tr>
<tr>
<td>{__("Content-Type")}</td><td>{mediaType}</td>
</tr>
<tr>
<td>{__("Language")}</td><td>{language}</td>
</tr>
<tr>
<td>{__("License")}</td><td>{license}</td>
</tr>
</tbody>
</table>
);
};
class FilePage extends React.PureComponent { class FilePage extends React.PureComponent {
componentDidMount() { 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 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 = <UriIndicator uri={uri} />;
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
const mediaType = lbry.getMediaType(contentType); const mediaType = lbry.getMediaType(contentType);
const player = require("render-media"); const player = require("render-media");
@ -109,7 +60,7 @@ class FilePage extends React.PureComponent {
mediaType === "audio"; mediaType === "audio";
return ( return (
<main className="main--single-column"> <div>
<section className="show-page-media"> <section className="show-page-media">
{isPlayable {isPlayable
? <Video className="video-embedded" uri={uri} /> ? <Video className="video-embedded" uri={uri} />
@ -119,6 +70,9 @@ class FilePage extends React.PureComponent {
</section> </section>
<section className={"card " + (obscureNsfw ? "card--obscured " : "")}> <section className={"card " + (obscureNsfw ? "card--obscured " : "")}>
<div className="card__inner"> <div className="card__inner">
{(!tab || tab === "details") &&
<div>
{" "} {" "}
<div className="card__title-identity"> <div className="card__title-identity">
{!fileInfo || fileInfo.written_bytes <= 0 {!fileInfo || fileInfo.written_bytes <= 0
? <span style={{ float: "right" }}> ? <span style={{ float: "right" }}>
@ -128,46 +82,16 @@ class FilePage extends React.PureComponent {
: null} : null}
<h1>{title}</h1> <h1>{title}</h1>
<div className="card__subtitle"> <div className="card__subtitle">
{channelUri <UriIndicator uri={uri} link={true} />
? <Link
onClick={() =>
this.props.navigate("/show", { uri: channelUri })}
>
{uriIndicator}
</Link>
: uriIndicator}
</div> </div>
<FileActions uri={uri} />
</div> </div>
{!showTipBox && <FileDetails uri={uri} />
<div className="card__content card__subtext card__subtext card__subtext--allow-newlines">
<ReactMarkdown
source={(metadata && metadata.description) || ""}
escapeHtml={true}
disallowedTypes={["Heading", "HtmlInline", "HtmlBlock"]}
/>
</div>} </div>}
{tab === "tip" &&
<WalletSendTip claim_id={claim.claim_id} uri={uri} />}
</div> </div>
{metadata && claim && !showTipBox
? <div className="card__content">
<FormatItem
metadata={metadata}
contentType={contentType}
claim={claim}
/>
</div>
: ""}
{showTipBox ? <TipLink claim_id={claim.claim_id} uri={uri} /> : ""}
{!showTipBox &&
<div className="card__content">
<Link
href={`https://lbry.io/dmca?claim_id=${claim.claim_id}`}
label={__("report")}
className="button-text-help"
/>
</div>}
</section> </section>
</main> </div>
); );
} }
} }

View file

@ -2,9 +2,7 @@ import * as types from "constants/action_types";
const reducers = {}; const reducers = {};
const defaultState = { const defaultState = {};
supportTransaction: {},
};
reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) { reducers[types.RESOLVE_URI_COMPLETED] = function(state, action) {
const { uri, certificate, claim } = action.data; 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) { 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);

View file

@ -15,6 +15,7 @@ const defaultState = {
receiveAddress: address, receiveAddress: address,
gettingNewAddress: false, gettingNewAddress: false,
draftTransaction: buildDraftTransaction(), draftTransaction: buildDraftTransaction(),
sendingSupport: false,
}; };
reducers[types.FETCH_TRANSACTIONS_STARTED] = function(state, action) { 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) => { reducers[types.FETCH_BLOCK_SUCCESS] = (state, action) => {
const { block, block: { height } } = action.data, const { block, block: { height } } = action.data,
blocks = Object.assign({}, state.blocks); blocks = Object.assign({}, state.blocks);

View file

@ -97,6 +97,13 @@ export const makeSelectMetadataForUri = uri => {
}); });
}; };
export const makeSelectTitleForUri = uri => {
return createSelector(
makeSelectMetadataForUri(uri),
metadata => metadata && metadata.title
);
};
export const makeSelectContentTypeForUri = uri => { export const makeSelectContentTypeForUri = uri => {
return createSelector(makeSelectClaimForUri(uri), claim => { return createSelector(makeSelectClaimForUri(uri), claim => {
const source = const source =
@ -174,8 +181,3 @@ export const selectMyChannelClaims = createSelector(
return claims; return claims;
} }
); );
export const selectShowTipBox = createSelector(
_selectState,
state => state.supportTransaction.tipBoxShown
);

View file

@ -61,6 +61,11 @@ export const selectIsFetchingTransactions = createSelector(
state => state.fetchingTransactions state => state.fetchingTransactions
); );
export const selectIsSendingSupport = createSelector(
_selectState,
state => state.sendingSupport
);
export const selectReceiveAddress = createSelector( export const selectReceiveAddress = createSelector(
_selectState, _selectState,
state => state.receiveAddress state => state.receiveAddress

View file

@ -7,6 +7,9 @@
border-radius: var(--card-radius); border-radius: var(--card-radius);
margin-bottom: var(--card-margin); margin-bottom: var(--card-margin);
overflow: auto; 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 .card--obscured
{ {
@ -62,6 +65,9 @@
.card__content { .card__content {
margin-top: var(--card-margin); margin-top: var(--card-margin);
margin-bottom: var(--card-margin); margin-bottom: var(--card-margin);
table:not(:last-child) {
margin-bottom: var(--card-margin);
}
} }
$font-size-subtext-multiple: 0.82; $font-size-subtext-multiple: 0.82;
.card__subtext { .card__subtext {