tip/support marriage
This commit is contained in:
parent
44cfe25ac2
commit
019d1f9176
21 changed files with 203 additions and 221 deletions
|
@ -154,15 +154,6 @@ export const icons = {
|
||||||
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
||||||
</g>
|
</g>
|
||||||
),
|
),
|
||||||
[ICONS.TIP]: buildIcon(
|
|
||||||
<g>
|
|
||||||
<polyline points="20 12 20 22 4 22 4 12" />
|
|
||||||
<rect x="2" y="7" width="20" height="5" />
|
|
||||||
<line x1="12" y1="22" x2="12" y2="7" />
|
|
||||||
<path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z" />
|
|
||||||
<path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z" />
|
|
||||||
</g>
|
|
||||||
),
|
|
||||||
[ICONS.SHARE]: buildIcon(
|
[ICONS.SHARE]: buildIcon(
|
||||||
<g>
|
<g>
|
||||||
<circle cx="18" cy="5" r="3" />
|
<circle cx="18" cy="5" r="3" />
|
||||||
|
@ -276,8 +267,11 @@ export const icons = {
|
||||||
),
|
),
|
||||||
[ICONS.SUPPORT]: buildIcon(
|
[ICONS.SUPPORT]: buildIcon(
|
||||||
<g>
|
<g>
|
||||||
<polyline points="23 6 13.5 15.5 8.5 10.5 1 18" />
|
<polyline points="20 12 20 22 4 22 4 12" />
|
||||||
<polyline points="17 6 23 6 23 12" />
|
<rect x="2" y="7" width="20" height="5" />
|
||||||
|
<line x1="12" y1="22" x2="12" y2="7" />
|
||||||
|
<path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z" />
|
||||||
|
<path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z" />
|
||||||
</g>
|
</g>
|
||||||
),
|
),
|
||||||
[ICONS.EYE]: buildIcon(
|
[ICONS.EYE]: buildIcon(
|
||||||
|
|
|
@ -122,7 +122,7 @@ export default function CreatorAnalytics(props: Props) {
|
||||||
follower_count_weekly_change: stats.ChannelSubChange || 0,
|
follower_count_weekly_change: stats.ChannelSubChange || 0,
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{stats.ChannelSubChange > 0 && <Icon icon={ICONS.SUPPORT} iconColor="green" size={18} />}
|
{stats.ChannelSubChange > 0 && <Icon icon={ICONS.TRENDING} iconColor="green" size={18} />}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -136,7 +136,7 @@ export default function CreatorAnalytics(props: Props) {
|
||||||
all_content_views_weekly_change: stats.AllContentViewChange || 0,
|
all_content_views_weekly_change: stats.AllContentViewChange || 0,
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{stats.AllContentViewChange > 0 && <Icon icon={ICONS.SUPPORT} iconColor="green" size={18} />}
|
{stats.AllContentViewChange > 0 && <Icon icon={ICONS.TRENDING} iconColor="green" size={18} />}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -156,7 +156,7 @@ export default function CreatorAnalytics(props: Props) {
|
||||||
lbc_received_changed: stats.LBCReceivedChange || 0,
|
lbc_received_changed: stats.LBCReceivedChange || 0,
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{stats.LBCReceivedChange > 0 && <Icon icon={ICONS.SUPPORT} iconColor="green" size={18} />}
|
{stats.LBCReceivedChange > 0 && <Icon icon={ICONS.TRENDING} iconColor="green" size={18} />}
|
||||||
</div>
|
</div>
|
||||||
<p className="help">
|
<p className="help">
|
||||||
{__(
|
{__(
|
||||||
|
@ -182,7 +182,7 @@ export default function CreatorAnalytics(props: Props) {
|
||||||
? __('1 view', { view_count: stats.VideoViewsTopNew })
|
? __('1 view', { view_count: stats.VideoViewsTopNew })
|
||||||
: __('%view_count% views', { view_count: stats.VideoViewsTopNew })}
|
: __('%view_count% views', { view_count: stats.VideoViewsTopNew })}
|
||||||
</span>
|
</span>
|
||||||
{stats.VideoViewsTopNew > 0 && <Icon icon={ICONS.SUPPORT} iconColor="green" size={18} />}
|
{stats.VideoViewsTopNew > 0 && <Icon icon={ICONS.TRENDING} iconColor="green" size={18} />}
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
@ -230,7 +230,7 @@ export default function CreatorAnalytics(props: Props) {
|
||||||
all_time_views_weekly_change: stats.VideoViewChangeTopAllTime,
|
all_time_views_weekly_change: stats.VideoViewChangeTopAllTime,
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
{stats.VideoViewChangeTopAllTime > 0 && <Icon icon={ICONS.SUPPORT} iconColor="green" size={18} />}
|
{stats.VideoViewChangeTopAllTime > 0 && <Icon icon={ICONS.TRENDING} iconColor="green" size={18} />}
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import * as SETTINGS from 'constants/settings';
|
|
||||||
import { makeSelectClaimIsMine, makeSelectFileInfoForUri, makeSelectClaimForUri, doPrepareEdit } from 'lbry-redux';
|
import { makeSelectClaimIsMine, makeSelectFileInfoForUri, makeSelectClaimForUri, doPrepareEdit } from 'lbry-redux';
|
||||||
import { makeSelectCostInfoForUri } from 'lbryinc';
|
import { makeSelectCostInfoForUri } from 'lbryinc';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import FileActions from './view';
|
import FileActions from './view';
|
||||||
|
@ -14,7 +12,6 @@ const select = (state, props) => ({
|
||||||
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
|
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
|
||||||
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
|
renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
|
||||||
costInfo: makeSelectCostInfoForUri(props.uri)(state),
|
costInfo: makeSelectCostInfoForUri(props.uri)(state),
|
||||||
supportOption: makeSelectClientSetting(SETTINGS.SUPPORT_OPTION)(state),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import type { Node } from 'react';
|
import type { Node } from 'react';
|
||||||
|
import * as PAGES from 'constants/pages';
|
||||||
|
import * as CS from 'constants/claim_search';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -8,6 +10,7 @@ import FileDownloadLink from 'component/fileDownloadLink';
|
||||||
import { buildURI } from 'lbry-redux';
|
import { buildURI } from 'lbry-redux';
|
||||||
import * as RENDER_MODES from 'constants/file_render_modes';
|
import * as RENDER_MODES from 'constants/file_render_modes';
|
||||||
import useIsMobile from 'effects/use-is-mobile';
|
import useIsMobile from 'effects/use-is-mobile';
|
||||||
|
import ClaimSupportButton from 'component/claimSupportButton';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -18,11 +21,10 @@ type Props = {
|
||||||
fileInfo: FileListItem,
|
fileInfo: FileListItem,
|
||||||
costInfo: ?{ cost: number },
|
costInfo: ?{ cost: number },
|
||||||
renderMode: string,
|
renderMode: string,
|
||||||
supportOption: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function FileActions(props: Props) {
|
function FileActions(props: Props) {
|
||||||
const { fileInfo, uri, openModal, claimIsMine, claim, costInfo, renderMode, supportOption, prepareEdit } = props;
|
const { fileInfo, uri, openModal, claimIsMine, claim, costInfo, renderMode, prepareEdit } = props;
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
|
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
|
||||||
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
|
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
|
||||||
|
@ -61,34 +63,25 @@ function FileActions(props: Props) {
|
||||||
label={__('Share')}
|
label={__('Share')}
|
||||||
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })}
|
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })}
|
||||||
/>
|
/>
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
icon={ICONS.REPOST}
|
|
||||||
label={__('Repost %count%', { count: claim.meta.reposted > 0 ? `(${claim.meta.reposted})` : '' })}
|
|
||||||
requiresAuth={IS_WEB}
|
|
||||||
onClick={() => openModal(MODALS.REPOST, { uri })}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!claimIsMine && (
|
<div className="button-group">
|
||||||
<Button
|
<Button
|
||||||
button="alt"
|
button="alt"
|
||||||
icon={ICONS.TIP}
|
icon={ICONS.REPOST}
|
||||||
label={__('Tip')}
|
label={__('Repost')}
|
||||||
requiresAuth={IS_WEB}
|
requiresAuth={IS_WEB}
|
||||||
title={__('Send a tip to this creator')}
|
onClick={() => openModal(MODALS.REPOST, { uri })}
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: false })}
|
|
||||||
/>
|
/>
|
||||||
)}
|
{claim.meta.reposted > 0 && (
|
||||||
{(claimIsMine || (!claimIsMine && supportOption)) && (
|
<Button
|
||||||
<Button
|
button="alt"
|
||||||
button="alt"
|
label={claim.meta.reposted}
|
||||||
icon={ICONS.SUPPORT}
|
requiresAuth={IS_WEB}
|
||||||
label={__('Support')}
|
navigate={`/$/${PAGES.DISCOVER}?${CS.REPOSTED_URI_KEY}=${encodeURIComponent(uri)}`}
|
||||||
requiresAuth={IS_WEB}
|
/>
|
||||||
title={__('Support this claim')}
|
)}
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: true })}
|
</div>
|
||||||
/>
|
<ClaimSupportButton uri={uri} />
|
||||||
)}
|
|
||||||
</ActionWrapper>
|
</ActionWrapper>
|
||||||
|
|
||||||
<ActionWrapper>
|
<ActionWrapper>
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as PAGES from 'constants/pages';
|
|
||||||
import * as CS from 'constants/claim_search';
|
|
||||||
import React, { Fragment, PureComponent } from 'react';
|
import React, { Fragment, PureComponent } from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
fileInfo: FileListItem,
|
fileInfo: FileListItem,
|
||||||
metadata: StreamMetadata,
|
metadata: StreamMetadata,
|
||||||
|
@ -18,7 +15,7 @@ type Props = {
|
||||||
|
|
||||||
class FileDetails extends PureComponent<Props> {
|
class FileDetails extends PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { uri, claim, contentType, fileInfo, metadata, openFolder } = this.props;
|
const { claim, contentType, fileInfo, metadata, openFolder } = this.props;
|
||||||
|
|
||||||
if (!claim || !metadata) {
|
if (!claim || !metadata) {
|
||||||
return <span className="empty">{__('Empty claim or metadata info.')}</span>;
|
return <span className="empty">{__('Empty claim or metadata info.')}</span>;
|
||||||
|
@ -52,18 +49,6 @@ class FileDetails extends PureComponent<Props> {
|
||||||
<td> {__('Content Type')}</td>
|
<td> {__('Content Type')}</td>
|
||||||
<td>{mediaType}</td>
|
<td>{mediaType}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{claim && claim.meta.reposted > 0 && (
|
|
||||||
<tr>
|
|
||||||
<td>{__('Reposts')}</td>
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
button="link"
|
|
||||||
label={__('View %count% reposts', { count: claim.meta.reposted })}
|
|
||||||
navigate={`/$/${PAGES.DISCOVER}?${CS.REPOSTED_URI_KEY}=${encodeURIComponent(uri)}`}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{fileSize && (
|
{fileSize && (
|
||||||
<tr>
|
<tr>
|
||||||
<td> {__('File Size')}</td>
|
<td> {__('File Size')}</td>
|
||||||
|
|
|
@ -83,7 +83,7 @@ const WalletBalance = (props: Props) => {
|
||||||
|
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="section__flex">
|
<div className="section__flex">
|
||||||
<Icon sectionIcon icon={ICONS.TIP} />
|
<Icon sectionIcon icon={ICONS.SUPPORT} />
|
||||||
<h2 className="section__title--small">
|
<h2 className="section__title--small">
|
||||||
<strong>
|
<strong>
|
||||||
<CreditAmount badge={false} amount={tipsBalance} precision={8} />
|
<CreditAmount badge={false} amount={tipsBalance} precision={8} />
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import * as MODALS from 'constants/modal_types';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import { parseURI } from 'lbry-redux';
|
|
||||||
import { FormField, Form } from 'component/common/form';
|
import { FormField, Form } from 'component/common/form';
|
||||||
import { MINIMUM_PUBLISH_BID } from 'constants/claim';
|
import { MINIMUM_PUBLISH_BID } from 'constants/claim';
|
||||||
import useIsMobile from 'effects/use-is-mobile';
|
import useIsMobile from 'effects/use-is-mobile';
|
||||||
import CreditAmount from 'component/common/credit-amount';
|
import CreditAmount from 'component/common/credit-amount';
|
||||||
import I18nMessage from 'component/i18nMessage';
|
import I18nMessage from 'component/i18nMessage';
|
||||||
import * as MODALS from 'constants/modal_types';
|
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
const DEFAULT_TIP_AMOUNTS = [5, 10, 50];
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
claimIsMine: boolean,
|
// claimIsMine: boolean,
|
||||||
title: string,
|
title: string,
|
||||||
claim: StreamClaim,
|
claim: StreamClaim,
|
||||||
isPending: boolean,
|
isPending: boolean,
|
||||||
sendSupport: (number, string, boolean) => void,
|
sendSupport: (number, string, boolean) => void,
|
||||||
onCancel: () => void,
|
|
||||||
closeModal: () => void,
|
closeModal: () => void,
|
||||||
balance: number,
|
balance: number,
|
||||||
isSupport: boolean,
|
isSupport: boolean,
|
||||||
|
@ -31,22 +34,21 @@ function WalletSendTip(props: Props) {
|
||||||
uri,
|
uri,
|
||||||
title,
|
title,
|
||||||
isPending,
|
isPending,
|
||||||
onCancel,
|
// claimIsMine,
|
||||||
claimIsMine,
|
|
||||||
isSupport,
|
|
||||||
balance,
|
balance,
|
||||||
claim,
|
claim = {},
|
||||||
instantTipEnabled,
|
instantTipEnabled,
|
||||||
instantTipMax,
|
instantTipMax,
|
||||||
openModal,
|
openModal,
|
||||||
sendSupport,
|
sendSupport,
|
||||||
closeModal,
|
closeModal,
|
||||||
} = props;
|
} = props;
|
||||||
const [tipAmount, setTipAmount] = React.useState(0);
|
const [tipAmount, setTipAmount] = React.useState(DEFAULT_TIP_AMOUNTS[0]);
|
||||||
const [tipError, setTipError] = React.useState();
|
const [tipError, setTipError] = React.useState();
|
||||||
|
const [isSupport, setIsSupport] = React.useState(false);
|
||||||
|
const [showMore, setShowMore] = React.useState(false);
|
||||||
const { claim_id: claimId } = claim;
|
const { claim_id: claimId } = claim;
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
const { channelName } = parseURI(uri);
|
|
||||||
|
|
||||||
function sendSupportOrConfirm(instantTipMaxAmount = null) {
|
function sendSupportOrConfirm(instantTipMaxAmount = null) {
|
||||||
if (!isSupport && (!instantTipMaxAmount || !instantTipEnabled || tipAmount > instantTipMaxAmount)) {
|
if (!isSupport && (!instantTipMaxAmount || !instantTipEnabled || tipAmount > instantTipMaxAmount)) {
|
||||||
|
@ -99,69 +101,137 @@ function WalletSendTip(props: Props) {
|
||||||
setTipError(tipError);
|
setTipError(tipError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const label =
|
// const label =
|
||||||
tipAmount && tipAmount !== 0
|
// tipAmount && tipAmount !== 0
|
||||||
? __(isSupport ? 'Support %amount% LBC' : 'Tip %amount% LBC', {
|
// ? __(isSupport ? 'Support %amount% LBC' : 'Tip %amount% LBC', {
|
||||||
amount: tipAmount.toFixed(8).replace(/\.?0+$/, ''),
|
// amount: tipAmount.toFixed(8).replace(/\.?0+$/, ''),
|
||||||
})
|
// })
|
||||||
: __('Amount');
|
// : __('Amount');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<Form onSubmit={handleSubmit}>
|
||||||
<Form onSubmit={handleSubmit}>
|
<Card
|
||||||
<FormField
|
title={__('Support This Content')}
|
||||||
autoFocus
|
subtitle={
|
||||||
name="tip-input"
|
<React.Fragment>
|
||||||
label={
|
{__(
|
||||||
<React.Fragment>
|
'This will increase the overall bid amount for this content, which will boost its ability to be discovered while active.'
|
||||||
{label}{' '}
|
)}{' '}
|
||||||
{isMobile && (
|
<Button label={__('Learn more')} button="link" href="https://lbry.com/faq/tipping" />.
|
||||||
<I18nMessage tokens={{ lbc_balance: <CreditAmount badge={false} amount={balance} /> }}>
|
</React.Fragment>
|
||||||
(%lbc_balance% available)
|
}
|
||||||
</I18nMessage>
|
actions={
|
||||||
)}
|
<>
|
||||||
</React.Fragment>
|
<div className="section">
|
||||||
}
|
{DEFAULT_TIP_AMOUNTS.map(amount => (
|
||||||
className="form-field--price-amount"
|
<Button
|
||||||
error={tipError}
|
key={amount}
|
||||||
min="0"
|
button="alt"
|
||||||
step="any"
|
className={classnames('button-toggle', { 'button-toggle--active': tipAmount === amount })}
|
||||||
type="number"
|
label={`${amount} LBC`}
|
||||||
placeholder="1.23"
|
onClick={() => setTipAmount(amount)}
|
||||||
onChange={event => handleSupportPriceChange(event)}
|
/>
|
||||||
inputButton={
|
))}
|
||||||
<Button
|
<Button
|
||||||
button="primary"
|
button="alt"
|
||||||
type="submit"
|
className={classnames('button-toggle', {
|
||||||
label={__('Confirm')}
|
'button-toggle--active': !DEFAULT_TIP_AMOUNTS.includes(tipAmount),
|
||||||
disabled={isPending || tipError || !tipAmount}
|
})}
|
||||||
/>
|
label={__('Custom')}
|
||||||
}
|
onClick={() => setShowMore(true)}
|
||||||
helper={
|
/>
|
||||||
<React.Fragment>
|
</div>
|
||||||
{claimIsMine || isSupport
|
|
||||||
? __(
|
{showMore && (
|
||||||
'This will increase the overall bid amount for %title%, which will boost its ability to be discovered while active.',
|
<div className="section">
|
||||||
{
|
<FormField
|
||||||
title: title || '@' + channelName,
|
autoFocus
|
||||||
}
|
name="tip-input"
|
||||||
)
|
label={
|
||||||
: __(
|
<React.Fragment>
|
||||||
'This will appear as a tip for %title%, which will boost its ability to be discovered while active.',
|
{'Custom support amount'}{' '}
|
||||||
{
|
{isMobile && (
|
||||||
title: title || '@' + channelName,
|
<I18nMessage tokens={{ lbc_balance: <CreditAmount badge={false} amount={balance} /> }}>
|
||||||
}
|
(%lbc_balance% available)
|
||||||
)}{' '}
|
</I18nMessage>
|
||||||
<Button label={__('Learn more')} button="link" href="https://lbry.com/faq/tipping" />.
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
/>
|
className="form-field--price-amount"
|
||||||
</Form>
|
error={tipError}
|
||||||
<div className="section__actions">
|
min="0"
|
||||||
<Button button="link" label={__('Cancel')} onClick={onCancel} />
|
step="any"
|
||||||
</div>
|
type="number"
|
||||||
</React.Fragment>
|
placeholder="1.23"
|
||||||
|
onChange={event => handleSupportPriceChange(event)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="section__actions">
|
||||||
|
<Button
|
||||||
|
autoFocus
|
||||||
|
icon={isSupport ? undefined : ICONS.SUPPORT}
|
||||||
|
button="primary"
|
||||||
|
type="submit"
|
||||||
|
label={
|
||||||
|
isSupport
|
||||||
|
? __('Send Revokable Support')
|
||||||
|
: __('Send a %amount% Tip', { amount: tipAmount ? `${tipAmount} LBC` : '' })
|
||||||
|
}
|
||||||
|
disabled={isPending || tipError || !tipAmount}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
name="toggle-is-support"
|
||||||
|
type="checkbox"
|
||||||
|
label={__('Make this support permanent')}
|
||||||
|
checked={!isSupport}
|
||||||
|
onChange={() => setIsSupport(!isSupport)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WalletSendTip;
|
export default WalletSendTip;
|
||||||
|
|
||||||
|
// <Button
|
||||||
|
// button="primary"
|
||||||
|
// type="submit"
|
||||||
|
// label={__('Confirm')}
|
||||||
|
// disabled={isPending || tipError || !tipAmount}
|
||||||
|
// />;
|
||||||
|
|
||||||
|
// <div className="section__actions">
|
||||||
|
// <FormField
|
||||||
|
// autoFocus
|
||||||
|
// name="tip-input"
|
||||||
|
// label={
|
||||||
|
// <React.Fragment>
|
||||||
|
// {label}{' '}
|
||||||
|
// {isMobile && (
|
||||||
|
// <I18nMessage tokens={{ lbc_balance: <CreditAmount badge={false} amount={balance} /> }}>
|
||||||
|
// (%lbc_balance% available)
|
||||||
|
// </I18nMessage>
|
||||||
|
// )}
|
||||||
|
// </React.Fragment>
|
||||||
|
// }
|
||||||
|
// className="form-field--price-amount"
|
||||||
|
// error={tipError}
|
||||||
|
// min="0"
|
||||||
|
// step="any"
|
||||||
|
// type="number"
|
||||||
|
// placeholder="1.23"
|
||||||
|
// onChange={event => handleSupportPriceChange(event)}
|
||||||
|
// />
|
||||||
|
// <FormField
|
||||||
|
// name="toggle-is-support"
|
||||||
|
// type="checkbox"
|
||||||
|
// label={__('Send this as a tip instead')}
|
||||||
|
// checked={!isSupport}
|
||||||
|
// onChange={() => setIsSupport(!isSupport)}
|
||||||
|
// />
|
||||||
|
// </div>;
|
||||||
|
|
|
@ -36,7 +36,6 @@ export const LOCK = 'Lock';
|
||||||
export const WEB = 'Globe';
|
export const WEB = 'Globe';
|
||||||
export const SHARE = 'Share2';
|
export const SHARE = 'Share2';
|
||||||
export const EXTERNAL = 'ExternalLink';
|
export const EXTERNAL = 'ExternalLink';
|
||||||
export const TIP = 'Gift';
|
|
||||||
export const PLAY = 'Play';
|
export const PLAY = 'Play';
|
||||||
export const FACEBOOK = 'Facebook';
|
export const FACEBOOK = 'Facebook';
|
||||||
export const TWITTER = 'Twitter';
|
export const TWITTER = 'Twitter';
|
||||||
|
|
|
@ -17,7 +17,6 @@ export const AUTOPLAY = 'autoplay';
|
||||||
export const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
|
export const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled';
|
||||||
export const AUTO_DOWNLOAD = 'auto_download';
|
export const AUTO_DOWNLOAD = 'auto_download';
|
||||||
export const AUTO_LAUNCH = 'auto_launch';
|
export const AUTO_LAUNCH = 'auto_launch';
|
||||||
export const SUPPORT_OPTION = 'support_option';
|
|
||||||
export const HIDE_BALANCE = 'hide_balance';
|
export const HIDE_BALANCE = 'hide_balance';
|
||||||
export const HIDE_SPLASH_ANIMATION = 'hide_splash_animation';
|
export const HIDE_SPLASH_ANIMATION = 'hide_splash_animation';
|
||||||
export const FLOATING_PLAYER = 'floating_player';
|
export const FLOATING_PLAYER = 'floating_player';
|
||||||
|
|
|
@ -2,9 +2,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Modal } from 'modal/modal';
|
import { Modal } from 'modal/modal';
|
||||||
import SendTip from 'component/walletSendTip';
|
import SendTip from 'component/walletSendTip';
|
||||||
import UriIndicator from 'component/uriIndicator';
|
|
||||||
import I18nMessage from 'component/i18nMessage';
|
|
||||||
import Card from 'component/common/card';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
closeModal: () => void,
|
closeModal: () => void,
|
||||||
|
@ -15,26 +12,11 @@ type Props = {
|
||||||
|
|
||||||
class ModalSendTip extends React.PureComponent<Props> {
|
class ModalSendTip extends React.PureComponent<Props> {
|
||||||
render() {
|
render() {
|
||||||
const { closeModal, uri, claimIsMine, isSupport } = this.props;
|
const { closeModal, uri, claimIsMine } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal onAborted={closeModal} isOpen type="card">
|
<Modal onAborted={closeModal} isOpen type="card">
|
||||||
<Card
|
<SendTip uri={uri} claimIsMine={claimIsMine} onCancel={closeModal} />
|
||||||
title={
|
|
||||||
claimIsMine || isSupport ? (
|
|
||||||
__('Support This Claim')
|
|
||||||
) : (
|
|
||||||
<I18nMessage
|
|
||||||
tokens={{
|
|
||||||
url: <UriIndicator uri={uri} inline />,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Send a tip to %url%
|
|
||||||
</I18nMessage>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
actions={<SendTip uri={uri} claimIsMine={claimIsMine} isSupport={isSupport} onCancel={closeModal} />}
|
|
||||||
/>
|
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import {
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { selectBlackListedOutpoints, doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
|
import { selectBlackListedOutpoints, doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
|
||||||
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import ChannelPage from './view';
|
import ChannelPage from './view';
|
||||||
|
|
||||||
|
@ -25,17 +24,12 @@ const select = (state, props) => ({
|
||||||
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
|
isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
|
||||||
channelIsBlocked: selectChannelIsBlocked(props.uri)(state),
|
channelIsBlocked: selectChannelIsBlocked(props.uri)(state),
|
||||||
blackListedOutpoints: selectBlackListedOutpoints(state),
|
blackListedOutpoints: selectBlackListedOutpoints(state),
|
||||||
supportOption: makeSelectClientSetting(settings.SUPPORT_OPTION)(state),
|
|
||||||
showMature: makeSelectClientSetting(settings.SHOW_MATURE)(state),
|
showMature: makeSelectClientSetting(settings.SHOW_MATURE)(state),
|
||||||
subCount: makeSelectSubCountForUri(props.uri)(state),
|
subCount: makeSelectSubCountForUri(props.uri)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
|
|
||||||
fetchSubCount: claimId => dispatch(doFetchSubCount(claimId)),
|
fetchSubCount: claimId => dispatch(doFetchSubCount(claimId)),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(
|
export default connect(select, perform)(ChannelPage);
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(ChannelPage);
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as MODALS from 'constants/modal_types';
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
|
@ -25,6 +24,7 @@ import HelpLink from 'component/common/help-link';
|
||||||
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
import DateTime from 'component/dateTime';
|
import DateTime from 'component/dateTime';
|
||||||
|
import ClaimSupportButton from 'component/claimSupportButton';
|
||||||
|
|
||||||
const PAGE_VIEW_QUERY = `view`;
|
const PAGE_VIEW_QUERY = `view`;
|
||||||
const ABOUT_PAGE = `about`;
|
const ABOUT_PAGE = `about`;
|
||||||
|
@ -50,8 +50,6 @@ type Props = {
|
||||||
txid: string,
|
txid: string,
|
||||||
nout: number,
|
nout: number,
|
||||||
}>,
|
}>,
|
||||||
openModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void,
|
|
||||||
supportOption: boolean,
|
|
||||||
fetchSubCount: string => void,
|
fetchSubCount: string => void,
|
||||||
subCount: number,
|
subCount: number,
|
||||||
showMature: boolean,
|
showMature: boolean,
|
||||||
|
@ -71,8 +69,6 @@ function ChannelPage(props: Props) {
|
||||||
isSubscribed,
|
isSubscribed,
|
||||||
channelIsBlocked,
|
channelIsBlocked,
|
||||||
blackListedOutpoints,
|
blackListedOutpoints,
|
||||||
openModal,
|
|
||||||
supportOption,
|
|
||||||
showMature,
|
showMature,
|
||||||
fetchSubCount,
|
fetchSubCount,
|
||||||
subCount,
|
subCount,
|
||||||
|
@ -203,24 +199,7 @@ function ChannelPage(props: Props) {
|
||||||
<header className="channel-cover">
|
<header className="channel-cover">
|
||||||
<div className="channel__quick-actions">
|
<div className="channel__quick-actions">
|
||||||
{!channelIsBlocked && !channelIsBlackListed && <ShareButton uri={uri} />}
|
{!channelIsBlocked && !channelIsBlackListed && <ShareButton uri={uri} />}
|
||||||
{!channelIsMine && (
|
{!channelIsBlocked && <ClaimSupportButton uri={uri} />}
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
icon={ICONS.TIP}
|
|
||||||
label={__('Tip')}
|
|
||||||
title={__('Send a tip to this creator')}
|
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: false })}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{(channelIsMine || (!channelIsMine && supportOption)) && (
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
icon={ICONS.SUPPORT}
|
|
||||||
label={__('Support')}
|
|
||||||
title={__('Support this creator')}
|
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: true })}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!channelIsBlocked && (!channelIsBlackListed || isSubscribed) && <SubscribeButton uri={permanentUrl} />}
|
{!channelIsBlocked && (!channelIsBlackListed || isSubscribed) && <SubscribeButton uri={permanentUrl} />}
|
||||||
{!isSubscribed && <BlockButton uri={permanentUrl} />}
|
{!isSubscribed && <BlockButton uri={permanentUrl} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -41,7 +41,6 @@ const select = state => ({
|
||||||
walletEncrypted: selectWalletIsEncrypted(state),
|
walletEncrypted: selectWalletIsEncrypted(state),
|
||||||
osNotificationsEnabled: selectosNotificationsEnabled(state),
|
osNotificationsEnabled: selectosNotificationsEnabled(state),
|
||||||
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
|
autoDownload: makeSelectClientSetting(SETTINGS.AUTO_DOWNLOAD)(state),
|
||||||
supportOption: makeSelectClientSetting(SETTINGS.SUPPORT_OPTION)(state),
|
|
||||||
userBlockedChannelsCount: selectBlockedChannelsCount(state),
|
userBlockedChannelsCount: selectBlockedChannelsCount(state),
|
||||||
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
hideBalance: makeSelectClientSetting(SETTINGS.HIDE_BALANCE)(state),
|
||||||
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
|
floatingPlayer: makeSelectClientSetting(SETTINGS.FLOATING_PLAYER)(state),
|
||||||
|
|
|
@ -75,7 +75,6 @@ type Props = {
|
||||||
updateWalletStatus: () => void,
|
updateWalletStatus: () => void,
|
||||||
walletEncrypted: boolean,
|
walletEncrypted: boolean,
|
||||||
osNotificationsEnabled: boolean,
|
osNotificationsEnabled: boolean,
|
||||||
supportOption: boolean,
|
|
||||||
userBlockedChannelsCount?: number,
|
userBlockedChannelsCount?: number,
|
||||||
hideBalance: boolean,
|
hideBalance: boolean,
|
||||||
confirmForgetPassword: ({}) => void,
|
confirmForgetPassword: ({}) => void,
|
||||||
|
@ -239,7 +238,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
setDaemonSetting,
|
setDaemonSetting,
|
||||||
setClientSetting,
|
setClientSetting,
|
||||||
toggle3PAnalytics,
|
toggle3PAnalytics,
|
||||||
supportOption,
|
|
||||||
hideBalance,
|
hideBalance,
|
||||||
userBlockedChannelsCount,
|
userBlockedChannelsCount,
|
||||||
floatingPlayer,
|
floatingPlayer,
|
||||||
|
@ -488,11 +486,11 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
actions={
|
actions={
|
||||||
<p>
|
<p>
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{
|
{userBlockedChannelsCount === 0
|
||||||
userBlockedChannelsCount === 0 ? __("You don't have blocked channels.")
|
? __("You don't have blocked channels.")
|
||||||
: userBlockedChannelsCount === 1 ? __('You have one blocked channel.') +' '
|
: userBlockedChannelsCount === 1
|
||||||
: __('You have %channels% blocked channels.', {channels: userBlockedChannelsCount})+' '
|
? __('You have one blocked channel.') + ' '
|
||||||
}
|
: __('You have %channels% blocked channels.', { channels: userBlockedChannelsCount }) + ' '}
|
||||||
{
|
{
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
|
@ -743,35 +741,11 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{/* @endif */}
|
{/* @endif */}
|
||||||
{(!IS_WEB || isAuthenticated) && (
|
{!IS_WEB && (
|
||||||
<Card
|
<Card
|
||||||
title={__('Experimental Settings')}
|
title={__('Experimental Settings')}
|
||||||
actions={
|
actions={
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<FormField
|
|
||||||
type="checkbox"
|
|
||||||
name="support_option"
|
|
||||||
onChange={() => setClientSetting(SETTINGS.SUPPORT_OPTION, !supportOption)}
|
|
||||||
checked={supportOption}
|
|
||||||
label={__('Enable claim support')}
|
|
||||||
helper={
|
|
||||||
<I18nMessage
|
|
||||||
tokens={{
|
|
||||||
discovery_link: (
|
|
||||||
<Button button="link" label={__('discovery')} href="https://lbry.com/faq/trending" />
|
|
||||||
),
|
|
||||||
vanity_names_link: (
|
|
||||||
<Button button="link" label={__('vanity names')} href="https://lbry.com/faq/naming" />
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
This will add a Support button along side tipping. Similar to tips, supports help
|
|
||||||
%discovery_link% but the LBC is returned to your wallet if revoked. Both also help secure your
|
|
||||||
%vanity_names_link%.
|
|
||||||
</I18nMessage>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* @if TARGET='app' */}
|
{/* @if TARGET='app' */}
|
||||||
{/*
|
{/*
|
||||||
Disabling below until we get downloads to work with shared subscriptions code
|
Disabling below until we get downloads to work with shared subscriptions code
|
||||||
|
|
|
@ -30,7 +30,6 @@ const defaultState = {
|
||||||
[SETTINGS.LANGUAGE]: settingLanguage.find(language => SUPPORTED_LANGUAGES[language]),
|
[SETTINGS.LANGUAGE]: settingLanguage.find(language => SUPPORTED_LANGUAGES[language]),
|
||||||
[SETTINGS.THEME]: __('light'),
|
[SETTINGS.THEME]: __('light'),
|
||||||
[SETTINGS.THEMES]: [__('light'), __('dark')],
|
[SETTINGS.THEMES]: [__('light'), __('dark')],
|
||||||
[SETTINGS.SUPPORT_OPTION]: false,
|
|
||||||
[SETTINGS.HIDE_SPLASH_ANIMATION]: false,
|
[SETTINGS.HIDE_SPLASH_ANIMATION]: false,
|
||||||
[SETTINGS.HIDE_BALANCE]: false,
|
[SETTINGS.HIDE_BALANCE]: false,
|
||||||
[SETTINGS.OS_NOTIFICATIONS_ENABLED]: true,
|
[SETTINGS.OS_NOTIFICATIONS_ENABLED]: true,
|
||||||
|
|
|
@ -141,3 +141,18 @@ svg + .button__label,
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.button:first-child {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: 1px solid var(--color-button-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:nth-child(2) {
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ input-submit {
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='number'] {
|
input[type='number'] {
|
||||||
width: 8em;
|
width: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset-group {
|
fieldset-group {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
height: 3.5rem;
|
|
||||||
width: 3.5rem;
|
width: 3.5rem;
|
||||||
border-radius: calc(3.5rem / 2);
|
border-radius: calc(3.5rem / 2);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -122,9 +122,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button--primary ~ .button--link {
|
.button--primary ~ .button--link,
|
||||||
|
.button--secondary ~ .button--link {
|
||||||
margin-left: var(--spacing-s);
|
margin-left: var(--spacing-s);
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-s) var(--spacing-m);
|
||||||
|
height: var(--button-height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
--color-button-alt-bg-hover: #3e464d;
|
--color-button-alt-bg-hover: #3e464d;
|
||||||
--color-button-alt-text: #e2e9f0;
|
--color-button-alt-text: #e2e9f0;
|
||||||
--color-header-button: var(--color-link-icon);
|
--color-header-button: var(--color-link-icon);
|
||||||
|
--color-button-border: var(--color-gray-5);
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
--color-focus: #2d69a5;
|
--color-focus: #2d69a5;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
--color-link-active: var(--color-primary);
|
--color-link-active: var(--color-primary);
|
||||||
--color-navigation-link: var(--color-gray-5);
|
--color-navigation-link: var(--color-gray-5);
|
||||||
--color-header-button: #f7f7f7;
|
--color-header-button: #f7f7f7;
|
||||||
|
--color-button-border: var(--color-gray-3);
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
--color-background: #f9f9f9;
|
--color-background: #f9f9f9;
|
||||||
|
|
Loading…
Reference in a new issue