[redesign] some more fixes #1288

Merged
neb-b merged 11 commits from redesign-fixes into master 2018-04-17 19:54:37 +02:00
30 changed files with 280 additions and 207 deletions

View file

@ -23,7 +23,7 @@ export default class Address extends React.PureComponent<Props> {
const { address, doShowSnackBar } = this.props; const { address, doShowSnackBar } = this.props;
return ( return (
<FormRow verticallyCentered padded> <FormRow verticallyCentered padded stretch>
<input <input
className="input-copyable form-field__input" className="input-copyable form-field__input"
readOnly readOnly

View file

@ -158,7 +158,7 @@ class CardVerify extends React.Component {
render() { render() {
return ( return (
<Button <Button
button="alt" button="primary"
label={this.props.label} label={this.props.label}
icon={icons.LOCK} icon={icons.LOCK}
disabled={this.props.disabled || this.state.open || this.hasPendingClick} disabled={this.props.disabled || this.state.open || this.hasPendingClick}

View file

@ -36,6 +36,8 @@ export class FormField extends React.PureComponent<Props> {
...inputProps ...inputProps
} = this.props; } = this.props;
const errorMessage = typeof error === 'object' ? error.message : error;
let input; let input;
if (type) { if (type) {
if (type === 'select') { if (type === 'select') {
@ -54,6 +56,8 @@ export class FormField extends React.PureComponent<Props> {
/> />
</div> </div>
); );
} else if (type === 'textarea') {
input = <textarea type={type} id={name} {...inputProps} />;
} else { } else {
input = <input type={type} id={name} {...inputProps} />; input = <input type={type} id={name} {...inputProps} />;
} }
@ -65,13 +69,13 @@ export class FormField extends React.PureComponent<Props> {
'form-field--stretch': stretch || type === 'markdown', 'form-field--stretch': stretch || type === 'markdown',
})} })}
> >
{(label || error) && ( {(label || errorMessage) && (
<label <label
className={classnames('form-field__label', { 'form-field__error': error })} className={classnames('form-field__label', { 'form-field__error': errorMessage })}
htmlFor={name} htmlFor={name}
> >
{!error && label} {!errorMessage && label}
{error} {errorMessage}
</label> </label>
)} )}
<div <div

View file

@ -8,6 +8,7 @@ type Props = {
children: React.Node, children: React.Node,
padded?: boolean, padded?: boolean,
verticallyCentered?: boolean, verticallyCentered?: boolean,
stretch?: boolean,
}; };
export class FormRow extends React.PureComponent<Props> { export class FormRow extends React.PureComponent<Props> {
@ -16,13 +17,14 @@ export class FormRow extends React.PureComponent<Props> {
}; };
render() { render() {
const { centered, children, padded, verticallyCentered } = this.props; const { centered, children, padded, verticallyCentered, stretch } = this.props;
return ( return (
<div <div
className={classnames('form-row', { className={classnames('form-row', {
'form-row--centered': centered, 'form-row--centered': centered,
'form-row--padded': padded, 'form-row--padded': padded,
'form-row--vertically-centered': verticallyCentered, 'form-row--vertically-centered': verticallyCentered,
'form-row--stretch': stretch,
})} })}
> >
{children} {children}

View file

@ -1,18 +1,30 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import QRCodeElement from 'qrcode.react'; import QRCodeElement from 'qrcode.react';
import classnames from 'classnames';
type Props = { type Props = {
value: string, value: string,
paddingRight?: boolean,
}; };
const QRCode = (props: Props) => { class QRCode extends React.Component<Props> {
const { value } = props; static defaultProps = {
return ( paddingRight: false,
<div className="qr-code"> };
<QRCodeElement value={value} />
</div> render() {
); const { value, paddingRight } = this.props;
}; return (
<div
className={classnames('qr-code', {
'qr-code--right-padding': paddingRight,
})}
>
<QRCodeElement value={value} />
</div>
);
}
}
export default QRCode; export default QRCode;

View file

@ -7,7 +7,7 @@ type Props = {
editingURI: ?string, editingURI: ?string,
isResolvingUri: boolean, isResolvingUri: boolean,
winningBidForClaimUri: ?number, winningBidForClaimUri: ?number,
claimIsMine: ?boolean, myClaimForUri: ?{},
onEditMyClaim: any => void, onEditMyClaim: any => void,
}; };
@ -18,7 +18,7 @@ class BidHelpText extends React.PureComponent<Props> {
editingURI, editingURI,
isResolvingUri, isResolvingUri,
winningBidForClaimUri, winningBidForClaimUri,
claimIsMine, myClaimForUri,
onEditMyClaim, onEditMyClaim,
} = this.props; } = this.props;
@ -34,12 +34,12 @@ class BidHelpText extends React.PureComponent<Props> {
return __('Checking the winning claim amount...'); return __('Checking the winning claim amount...');
} }
if (claimIsMine) { if (myClaimForUri) {
return ( return (
<React.Fragment> <React.Fragment>
{__('You already have a claim at')} {__('You already have a claim at')}
{` ${uri} `} {` ${uri} `}
<Button button="link" label="Edit it" onClick={onEditMyClaim} /> <Button button="link" label="Edit it" onClick={() => onEditMyClaim(myClaimForUri, uri)} />
<br /> <br />
{__('Publishing will update your existing claim.')} {__('Publishing will update your existing claim.')}
</React.Fragment> </React.Fragment>

View file

@ -55,7 +55,7 @@ type Props = {
clearPublish: () => void, clearPublish: () => void,
resolveUri: string => void, resolveUri: string => void,
scrollToTop: () => void, scrollToTop: () => void,
prepareEdit: ({}) => void, prepareEdit: ({}, uri) => void,
}; };
class PublishForm extends React.PureComponent<Props> { class PublishForm extends React.PureComponent<Props> {
@ -159,10 +159,10 @@ class PublishForm extends React.PureComponent<Props> {
updatePublishForm({ bid, bidError }); updatePublishForm({ bid, bidError });
} }
editExistingClaim() { editExistingClaim(myClaimForUri: ?{}, uri: string) {
const { myClaimForUri, prepareEdit, scrollToTop } = this.props; const { prepareEdit, scrollToTop } = this.props;
if (myClaimForUri) { if (myClaimForUri) {
prepareEdit(myClaimForUri); prepareEdit(myClaimForUri, uri);
scrollToTop(); scrollToTop();
} }
} }
@ -300,7 +300,8 @@ class PublishForm extends React.PureComponent<Props> {
const formDisabled = (!filePath && !editingURI) || publishing; const formDisabled = (!filePath && !editingURI) || publishing;
const formValid = this.checkIsFormValid(); const formValid = this.checkIsFormValid();
const isStillEditing = editingURI === uri; const simpleUri = uri && uri.split('#')[0];
const isStillEditing = editingURI === simpleUri;
let submitLabel; let submitLabel;
if (isStillEditing) { if (isStillEditing) {
submitLabel = !publishing ? __('Edit') : __('Editing...'); submitLabel = !publishing ? __('Edit') : __('Editing...');
@ -446,11 +447,11 @@ class PublishForm extends React.PureComponent<Props> {
error={nameError} error={nameError}
helper={ helper={
<BidHelpText <BidHelpText
uri={uri} uri={simpleUri}
editingURI={editingURI} editingURI={editingURI}
isResolvingUri={isResolvingUri} isResolvingUri={isResolvingUri}
winningBidForClaimUri={winningBidForClaimUri} winningBidForClaimUri={winningBidForClaimUri}
claimIsMine={!!myClaimForUri} myClaimForUri={myClaimForUri}
onEditMyClaim={this.editExistingClaim} onEditMyClaim={this.editExistingClaim}
/> />
} }

View file

@ -1,14 +1,28 @@
// @flow
import React from 'react'; import React from 'react';
import Modal from 'modal/modal'; import { Modal } from 'modal/modal';
import Button from 'component/button'; import Button from 'component/button';
const RewardLink = props => { type Reward = {
const { reward, button, claimReward, clearError, errorMessage, label, isPending } = props; reward_amount: number,
};
type Props = {
isPending: boolean,
label: ?string,
errorMessage: ?string,
reward: Reward,
clearError: Reward => void,
claimReward: Reward => void,
};
const RewardLink = (props: Props) => {
const { reward, claimReward, clearError, errorMessage, label, isPending } = props;
return !reward ? null : ( return !reward ? null : (
<div className="reward-link"> <div className="reward-link">
<Button <Button
button="primary" button="link"
disabled={isPending} disabled={isPending}
label={isPending ? __('Claiming...') : label || `${__('Get')} ${reward.reward_amount} LBC`} label={isPending ? __('Claiming...') : label || `${__('Get')} ${reward.reward_amount} LBC`}
onClick={() => { onClick={() => {
@ -16,6 +30,7 @@ const RewardLink = props => {
}} }}
/> />
{errorMessage ? ( {errorMessage ? (
// TODO: This should be moved to redux
<Modal <Modal
isOpen isOpen
contentLabel="Reward Claim Error" contentLabel="Reward Claim Error"
@ -32,4 +47,5 @@ const RewardLink = props => {
</div> </div>
); );
}; };
export default RewardLink; export default RewardLink;

View file

@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import SettingsPage from 'page/settings'; import SettingsPage from 'page/settings';
import HelpPage from 'page/help'; import HelpPage from 'page/help';
import ReportPage from 'page/report.js'; import ReportPage from 'page/report';
import WalletPage from 'page/wallet'; import WalletPage from 'page/wallet';
import GetCreditsPage from '../../page/getCredits'; import GetCreditsPage from 'page/getCredits';
import SendReceivePage from 'page/sendCredits'; import SendReceivePage from 'page/sendCredits';
import ShowPage from 'page/show'; import ShowPage from 'page/show';
import PublishPage from 'page/publish'; import PublishPage from 'page/publish';

View file

@ -16,7 +16,6 @@ type Props = {
shiftOrderId: ?string, shiftOrderId: ?string,
originCoinDepositMax: ?number, originCoinDepositMax: ?number,
clearShapeShift: Dispatch, clearShapeShift: Dispatch,
doShowSnackBar: Dispatch,
getActiveShift: Dispatch, getActiveShift: Dispatch,
shapeShiftRate: ?number, shapeShiftRate: ?number,
originCoinDepositMax: ?number, originCoinDepositMax: ?number,
@ -25,8 +24,6 @@ type Props = {
}; };
class ActiveShapeShift extends React.PureComponent<Props> { class ActiveShapeShift extends React.PureComponent<Props> {
continousFetch: ?number;
constructor() { constructor() {
super(); super();
this.continousFetch = undefined; this.continousFetch = undefined;
@ -59,6 +56,8 @@ class ActiveShapeShift extends React.PureComponent<Props> {
} }
} }
continousFetch: ?number;
render() { render() {
const { const {
shiftCoinType, shiftCoinType,
@ -68,7 +67,6 @@ class ActiveShapeShift extends React.PureComponent<Props> {
shiftState, shiftState,
originCoinDepositMax, originCoinDepositMax,
clearShapeShift, clearShapeShift,
doShowSnackBar,
shapeShiftRate, shapeShiftRate,
originCoinDepositFee, originCoinDepositFee,
originCoinDepositMin, originCoinDepositMin,
@ -95,8 +93,8 @@ class ActiveShapeShift extends React.PureComponent<Props> {
{shiftDepositAddress && ( {shiftDepositAddress && (
<FormRow verticallyCentered padded> <FormRow verticallyCentered padded>
<Address address={shiftDepositAddress} showCopyButton /> <QRCode value={shiftDepositAddress} paddingRight />
<QRCode value={shiftDepositAddress} /> <Address address={shiftDepositAddress} showCopyButton padded />
</FormRow> </FormRow>
)} )}
</div> </div>

View file

@ -19,7 +19,6 @@ type Props = {
isSubmitting: boolean, isSubmitting: boolean,
shiftSupportedCoins: Array<string>, shiftSupportedCoins: Array<string>,
originCoin: string, originCoin: string,
updating: boolean,
getCoinStats: Dispatch, getCoinStats: Dispatch,
originCoinDepositFee: number, originCoinDepositFee: number,
originCoinDepositMin: string, originCoinDepositMin: string,
@ -38,7 +37,6 @@ export default (props: Props) => {
isSubmitting, isSubmitting,
shiftSupportedCoins, shiftSupportedCoins,
originCoin, originCoin,
updating,
getCoinStats, getCoinStats,
originCoinDepositMax, originCoinDepositMax,
originCoinDepositMin, originCoinDepositMin,
@ -51,7 +49,7 @@ export default (props: Props) => {
prefix={__('Exchange')} prefix={__('Exchange')}
postfix={__('for LBC')} postfix={__('for LBC')}
type="select" type="select"
name="origin_coin" name="originCoin"
onChange={e => { onChange={e => {
getCoinStats(e.target.value); getCoinStats(e.target.value);
handleChange(e); handleChange(e);
@ -76,7 +74,7 @@ export default (props: Props) => {
label={__('Return address')} label={__('Return address')}
error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress} error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress}
type="text" type="text"
name="return_address" name="returnAddress"
className="input--address" className="input--address"
placeholder={getExampleAddress(originCoin)} placeholder={getExampleAddress(originCoin)}
onChange={handleChange} onChange={handleChange}

View file

@ -1,7 +1,7 @@
// I'll come back to this // I'll come back to this
/* eslint-disable */ /* eslint-disable */
import React from 'react'; import React from 'react';
import { Form, FormRow, FormField } from 'component/common/form'; import { Form, FormRow, FormField, Submit } from 'component/common/form';
const os = require('os').type(); const os = require('os').type();
const countryCodes = require('country-data') const countryCodes = require('country-data')
@ -77,37 +77,30 @@ class UserPhoneNew extends React.PureComponent {
)} )}
</p> </p>
<Form onSubmit={this.handleSubmit.bind(this)}> <Form onSubmit={this.handleSubmit.bind(this)}>
<div className="form-row-phone"> <FormRow>
<FormField type="select" name="country-codes" onChange={this.handleSelect.bind(this)}>
{countryCodes.map((country, index) => (
<option key={index} value={country.countryCallingCode}>
{os === 'Darwin' ? country.emoji : `(${country.alpha2})`}{' '}
{country.countryCallingCode}
</option>
))}
</FormField>
<FormField <FormField
onChange={this.handleSelect.bind(this)} type="text"
render={() => ( placeholder={this.state.country_code === '+1' ? '(555) 555-5555' : '5555555555'}
<select> name="phone"
{countryCodes.map((country, index) => ( value={this.state.phone}
<option key={index} value={country.countryCallingCode}> error={phoneErrorMessage}
{os === 'Darwin' ? country.emoji : `(${country.alpha2})`}{' '}
{country.countryCallingCode}
</option>
))}
</select>
)}
/>
<FormField
errorMessage={phoneErrorMessage}
onChange={event => { onChange={event => {
this.handleChanged(event); this.handleChanged(event);
}} }}
render={() => (
<input
type="text"
placeholder={this.state.country_code === '+1' ? '(555) 555-5555' : '5555555555'}
name="phone"
value={this.state.phone}
/>
)}
/> />
</FormRow>
<div className="card__actions card__actions--center">
<Submit label="Submit" disabled={isPending} />
{cancelButton}
</div> </div>
<Submit label="Submit" disabled={isPending} />
{cancelButton}
</Form> </Form>
</div> </div>
); );

View file

@ -2,7 +2,7 @@
/* eslint-disable */ /* eslint-disable */
import React from 'react'; import React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import { Form, FormElement, Submit } from 'component/common/form'; import { Form, FormField, Submit } from 'component/common/form';
class UserPhoneVerify extends React.PureComponent { class UserPhoneVerify extends React.PureComponent {
constructor(props) { constructor(props) {
@ -37,31 +37,27 @@ class UserPhoneVerify extends React.PureComponent {
{__( {__(
`Please enter the verification code sent to +${countryCode}${phone}. Didn't receive it? ` `Please enter the verification code sent to +${countryCode}${phone}. Didn't receive it? `
)} )}
<Button onClick={this.reset.bind(this)} label="Go back." /> <Button button="link" onClick={this.reset.bind(this)} label="Go back." />
</p> </p>
<FormElement <FormField
type="text"
name="code"
value={this.state.code}
onChange={event => {
this.handleCodeChanged(event);
}}
label={__('Verification Code')} label={__('Verification Code')}
errorMessage={phoneErrorMessage} error={phoneErrorMessage}
render={() => (
<input
type="text"
name="code"
value={this.state.code}
onChange={event => {
this.handleCodeChanged(event);
}}
/>
)}
/> />
{/* render help separately so it always shows */} {/* render help separately so it always shows */}
<div className="form-field__helper"> <div className="meta">
<p> <p>
{__('Email')} <Button href="mailto:help@lbry.io" label="help@lbry.io" /> or join our{' '} {__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" />{' '}
<Button href="https://chat.lbry.io" label="chat" />{' '} or join our <Button button="link" href="https://chat.lbry.io" label="chat" />{' '}
{__('if you encounter any trouble with your code.')} {__('if you encounter any trouble with your code.')}
</p> </p>
</div> </div>
<div className="form-row-submit"> <div className="card__actions card__actions--center">
<Submit label={__('Verify')} /> <Submit label={__('Verify')} />
{cancelButton} {cancelButton}
</div> </div>

View file

@ -1,31 +1,31 @@
/* eslint-disable */ // @flow
import React from 'react'; import * as React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import CardVerify from 'component/cardVerify'; import CardVerify from 'component/cardVerify';
import lbryio from 'lbryio.js'; import lbryio from 'lbryio';
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
class UserVerify extends React.PureComponent { type Props = {
constructor(props) { errorMessage: ?string,
super(props); isPending: boolean,
navigate: string => void,
verifyUserIdentity: string => void,
verifyPhone: () => void,
};
this.state = { class UserVerify extends React.PureComponent<Props> {
code: '', constructor() {
}; super();
(this: any).onToken = this.onToken.bind(this);
} }
handleCodeChanged(event) { onToken(data: { id: string }) {
this.setState({
code: event.target.value,
});
}
onToken(data) {
this.props.verifyUserIdentity(data.id); this.props.verifyUserIdentity(data.id);
} }
render() { render() {
const { errorMessage, isPending, navigate, verifyPhone, modal } = this.props; const { errorMessage, isPending, navigate, verifyPhone } = this.props;
return ( return (
<React.Fragment> <React.Fragment>
<section className="card card--section"> <section className="card card--section">
@ -39,20 +39,18 @@ class UserVerify extends React.PureComponent {
</div> </div>
</section> </section>
<section className="card card--section"> <section className="card card--section">
<div className="card__title"> <div className="card__title">{__('1) Proof via Credit')}</div>
<h3>{__('1) Proof via Credit')}</h3> <p className="card__content">
</div>
<div className="card__content">
{`${__( {`${__(
'If you have a valid credit or debit card, you can use it to instantly prove your humanity.' 'If you have a valid credit or debit card, you can use it to instantly prove your humanity.'
)} ${__('There is no charge at all for this, now or in the future.')} `} )} ${__('There is no charge at all for this, now or in the future.')} `}
</div> </p>
<div className="card__actions"> <div className="card__actions">
{errorMessage && <p className="form-field__error">{errorMessage}</p>} {errorMessage && <p className="form-field__error">{errorMessage}</p>}
<CardVerify <CardVerify
label={__('Perform Card Verification')} label={__('Perform Card Verification')}
disabled={isPending} disabled={isPending}
token={this.onToken.bind(this)} token={this.onToken}
stripeKey={lbryio.getStripeToken()} stripeKey={lbryio.getStripeToken()}
/> />
</div> </div>
@ -60,6 +58,7 @@ class UserVerify extends React.PureComponent {
<div className="meta"> <div className="meta">
{__('A $1 authorization may temporarily appear with your provider.')}{' '} {__('A $1 authorization may temporarily appear with your provider.')}{' '}
<Button <Button
button="link"
href="https://lbry.io/faq/identity-requirements" href="https://lbry.io/faq/identity-requirements"
label={__('Read more about why we do this.')} label={__('Read more about why we do this.')}
/> />
@ -67,20 +66,18 @@ class UserVerify extends React.PureComponent {
</div> </div>
</section> </section>
<section className="card card--section"> <section className="card card--section">
<div className="card__title"> <div className="card__title">{__('2) Proof via Phone')}</div>
<h3>{__('2) Proof via Phone')}</h3> <p className="card__content">
</div>
<div className="card__content">
{`${__( {`${__(
'You will receive an SMS text message confirming that your phone number is correct.' 'You will receive an SMS text message confirming that your phone number is correct.'
)}`} )}`}
</div> </p>
<div className="card__actions"> <div className="card__actions">
<Button <Button
onClick={() => { onClick={() => {
verifyPhone(); verifyPhone();
}} }}
button="alt" button="primary"
icon={icons.PHONE} icon={icons.PHONE}
label={__('Submit Phone Number')} label={__('Submit Phone Number')}
/> />
@ -88,14 +85,12 @@ class UserVerify extends React.PureComponent {
<div className="card__content"> <div className="card__content">
<div className="meta"> <div className="meta">
{__('Standard messaging rates apply. Having trouble?')}{' '} {__('Standard messaging rates apply. Having trouble?')}{' '}
<Button href="https://lbry.io/faq/phone" label={__('Read more.')} /> <Button button="link" href="https://lbry.io/faq/phone" label={__('Read more.')} />
</div> </div>
</div> </div>
</section> </section>
<section className="card card--form"> <section className="card card--section">
<div className="card__title"> <div className="card__title">{__('3) Proof via Chat')}</div>
<h3>{__('3) Proof via Chat')}</h3>
</div>
<div className="card__content"> <div className="card__content">
<p> <p>
{__( {__(
@ -111,25 +106,25 @@ class UserVerify extends React.PureComponent {
<div className="card__actions"> <div className="card__actions">
<Button <Button
href="https://chat.lbry.io" href="https://chat.lbry.io"
button="alt" button="primary"
icon={icons.MESSAGE} icon={icons.MESSAGE}
label={__('Join LBRY Chat')} label={__('Join LBRY Chat')}
/> />
</div> </div>
</section> </section>
<section className="card card--section"> <section className="card card--section">
<div className="card__title"> <div className="card__title">{__('Or, Skip It Entirely')}</div>
<h5>{__('Or, Skip It Entirely')}</h5> <p className="card__content">
</div> {__(
<div className="card__content"> 'You can continue without this step, but you will not be eligible to earn rewards.'
<p className="meta"> )}
{__( </p>
'You can continue without this step, but you will not be eligible to earn rewards.'
)}
</p>
</div>
<div className="card__actions"> <div className="card__actions">
<Button onClick={() => navigate('/discover')} button="alt" label={__('Skip Rewards')} /> <Button
onClick={() => navigate('/discover')}
button="primary"
label={__('Skip Rewards')}
/>
</div> </div>
</section> </section>
</React.Fragment> </React.Fragment>
@ -138,4 +133,3 @@ class UserVerify extends React.PureComponent {
} }
export default UserVerify; export default UserVerify;
/* eslint-enable */

View file

@ -51,6 +51,7 @@ class WalletSend extends React.PureComponent<Props> {
postfix={__('LBC')} postfix={__('LBC')}
className="input--price-amount" className="input--price-amount"
min="0" min="0"
step="any"
onChange={handleChange} onChange={handleChange}
onBlur={handleBlur} onBlur={handleBlur}
value={values.amount} value={values.amount}

View file

@ -1,10 +1,8 @@
import React from 'react'; import React from 'react';
import { ipcRenderer } from 'electron';
import { Modal } from 'modal/modal'; import { Modal } from 'modal/modal';
import { Line } from 'rc-progress';
import Button from 'component/button'; import Button from 'component/button';
const { ipcRenderer } = require('electron');
class ModalAutoUpdateDownloaded extends React.PureComponent { class ModalAutoUpdateDownloaded extends React.PureComponent {
render() { render() {
const { closeModal, declineAutoUpdate } = this.props; const { closeModal, declineAutoUpdate } = this.props;
@ -32,6 +30,14 @@ class ModalAutoUpdateDownloaded extends React.PureComponent {
'A new version of LBRY has been released, downloaded, and is ready for you to use pending a restart.' 'A new version of LBRY has been released, downloaded, and is ready for you to use pending a restart.'
)} )}
</p> </p>
<p className="meta text-center">
{__('Want to know what has changed?')} See the{' '}
<Button
button="link"
label={__('release notes')}
href="https://github.com/lbryio/lbry-app/releases"
/>.
</p>
</section> </section>
</Modal> </Modal>
); );

View file

@ -21,24 +21,24 @@ const ModalCreditIntro = props => {
</p> </p>
{currentBalance <= 0 && ( {currentBalance <= 0 && (
<p> <p>
You currently have <CreditAmount amount={currentBalance} />, so the actions you can take You currently have <CreditAmount noStyle amount={currentBalance} />, so the actions you
are limited. can take are limited.
</p> </p>
)} )}
<p> <p>
There are a variety of ways to get credits, including more than{' '} There are a variety of ways to get credits, including more than{' '}
{totalRewardValue ? ( {totalRewardValue ? (
<CreditAmount amount={totalRewardRounded} /> <CreditAmount noStyle amount={totalRewardRounded} />
) : ( ) : (
<span className="credit-amount">{__('?? credits')}</span> <span className="credit-amount">{__('?? credits')}</span>
)}{' '} )}{' '}
{__(' in free rewards for participating in the LBRY beta.')} {__(' in free rewards for participating in the LBRY beta.')}
</p> </p>
<div className="modal__buttons"> <div className="card__actions card__actions--center">
<Button button="primary" onClick={addBalance} label={__('Get Credits')} /> <Button button="primary" onClick={addBalance} label={__('Get Credits')} />
<Button <Button
button="alt" button="link"
onClick={closeModal} onClick={closeModal}
label={currentBalance <= 0 ? __('Use Without LBC') : __('Meh, Not Now')} label={currentBalance <= 0 ? __('Use Without LBC') : __('Meh, Not Now')}
/> />

View file

@ -8,7 +8,7 @@ class ModalPhoneCollection extends React.PureComponent {
renderInner() { renderInner() {
const { closeModal, phone, user } = this.props; const { closeModal, phone, user } = this.props;
const cancelButton = <Button button="text" onClick={closeModal} label={__('Not Now')} />; const cancelButton = <Button button="link" onClick={closeModal} label={__('Not Now')} />;
if (!user.phone_number && !phone) { if (!user.phone_number && !phone) {
return <UserPhoneNew cancelButton={cancelButton} />; return <UserPhoneNew cancelButton={cancelButton} />;

View file

@ -15,10 +15,9 @@ import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
import { selectShowNsfw } from 'redux/selectors/settings'; import { selectShowNsfw } from 'redux/selectors/settings';
import { selectMediaPaused } from 'redux/selectors/media'; import { selectMediaPaused } from 'redux/selectors/media';
import { doOpenModal } from 'redux/actions/app'; import { doOpenModal } from 'redux/actions/app';
import FilePage from './view';
import { makeSelectCurrentParam } from 'redux/selectors/navigation';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { doPrepareEdit } from 'redux/actions/publish'; import { doPrepareEdit } from 'redux/actions/publish';
import FilePage from './view';
const select = (state, props) => ({ const select = (state, props) => ({
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
@ -40,7 +39,7 @@ const perform = dispatch => ({
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
checkSubscription: subscription => dispatch(doCheckSubscription(subscription)), checkSubscription: subscription => dispatch(doCheckSubscription(subscription)),
openModal: (modal, props) => dispatch(doOpenModal(modal, props)), openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
prepareEdit: publishData => dispatch(doPrepareEdit(publishData)), prepareEdit: (publishData, uri) => dispatch(doPrepareEdit(publishData, uri)),
}); });
export default connect(select, perform)(FilePage); export default connect(select, perform)(FilePage);

View file

@ -9,7 +9,6 @@ import FileDetails from 'component/fileDetails';
import FileActions from 'component/fileActions'; import FileActions from 'component/fileActions';
import UriIndicator from 'component/uriIndicator'; import UriIndicator from 'component/uriIndicator';
import Icon from 'component/common/icon'; import Icon from 'component/common/icon';
import WalletSendTip from 'component/walletSendTip';
import DateTime from 'component/dateTime'; import DateTime from 'component/dateTime';
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
import Button from 'component/button'; import Button from 'component/button';
@ -72,7 +71,7 @@ class FilePage extends React.Component<Props> {
} }
} }
checkSubscription(props) { checkSubscription = (props: Props) => {
if ( if (
props.subscriptions props.subscriptions
.map(subscription => subscription.channelName) .map(subscription => subscription.channelName)
@ -89,12 +88,11 @@ class FilePage extends React.Component<Props> {
), ),
}); });
} }
} };
render() { render() {
const { const {
claim, claim,
fileInfo,
metadata, metadata,
contentType, contentType,
uri, uri,
@ -109,10 +107,9 @@ class FilePage extends React.Component<Props> {
} = this.props; } = this.props;
// File info // File info
const title = metadata.title; const { title, thumbnail } = metadata;
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
const shouldObscureThumbnail = obscureNsfw && metadata.nsfw; const shouldObscureThumbnail = obscureNsfw && metadata.nsfw;
const thumbnail = metadata.thumbnail;
const { height, channel_name: channelName, value } = claim; const { height, channel_name: channelName, value } = claim;
const mediaType = lbry.getMediaType(contentType); const mediaType = lbry.getMediaType(contentType);
const isPlayable = const isPlayable =
@ -165,7 +162,7 @@ class FilePage extends React.Component<Props> {
icon={icons.EDIT} icon={icons.EDIT}
label={__('Edit')} label={__('Edit')}
onClick={() => { onClick={() => {
prepareEdit(claim); prepareEdit(claim, uri);
navigate('/publish'); navigate('/publish');
}} }}
/> />

View file

@ -151,10 +151,10 @@ class HelpPage extends React.PureComponent {
{user && user.primary_email ? ( {user && user.primary_email ? (
user.primary_email user.primary_email
) : ( ) : (
<span> <React.Fragment>
<span className="empty">{__('none')} </span> <span className="empty">{__('none')} </span>
(<Button onClick={() => doAuth()} label={__('set email')} />) <Button button="link" onClick={() => doAuth()} label={__('set email')} />
</span> </React.Fragment>
)} )}
</td> </td>
</tr> </tr>

View file

@ -1,15 +1,17 @@
import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doNavigate } from 'redux/actions/navigation'; import { doNavigate } from 'redux/actions/navigation';
import { doClaimRewardType } from 'redux/actions/rewards';
import { selectMyClaims, selectClaimsByUri } from 'redux/selectors/claims'; import { selectMyClaims, selectClaimsByUri } from 'redux/selectors/claims';
import { selectResolvingUris } from 'redux/selectors/content'; import { selectResolvingUris } from 'redux/selectors/content';
import { selectPublishFormValues } from 'redux/selectors/publish'; import { selectPublishFormValues } from 'redux/selectors/publish';
import { doResolveUri } from 'redux/actions/content'; import { doResolveUri } from 'redux/actions/content';
import { selectBalance } from 'redux/selectors/wallet'; import { selectBalance } from 'redux/selectors/wallet';
import { doClearPublish, doUpdatePublishForm, doPublish } from 'redux/actions/publish'; import {
doClearPublish,
doUpdatePublishForm,
doPublish,
doPrepareEdit,
} from 'redux/actions/publish';
import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info'; import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
import { doPrepareEdit } from 'redux/actions/publish';
import PublishPage from './view'; import PublishPage from './view';
const select = (state, props) => { const select = (state, props) => {
@ -50,7 +52,7 @@ const perform = dispatch => ({
resolveUri: uri => dispatch(doResolveUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)),
publish: params => dispatch(doPublish(params)), publish: params => dispatch(doPublish(params)),
navigate: path => dispatch(doNavigate(path)), navigate: path => dispatch(doNavigate(path)),
prepareEdit: claim => dispatch(doPrepareEdit(claim)), prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)),
}); });
export default connect(select, perform)(PublishPage); export default connect(select, perform)(PublishPage);

View file

@ -0,0 +1,4 @@
import { connect } from 'react-redux';
import ReportPage from './view';
export default connect(null, null)(ReportPage);

View file

@ -1,8 +1,9 @@
import React from 'react'; import React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import { FormRow } from 'component/common/form'; import { FormRow, FormField } from 'component/common/form';
import { doShowSnackBar } from 'redux/actions/app'; import { doShowSnackBar } from 'redux/actions/app';
import lbry from '../lbry.js'; import lbry from 'lbry';
import Page from 'component/page';
class ReportPage extends React.Component { class ReportPage extends React.Component {
constructor(props) { constructor(props) {
@ -14,8 +15,14 @@ class ReportPage extends React.Component {
}; };
} }
onMessageChange(event) {
this.setState({
message: event.target.value,
});
}
submitMessage() { submitMessage() {
const message = this.state.message; const { message } = this.state;
if (message) { if (message) {
this.setState({ this.setState({
submitting: true, submitting: true,
@ -37,58 +44,55 @@ class ReportPage extends React.Component {
} }
} }
onMessageChange(event) {
this.setState({
message: event.target.value,
});
}
render() { render() {
return ( return (
<main className="main--single-column"> <Page>
<section className="card"> <section className="card card--section">
<div className="card__content"> <div className="card__content">
<h3>{__('Report an Issue')}</h3> <div className="card__title">{__('Report an Issue')}</div>
<p> <p>
{__( {__(
'Please describe the problem you experienced and any information you think might be useful to us. Links to screenshots are great!' 'Please describe the problem you experienced and any information you think might be useful to us. Links to screenshots are great!'
)} )}
</p> </p>
<div className="form-row"> <FormRow>
<FormRow <FormField
type="textarea" type="textarea"
rows="10" rows="10"
name="message" name="message"
stretch
value={this.state.message} value={this.state.message}
onChange={event => { onChange={event => {
this.onMessageChange(event); this.onMessageChange(event);
}} }}
placeholder={__('Description of your issue')} placeholder={__('Description of your issue')}
/> />
</div> </FormRow>
<div className="form-row form-row-submit"> <div className="card__actions">
<button <Button
button="primary"
onClick={event => { onClick={event => {
this.submitMessage(event); this.submitMessage(event);
}} }}
className={`button-block button-primary ${this.state.submitting ? 'disabled' : ''}`} className={`button-block button-primary ${this.state.submitting ? 'disabled' : ''}`}
> >
{this.state.submitting ? __('Submitting...') : __('Submit Report')} {this.state.submitting ? __('Submitting...') : __('Submit Report')}
</button> </Button>
</div> </div>
</div> </div>
</section> </section>
<section className="card"> <section className="card card--section">
<div className="card__content"> <div className="card__title">{__('Developer?')}</div>
<h3>{__('Developer?')}</h3> <p>
{__('You can also')}{' '} {__('You can also')}{' '}
<Button <Button
button="link"
href="https://github.com/lbryio/lbry/issues" href="https://github.com/lbryio/lbry/issues"
label={__('submit an issue on GitHub')} label={__('submit an issue on GitHub')}
/>. />.
</div> </p>
</section> </section>
</main> </Page>
); );
} }
} }

View file

@ -1,3 +1,4 @@
// @flow
import React from 'react'; import React from 'react';
import BusyIndicator from 'component/common/busy-indicator'; import BusyIndicator from 'component/common/busy-indicator';
import RewardListClaimed from 'component/rewardListClaimed'; import RewardListClaimed from 'component/rewardListClaimed';
@ -6,7 +7,20 @@ import Button from 'component/button';
import Page from 'component/page'; import Page from 'component/page';
import classnames from 'classnames'; import classnames from 'classnames';
class RewardsPage extends React.PureComponent { type Props = {
doAuth: () => void,
navigate: string => void,
fetching: boolean,
rewards: Array<{ reward_type: boolean }>,
user: ?{
is_identity_verified: boolean,
},
daemonSettings: {
share_usage_data: boolean,
},
};
class RewardsPage extends React.PureComponent<Props> {
/* /*
Below is broken for users who have claimed all rewards. Below is broken for users who have claimed all rewards.
@ -74,6 +88,8 @@ class RewardsPage extends React.PureComponent {
</div> </div>
); );
} }
return null;
} }
renderUnclaimedRewards() { renderUnclaimedRewards() {
@ -115,7 +131,8 @@ class RewardsPage extends React.PureComponent {
} }
const isNotEligible = const isNotEligible =
!user.primary_email || !user.has_verified_email || !user.is_identity_verified; !user || !user.primary_email || !user.has_verified_email || !user.is_identity_verified;
return ( return (
<div <div
className={classnames('card__list--rewards', { className={classnames('card__list--rewards', {

View file

@ -15,7 +15,6 @@ import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH }; type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };
type PromiseAction = Promise<Action>; type PromiseAction = Promise<Action>;
type Dispatch = (action: Action | PromiseAction | Array<Action>) => any; type Dispatch = (action: Action | PromiseAction | Array<Action>) => any;
type ThunkAction = (dispatch: Dispatch) => any;
type GetState = () => {}; type GetState = () => {};
export const doClearPublish = () => (dispatch: Dispatch): Action => export const doClearPublish = () => (dispatch: Dispatch): Action =>
@ -29,7 +28,7 @@ export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) =>
data: { ...publishFormValue }, data: { ...publishFormValue },
}); });
export const doPrepareEdit = (claim: any) => (dispatch: Dispatch) => { export const doPrepareEdit = (claim: any, uri: string) => (dispatch: Dispatch) => {
const { name, amount, channel_name: channelName, value: { stream: { metadata } } } = claim; const { name, amount, channel_name: channelName, value: { stream: { metadata } } } = claim;
const { const {
author, author,
@ -63,12 +62,16 @@ export const doPrepareEdit = (claim: any) => (dispatch: Dispatch) => {
nsfw, nsfw,
thumbnail, thumbnail,
title, title,
uri,
}; };
dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
}; };
export const doPublish = (params: PublishParams): ThunkAction => { export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => {
const state = getState();
const myClaims = selectMyClaimsWithoutChannels(state);
const { const {
name, name,
bid, bid,
@ -87,6 +90,17 @@ export const doPublish = (params: PublishParams): ThunkAction => {
sources, sources,
} = params; } = params;
let isEdit;
const newPublishName = channel ? `${channel}/${name}` : name;
for (let i = 0; i < myClaims.length; i += 1) {
const { channel_name: claimChannelName, name: claimName } = myClaims[i];
const contentName = claimChannelName ? `${claimChannelName}/${claimName}` : claimName;
if (contentName === newPublishName) {
isEdit = true;
break;
}
}
const channelName = channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : channel; const channelName = channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : channel;
const fee = contentIsFree || !price.amount ? undefined : { ...price }; const fee = contentIsFree || !price.amount ? undefined : { ...price };
@ -120,24 +134,22 @@ export const doPublish = (params: PublishParams): ThunkAction => {
publishPayload.sources = sources; publishPayload.sources = sources;
} }
return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.PUBLISH_START });
dispatch({ type: ACTIONS.PUBLISH_START });
const success = () => { const success = () => {
dispatch({ dispatch({
type: ACTIONS.PUBLISH_SUCCESS, type: ACTIONS.PUBLISH_SUCCESS,
data: { pendingPublish: publishPayload }, data: { pendingPublish: { ...publishPayload, isEdit } },
}); });
dispatch(doOpenModal(MODALS.PUBLISH, { uri })); dispatch(doOpenModal(MODALS.PUBLISH, { uri }));
};
const failure = error => {
dispatch({ type: ACTIONS.PUBLISH_FAIL });
dispatch(doOpenModal(MODALS.ERROR, { error: error.message }));
};
return Lbry.publish(publishPayload).then(success, failure);
}; };
const failure = error => {
dispatch({ type: ACTIONS.PUBLISH_FAIL });
dispatch(doOpenModal(MODALS.ERROR, { error: error.message }));
};
return Lbry.publish(publishPayload).then(success, failure);
}; };
// Calls claim_list_mine until any pending publishes are confirmed // Calls claim_list_mine until any pending publishes are confirmed

View file

@ -178,7 +178,7 @@ export const selectSearchDownloadUris = query =>
if (channelName) { if (channelName) {
const claim = claimsById[claimId]; const claim = claimsById[claimId];
if (claim.value) { if (claim && claim.value) {
uriParams.claimId = claim.value.publisherSignature.certificateId; uriParams.claimId = claim.value.publisherSignature.certificateId;
} else { } else {
uriParams.claimId = claimId; uriParams.claimId = claimId;

View file

@ -10,7 +10,7 @@ export const selectPendingPublishes = createSelector(
export const selectPendingPublishesLessEdits = createSelector( export const selectPendingPublishesLessEdits = createSelector(
selectPendingPublishes, selectPendingPublishes,
pendingPublishes => pendingPublishes.filter(pendingPublish => !pendingPublish.sources) pendingPublishes => pendingPublishes.filter(pendingPublish => !pendingPublish.isEdit)
); );
export const selectPublishFormValues = createSelector(selectState, state => { export const selectPublishFormValues = createSelector(selectState, state => {

View file

@ -86,7 +86,6 @@ input {
&[type='file'] { &[type='file'] {
border-bottom: none; border-bottom: none;
} }
&.input-copyable { &.input-copyable {
flex: 1; flex: 1;
background: var(--input-copyable-bg); background: var(--input-copyable-bg);
@ -106,6 +105,14 @@ input {
} }
} }
textarea {
font-family: 'metropolis-medium';
border: 1px solid var(--color-divider);
font-size: 0.8em;
width: 100%;
padding: $spacing-vertical * 1/3;
}
input::placeholder { input::placeholder {
opacity: 0.5; opacity: 0.5;
} }
@ -338,3 +345,9 @@ p {
color: var(--color-meta-light); color: var(--color-meta-light);
font-style: italic; font-style: italic;
} }
.qr-code {
&.qr-code--right-padding {
padding-right: $spacing-vertical * 2/3;
}
}

View file

@ -19,6 +19,10 @@
align-items: center; align-items: center;
} }
&.form-row--stretch {
flex: 1;
}
.form-field.form-field--stretch { .form-field.form-field--stretch {
width: 100%; width: 100%;