tip/support marriage

This commit is contained in:
Sean Yesmunt 2020-06-08 14:42:29 -04:00
parent 44cfe25ac2
commit 019d1f9176
21 changed files with 203 additions and 221 deletions

View file

@ -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(

View file

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

View file

@ -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 => ({

View file

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

View file

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

View file

@ -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} />

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

@ -12,7 +12,7 @@ input-submit {
} }
input[type='number'] { input[type='number'] {
width: 8em; width: 5rem;
} }
fieldset-group { fieldset-group {

View file

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

View file

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

View file

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

View file

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