[redesign] some more fixes #1288
30 changed files with 280 additions and 207 deletions
|
@ -23,7 +23,7 @@ export default class Address extends React.PureComponent<Props> {
|
|||
const { address, doShowSnackBar } = this.props;
|
||||
|
||||
return (
|
||||
<FormRow verticallyCentered padded>
|
||||
<FormRow verticallyCentered padded stretch>
|
||||
<input
|
||||
className="input-copyable form-field__input"
|
||||
readOnly
|
||||
|
|
|
@ -158,7 +158,7 @@ class CardVerify extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<Button
|
||||
button="alt"
|
||||
button="primary"
|
||||
label={this.props.label}
|
||||
icon={icons.LOCK}
|
||||
disabled={this.props.disabled || this.state.open || this.hasPendingClick}
|
||||
|
|
|
@ -36,6 +36,8 @@ export class FormField extends React.PureComponent<Props> {
|
|||
...inputProps
|
||||
} = this.props;
|
||||
|
||||
const errorMessage = typeof error === 'object' ? error.message : error;
|
||||
|
||||
let input;
|
||||
if (type) {
|
||||
if (type === 'select') {
|
||||
|
@ -54,6 +56,8 @@ export class FormField extends React.PureComponent<Props> {
|
|||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (type === 'textarea') {
|
||||
input = <textarea type={type} id={name} {...inputProps} />;
|
||||
} else {
|
||||
input = <input type={type} id={name} {...inputProps} />;
|
||||
}
|
||||
|
@ -65,13 +69,13 @@ export class FormField extends React.PureComponent<Props> {
|
|||
'form-field--stretch': stretch || type === 'markdown',
|
||||
})}
|
||||
>
|
||||
{(label || error) && (
|
||||
{(label || errorMessage) && (
|
||||
<label
|
||||
className={classnames('form-field__label', { 'form-field__error': error })}
|
||||
className={classnames('form-field__label', { 'form-field__error': errorMessage })}
|
||||
htmlFor={name}
|
||||
>
|
||||
{!error && label}
|
||||
{error}
|
||||
{!errorMessage && label}
|
||||
{errorMessage}
|
||||
</label>
|
||||
)}
|
||||
<div
|
||||
|
|
|
@ -8,6 +8,7 @@ type Props = {
|
|||
children: React.Node,
|
||||
padded?: boolean,
|
||||
verticallyCentered?: boolean,
|
||||
stretch?: boolean,
|
||||
};
|
||||
|
||||
export class FormRow extends React.PureComponent<Props> {
|
||||
|
@ -16,13 +17,14 @@ export class FormRow extends React.PureComponent<Props> {
|
|||
};
|
||||
|
||||
render() {
|
||||
const { centered, children, padded, verticallyCentered } = this.props;
|
||||
const { centered, children, padded, verticallyCentered, stretch } = this.props;
|
||||
return (
|
||||
<div
|
||||
className={classnames('form-row', {
|
||||
'form-row--centered': centered,
|
||||
'form-row--padded': padded,
|
||||
'form-row--vertically-centered': verticallyCentered,
|
||||
'form-row--stretch': stretch,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import QRCodeElement from 'qrcode.react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
value: string,
|
||||
paddingRight?: boolean,
|
||||
};
|
||||
|
||||
const QRCode = (props: Props) => {
|
||||
const { value } = props;
|
||||
class QRCode extends React.Component<Props> {
|
||||
static defaultProps = {
|
||||
paddingRight: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { value, paddingRight } = this.props;
|
||||
return (
|
||||
<div className="qr-code">
|
||||
<div
|
||||
className={classnames('qr-code', {
|
||||
'qr-code--right-padding': paddingRight,
|
||||
})}
|
||||
>
|
||||
<QRCodeElement value={value} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default QRCode;
|
||||
|
|
|
@ -7,7 +7,7 @@ type Props = {
|
|||
editingURI: ?string,
|
||||
isResolvingUri: boolean,
|
||||
winningBidForClaimUri: ?number,
|
||||
claimIsMine: ?boolean,
|
||||
myClaimForUri: ?{},
|
||||
onEditMyClaim: any => void,
|
||||
};
|
||||
|
||||
|
@ -18,7 +18,7 @@ class BidHelpText extends React.PureComponent<Props> {
|
|||
editingURI,
|
||||
isResolvingUri,
|
||||
winningBidForClaimUri,
|
||||
claimIsMine,
|
||||
myClaimForUri,
|
||||
onEditMyClaim,
|
||||
} = this.props;
|
||||
|
||||
|
@ -34,12 +34,12 @@ class BidHelpText extends React.PureComponent<Props> {
|
|||
return __('Checking the winning claim amount...');
|
||||
}
|
||||
|
||||
if (claimIsMine) {
|
||||
if (myClaimForUri) {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{__('You already have a claim at')}
|
||||
{` ${uri} `}
|
||||
<Button button="link" label="Edit it" onClick={onEditMyClaim} />
|
||||
<Button button="link" label="Edit it" onClick={() => onEditMyClaim(myClaimForUri, uri)} />
|
||||
<br />
|
||||
{__('Publishing will update your existing claim.')}
|
||||
</React.Fragment>
|
||||
|
|
|
@ -55,7 +55,7 @@ type Props = {
|
|||
clearPublish: () => void,
|
||||
resolveUri: string => void,
|
||||
scrollToTop: () => void,
|
||||
prepareEdit: ({}) => void,
|
||||
prepareEdit: ({}, uri) => void,
|
||||
};
|
||||
|
||||
class PublishForm extends React.PureComponent<Props> {
|
||||
|
@ -159,10 +159,10 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
updatePublishForm({ bid, bidError });
|
||||
}
|
||||
|
||||
editExistingClaim() {
|
||||
const { myClaimForUri, prepareEdit, scrollToTop } = this.props;
|
||||
editExistingClaim(myClaimForUri: ?{}, uri: string) {
|
||||
const { prepareEdit, scrollToTop } = this.props;
|
||||
if (myClaimForUri) {
|
||||
prepareEdit(myClaimForUri);
|
||||
prepareEdit(myClaimForUri, uri);
|
||||
scrollToTop();
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +300,8 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
const formDisabled = (!filePath && !editingURI) || publishing;
|
||||
const formValid = this.checkIsFormValid();
|
||||
|
||||
const isStillEditing = editingURI === uri;
|
||||
const simpleUri = uri && uri.split('#')[0];
|
||||
const isStillEditing = editingURI === simpleUri;
|
||||
let submitLabel;
|
||||
if (isStillEditing) {
|
||||
submitLabel = !publishing ? __('Edit') : __('Editing...');
|
||||
|
@ -446,11 +447,11 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
error={nameError}
|
||||
helper={
|
||||
<BidHelpText
|
||||
uri={uri}
|
||||
uri={simpleUri}
|
||||
editingURI={editingURI}
|
||||
isResolvingUri={isResolvingUri}
|
||||
winningBidForClaimUri={winningBidForClaimUri}
|
||||
claimIsMine={!!myClaimForUri}
|
||||
myClaimForUri={myClaimForUri}
|
||||
onEditMyClaim={this.editExistingClaim}
|
||||
/>
|
||||
}
|
||||
|
|
|
@ -1,14 +1,28 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Modal from 'modal/modal';
|
||||
import { Modal } from 'modal/modal';
|
||||
import Button from 'component/button';
|
||||
|
||||
const RewardLink = props => {
|
||||
const { reward, button, claimReward, clearError, errorMessage, label, isPending } = props;
|
||||
type Reward = {
|
||||
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 : (
|
||||
<div className="reward-link">
|
||||
<Button
|
||||
button="primary"
|
||||
button="link"
|
||||
disabled={isPending}
|
||||
label={isPending ? __('Claiming...') : label || `${__('Get')} ${reward.reward_amount} LBC`}
|
||||
onClick={() => {
|
||||
|
@ -16,6 +30,7 @@ const RewardLink = props => {
|
|||
}}
|
||||
/>
|
||||
{errorMessage ? (
|
||||
// TODO: This should be moved to redux
|
||||
<Modal
|
||||
isOpen
|
||||
contentLabel="Reward Claim Error"
|
||||
|
@ -32,4 +47,5 @@ const RewardLink = props => {
|
|||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RewardLink;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import React from 'react';
|
||||
import SettingsPage from 'page/settings';
|
||||
import HelpPage from 'page/help';
|
||||
import ReportPage from 'page/report.js';
|
||||
import ReportPage from 'page/report';
|
||||
import WalletPage from 'page/wallet';
|
||||
import GetCreditsPage from '../../page/getCredits';
|
||||
import GetCreditsPage from 'page/getCredits';
|
||||
import SendReceivePage from 'page/sendCredits';
|
||||
import ShowPage from 'page/show';
|
||||
import PublishPage from 'page/publish';
|
||||
|
|
|
@ -16,7 +16,6 @@ type Props = {
|
|||
shiftOrderId: ?string,
|
||||
originCoinDepositMax: ?number,
|
||||
clearShapeShift: Dispatch,
|
||||
doShowSnackBar: Dispatch,
|
||||
getActiveShift: Dispatch,
|
||||
shapeShiftRate: ?number,
|
||||
originCoinDepositMax: ?number,
|
||||
|
@ -25,8 +24,6 @@ type Props = {
|
|||
};
|
||||
|
||||
class ActiveShapeShift extends React.PureComponent<Props> {
|
||||
continousFetch: ?number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.continousFetch = undefined;
|
||||
|
@ -59,6 +56,8 @@ class ActiveShapeShift extends React.PureComponent<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
continousFetch: ?number;
|
||||
|
||||
render() {
|
||||
const {
|
||||
shiftCoinType,
|
||||
|
@ -68,7 +67,6 @@ class ActiveShapeShift extends React.PureComponent<Props> {
|
|||
shiftState,
|
||||
originCoinDepositMax,
|
||||
clearShapeShift,
|
||||
doShowSnackBar,
|
||||
shapeShiftRate,
|
||||
originCoinDepositFee,
|
||||
originCoinDepositMin,
|
||||
|
@ -95,8 +93,8 @@ class ActiveShapeShift extends React.PureComponent<Props> {
|
|||
|
||||
{shiftDepositAddress && (
|
||||
<FormRow verticallyCentered padded>
|
||||
<Address address={shiftDepositAddress} showCopyButton />
|
||||
<QRCode value={shiftDepositAddress} />
|
||||
<QRCode value={shiftDepositAddress} paddingRight />
|
||||
<Address address={shiftDepositAddress} showCopyButton padded />
|
||||
</FormRow>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,6 @@ type Props = {
|
|||
isSubmitting: boolean,
|
||||
shiftSupportedCoins: Array<string>,
|
||||
originCoin: string,
|
||||
updating: boolean,
|
||||
getCoinStats: Dispatch,
|
||||
originCoinDepositFee: number,
|
||||
originCoinDepositMin: string,
|
||||
|
@ -38,7 +37,6 @@ export default (props: Props) => {
|
|||
isSubmitting,
|
||||
shiftSupportedCoins,
|
||||
originCoin,
|
||||
updating,
|
||||
getCoinStats,
|
||||
originCoinDepositMax,
|
||||
originCoinDepositMin,
|
||||
|
@ -51,7 +49,7 @@ export default (props: Props) => {
|
|||
prefix={__('Exchange')}
|
||||
postfix={__('for LBC')}
|
||||
type="select"
|
||||
name="origin_coin"
|
||||
name="originCoin"
|
||||
onChange={e => {
|
||||
getCoinStats(e.target.value);
|
||||
handleChange(e);
|
||||
|
@ -76,7 +74,7 @@ export default (props: Props) => {
|
|||
label={__('Return address')}
|
||||
error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress}
|
||||
type="text"
|
||||
name="return_address"
|
||||
name="returnAddress"
|
||||
className="input--address"
|
||||
placeholder={getExampleAddress(originCoin)}
|
||||
onChange={handleChange}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// I'll come back to this
|
||||
/* eslint-disable */
|
||||
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 countryCodes = require('country-data')
|
||||
|
@ -77,37 +77,30 @@ class UserPhoneNew extends React.PureComponent {
|
|||
)}
|
||||
</p>
|
||||
<Form onSubmit={this.handleSubmit.bind(this)}>
|
||||
<div className="form-row-phone">
|
||||
<FormField
|
||||
onChange={this.handleSelect.bind(this)}
|
||||
render={() => (
|
||||
<select>
|
||||
<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>
|
||||
))}
|
||||
</select>
|
||||
)}
|
||||
/>
|
||||
</FormField>
|
||||
<FormField
|
||||
errorMessage={phoneErrorMessage}
|
||||
onChange={event => {
|
||||
this.handleChanged(event);
|
||||
}}
|
||||
render={() => (
|
||||
<input
|
||||
type="text"
|
||||
placeholder={this.state.country_code === '+1' ? '(555) 555-5555' : '5555555555'}
|
||||
name="phone"
|
||||
value={this.state.phone}
|
||||
error={phoneErrorMessage}
|
||||
onChange={event => {
|
||||
this.handleChanged(event);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</FormRow>
|
||||
<div className="card__actions card__actions--center">
|
||||
<Submit label="Submit" disabled={isPending} />
|
||||
{cancelButton}
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
import React from 'react';
|
||||
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 {
|
||||
constructor(props) {
|
||||
|
@ -37,31 +37,27 @@ class UserPhoneVerify extends React.PureComponent {
|
|||
{__(
|
||||
`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>
|
||||
<FormElement
|
||||
label={__('Verification Code')}
|
||||
errorMessage={phoneErrorMessage}
|
||||
render={() => (
|
||||
<input
|
||||
<FormField
|
||||
type="text"
|
||||
name="code"
|
||||
value={this.state.code}
|
||||
onChange={event => {
|
||||
this.handleCodeChanged(event);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
label={__('Verification Code')}
|
||||
error={phoneErrorMessage}
|
||||
/>
|
||||
{/* render help separately so it always shows */}
|
||||
<div className="form-field__helper">
|
||||
<div className="meta">
|
||||
<p>
|
||||
{__('Email')} <Button href="mailto:help@lbry.io" label="help@lbry.io" /> or join our{' '}
|
||||
<Button href="https://chat.lbry.io" label="chat" />{' '}
|
||||
{__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" />{' '}
|
||||
or join our <Button button="link" href="https://chat.lbry.io" label="chat" />{' '}
|
||||
{__('if you encounter any trouble with your code.')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="form-row-submit">
|
||||
<div className="card__actions card__actions--center">
|
||||
<Submit label={__('Verify')} />
|
||||
{cancelButton}
|
||||
</div>
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
/* eslint-disable */
|
||||
import React from 'react';
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import Button from 'component/button';
|
||||
import CardVerify from 'component/cardVerify';
|
||||
import lbryio from 'lbryio.js';
|
||||
import lbryio from 'lbryio';
|
||||
import * as icons from 'constants/icons';
|
||||
|
||||
class UserVerify extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
type Props = {
|
||||
errorMessage: ?string,
|
||||
isPending: boolean,
|
||||
navigate: string => void,
|
||||
verifyUserIdentity: string => void,
|
||||
verifyPhone: () => void,
|
||||
};
|
||||
|
||||
this.state = {
|
||||
code: '',
|
||||
};
|
||||
class UserVerify extends React.PureComponent<Props> {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
(this: any).onToken = this.onToken.bind(this);
|
||||
}
|
||||
|
||||
handleCodeChanged(event) {
|
||||
this.setState({
|
||||
code: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
onToken(data) {
|
||||
onToken(data: { id: string }) {
|
||||
this.props.verifyUserIdentity(data.id);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { errorMessage, isPending, navigate, verifyPhone, modal } = this.props;
|
||||
const { errorMessage, isPending, navigate, verifyPhone } = this.props;
|
||||
return (
|
||||
<React.Fragment>
|
||||
<section className="card card--section">
|
||||
|
@ -39,20 +39,18 @@ class UserVerify extends React.PureComponent {
|
|||
</div>
|
||||
</section>
|
||||
<section className="card card--section">
|
||||
<div className="card__title">
|
||||
<h3>{__('1) Proof via Credit')}</h3>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<div className="card__title">{__('1) Proof via Credit')}</div>
|
||||
<p className="card__content">
|
||||
{`${__(
|
||||
'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.')} `}
|
||||
</div>
|
||||
</p>
|
||||
<div className="card__actions">
|
||||
{errorMessage && <p className="form-field__error">{errorMessage}</p>}
|
||||
<CardVerify
|
||||
label={__('Perform Card Verification')}
|
||||
disabled={isPending}
|
||||
token={this.onToken.bind(this)}
|
||||
token={this.onToken}
|
||||
stripeKey={lbryio.getStripeToken()}
|
||||
/>
|
||||
</div>
|
||||
|
@ -60,6 +58,7 @@ class UserVerify extends React.PureComponent {
|
|||
<div className="meta">
|
||||
{__('A $1 authorization may temporarily appear with your provider.')}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
href="https://lbry.io/faq/identity-requirements"
|
||||
label={__('Read more about why we do this.')}
|
||||
/>
|
||||
|
@ -67,20 +66,18 @@ class UserVerify extends React.PureComponent {
|
|||
</div>
|
||||
</section>
|
||||
<section className="card card--section">
|
||||
<div className="card__title">
|
||||
<h3>{__('2) Proof via Phone')}</h3>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<div className="card__title">{__('2) Proof via Phone')}</div>
|
||||
<p className="card__content">
|
||||
{`${__(
|
||||
'You will receive an SMS text message confirming that your phone number is correct.'
|
||||
)}`}
|
||||
</div>
|
||||
</p>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
onClick={() => {
|
||||
verifyPhone();
|
||||
}}
|
||||
button="alt"
|
||||
button="primary"
|
||||
icon={icons.PHONE}
|
||||
label={__('Submit Phone Number')}
|
||||
/>
|
||||
|
@ -88,14 +85,12 @@ class UserVerify extends React.PureComponent {
|
|||
<div className="card__content">
|
||||
<div className="meta">
|
||||
{__('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>
|
||||
</section>
|
||||
<section className="card card--form">
|
||||
<div className="card__title">
|
||||
<h3>{__('3) Proof via Chat')}</h3>
|
||||
</div>
|
||||
<section className="card card--section">
|
||||
<div className="card__title">{__('3) Proof via Chat')}</div>
|
||||
<div className="card__content">
|
||||
<p>
|
||||
{__(
|
||||
|
@ -111,25 +106,25 @@ class UserVerify extends React.PureComponent {
|
|||
<div className="card__actions">
|
||||
<Button
|
||||
href="https://chat.lbry.io"
|
||||
button="alt"
|
||||
button="primary"
|
||||
icon={icons.MESSAGE}
|
||||
label={__('Join LBRY Chat')}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<section className="card card--section">
|
||||
<div className="card__title">
|
||||
<h5>{__('Or, Skip It Entirely')}</h5>
|
||||
</div>
|
||||
<div className="card__content">
|
||||
<p className="meta">
|
||||
<div className="card__title">{__('Or, Skip It Entirely')}</div>
|
||||
<p className="card__content">
|
||||
{__(
|
||||
'You can continue without this step, but you will not be eligible to earn rewards.'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<Button onClick={() => navigate('/discover')} button="alt" label={__('Skip Rewards')} />
|
||||
<Button
|
||||
onClick={() => navigate('/discover')}
|
||||
button="primary"
|
||||
label={__('Skip Rewards')}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</React.Fragment>
|
||||
|
@ -138,4 +133,3 @@ class UserVerify extends React.PureComponent {
|
|||
}
|
||||
|
||||
export default UserVerify;
|
||||
/* eslint-enable */
|
||||
|
|
|
@ -51,6 +51,7 @@ class WalletSend extends React.PureComponent<Props> {
|
|||
postfix={__('LBC')}
|
||||
className="input--price-amount"
|
||||
min="0"
|
||||
step="any"
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.amount}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import React from 'react';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { Modal } from 'modal/modal';
|
||||
import { Line } from 'rc-progress';
|
||||
import Button from 'component/button';
|
||||
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
class ModalAutoUpdateDownloaded extends React.PureComponent {
|
||||
render() {
|
||||
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.'
|
||||
)}
|
||||
</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>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -21,24 +21,24 @@ const ModalCreditIntro = props => {
|
|||
</p>
|
||||
{currentBalance <= 0 && (
|
||||
<p>
|
||||
You currently have <CreditAmount amount={currentBalance} />, so the actions you can take
|
||||
are limited.
|
||||
You currently have <CreditAmount noStyle amount={currentBalance} />, so the actions you
|
||||
can take are limited.
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
There are a variety of ways to get credits, including more than{' '}
|
||||
{totalRewardValue ? (
|
||||
<CreditAmount amount={totalRewardRounded} />
|
||||
<CreditAmount noStyle amount={totalRewardRounded} />
|
||||
) : (
|
||||
<span className="credit-amount">{__('?? credits')}</span>
|
||||
)}{' '}
|
||||
{__(' in free rewards for participating in the LBRY beta.')}
|
||||
</p>
|
||||
|
||||
<div className="modal__buttons">
|
||||
<div className="card__actions card__actions--center">
|
||||
<Button button="primary" onClick={addBalance} label={__('Get Credits')} />
|
||||
<Button
|
||||
button="alt"
|
||||
button="link"
|
||||
onClick={closeModal}
|
||||
label={currentBalance <= 0 ? __('Use Without LBC') : __('Meh, Not Now')}
|
||||
/>
|
||||
|
|
|
@ -8,7 +8,7 @@ class ModalPhoneCollection extends React.PureComponent {
|
|||
renderInner() {
|
||||
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) {
|
||||
return <UserPhoneNew cancelButton={cancelButton} />;
|
||||
|
|
|
@ -15,10 +15,9 @@ import { makeSelectCostInfoForUri } from 'redux/selectors/cost_info';
|
|||
import { selectShowNsfw } from 'redux/selectors/settings';
|
||||
import { selectMediaPaused } from 'redux/selectors/media';
|
||||
import { doOpenModal } from 'redux/actions/app';
|
||||
import FilePage from './view';
|
||||
import { makeSelectCurrentParam } from 'redux/selectors/navigation';
|
||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||
import { doPrepareEdit } from 'redux/actions/publish';
|
||||
import FilePage from './view';
|
||||
|
||||
const select = (state, props) => ({
|
||||
claim: makeSelectClaimForUri(props.uri)(state),
|
||||
|
@ -40,7 +39,7 @@ const perform = dispatch => ({
|
|||
fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)),
|
||||
checkSubscription: subscription => dispatch(doCheckSubscription(subscription)),
|
||||
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);
|
||||
|
|
|
@ -9,7 +9,6 @@ import FileDetails from 'component/fileDetails';
|
|||
import FileActions from 'component/fileActions';
|
||||
import UriIndicator from 'component/uriIndicator';
|
||||
import Icon from 'component/common/icon';
|
||||
import WalletSendTip from 'component/walletSendTip';
|
||||
import DateTime from 'component/dateTime';
|
||||
import * as icons from 'constants/icons';
|
||||
import Button from 'component/button';
|
||||
|
@ -72,7 +71,7 @@ class FilePage extends React.Component<Props> {
|
|||
}
|
||||
}
|
||||
|
||||
checkSubscription(props) {
|
||||
checkSubscription = (props: Props) => {
|
||||
if (
|
||||
props.subscriptions
|
||||
.map(subscription => subscription.channelName)
|
||||
|
@ -89,12 +88,11 @@ class FilePage extends React.Component<Props> {
|
|||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
claim,
|
||||
fileInfo,
|
||||
metadata,
|
||||
contentType,
|
||||
uri,
|
||||
|
@ -109,10 +107,9 @@ class FilePage extends React.Component<Props> {
|
|||
} = this.props;
|
||||
|
||||
// File info
|
||||
const title = metadata.title;
|
||||
const { title, thumbnail } = metadata;
|
||||
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
|
||||
const shouldObscureThumbnail = obscureNsfw && metadata.nsfw;
|
||||
const thumbnail = metadata.thumbnail;
|
||||
const { height, channel_name: channelName, value } = claim;
|
||||
const mediaType = lbry.getMediaType(contentType);
|
||||
const isPlayable =
|
||||
|
@ -165,7 +162,7 @@ class FilePage extends React.Component<Props> {
|
|||
icon={icons.EDIT}
|
||||
label={__('Edit')}
|
||||
onClick={() => {
|
||||
prepareEdit(claim);
|
||||
prepareEdit(claim, uri);
|
||||
navigate('/publish');
|
||||
}}
|
||||
/>
|
||||
|
|
|
@ -151,10 +151,10 @@ class HelpPage extends React.PureComponent {
|
|||
{user && user.primary_email ? (
|
||||
user.primary_email
|
||||
) : (
|
||||
<span>
|
||||
<React.Fragment>
|
||||
<span className="empty">{__('none')} </span>
|
||||
(<Button onClick={() => doAuth()} label={__('set email')} />)
|
||||
</span>
|
||||
<Button button="link" onClick={() => doAuth()} label={__('set email')} />
|
||||
</React.Fragment>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { doNavigate } from 'redux/actions/navigation';
|
||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||
import { selectMyClaims, selectClaimsByUri } from 'redux/selectors/claims';
|
||||
import { selectResolvingUris } from 'redux/selectors/content';
|
||||
import { selectPublishFormValues } from 'redux/selectors/publish';
|
||||
import { doResolveUri } from 'redux/actions/content';
|
||||
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 { doPrepareEdit } from 'redux/actions/publish';
|
||||
import PublishPage from './view';
|
||||
|
||||
const select = (state, props) => {
|
||||
|
@ -50,7 +52,7 @@ const perform = dispatch => ({
|
|||
resolveUri: uri => dispatch(doResolveUri(uri)),
|
||||
publish: params => dispatch(doPublish(params)),
|
||||
navigate: path => dispatch(doNavigate(path)),
|
||||
prepareEdit: claim => dispatch(doPrepareEdit(claim)),
|
||||
prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(PublishPage);
|
||||
|
|
4
src/renderer/page/report/index.js
Normal file
4
src/renderer/page/report/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { connect } from 'react-redux';
|
||||
import ReportPage from './view';
|
||||
|
||||
export default connect(null, null)(ReportPage);
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react';
|
||||
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 lbry from '../lbry.js';
|
||||
import lbry from 'lbry';
|
||||
import Page from 'component/page';
|
||||
|
||||
class ReportPage extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -14,8 +15,14 @@ class ReportPage extends React.Component {
|
|||
};
|
||||
}
|
||||
|
||||
onMessageChange(event) {
|
||||
this.setState({
|
||||
message: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
submitMessage() {
|
||||
const message = this.state.message;
|
||||
const { message } = this.state;
|
||||
if (message) {
|
||||
this.setState({
|
||||
submitting: true,
|
||||
|
@ -37,58 +44,55 @@ class ReportPage extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
onMessageChange(event) {
|
||||
this.setState({
|
||||
message: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<main className="main--single-column">
|
||||
<section className="card">
|
||||
<Page>
|
||||
<section className="card card--section">
|
||||
<div className="card__content">
|
||||
<h3>{__('Report an Issue')}</h3>
|
||||
<div className="card__title">{__('Report an Issue')}</div>
|
||||
<p>
|
||||
{__(
|
||||
'Please describe the problem you experienced and any information you think might be useful to us. Links to screenshots are great!'
|
||||
)}
|
||||
</p>
|
||||
<div className="form-row">
|
||||
<FormRow
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="textarea"
|
||||
rows="10"
|
||||
name="message"
|
||||
stretch
|
||||
value={this.state.message}
|
||||
onChange={event => {
|
||||
this.onMessageChange(event);
|
||||
}}
|
||||
placeholder={__('Description of your issue')}
|
||||
/>
|
||||
</div>
|
||||
<div className="form-row form-row-submit">
|
||||
<button
|
||||
</FormRow>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
onClick={event => {
|
||||
this.submitMessage(event);
|
||||
}}
|
||||
className={`button-block button-primary ${this.state.submitting ? 'disabled' : ''}`}
|
||||
>
|
||||
{this.state.submitting ? __('Submitting...') : __('Submit Report')}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section className="card">
|
||||
<div className="card__content">
|
||||
<h3>{__('Developer?')}</h3>
|
||||
<section className="card card--section">
|
||||
<div className="card__title">{__('Developer?')}</div>
|
||||
<p>
|
||||
{__('You can also')}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
href="https://github.com/lbryio/lbry/issues"
|
||||
label={__('submit an issue on GitHub')}
|
||||
/>.
|
||||
</div>
|
||||
</p>
|
||||
</section>
|
||||
</main>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import BusyIndicator from 'component/common/busy-indicator';
|
||||
import RewardListClaimed from 'component/rewardListClaimed';
|
||||
|
@ -6,7 +7,20 @@ import Button from 'component/button';
|
|||
import Page from 'component/page';
|
||||
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.
|
||||
|
||||
|
@ -74,6 +88,8 @@ class RewardsPage extends React.PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
renderUnclaimedRewards() {
|
||||
|
@ -115,7 +131,8 @@ class RewardsPage extends React.PureComponent {
|
|||
}
|
||||
|
||||
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 (
|
||||
<div
|
||||
className={classnames('card__list--rewards', {
|
||||
|
|
|
@ -15,7 +15,6 @@ import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
|
|||
type Action = UpdatePublishFormAction | { type: ACTIONS.CLEAR_PUBLISH };
|
||||
type PromiseAction = Promise<Action>;
|
||||
type Dispatch = (action: Action | PromiseAction | Array<Action>) => any;
|
||||
type ThunkAction = (dispatch: Dispatch) => any;
|
||||
type GetState = () => {};
|
||||
|
||||
export const doClearPublish = () => (dispatch: Dispatch): Action =>
|
||||
|
@ -29,7 +28,7 @@ export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) =>
|
|||
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 {
|
||||
author,
|
||||
|
@ -63,12 +62,16 @@ export const doPrepareEdit = (claim: any) => (dispatch: Dispatch) => {
|
|||
nsfw,
|
||||
thumbnail,
|
||||
title,
|
||||
uri,
|
||||
};
|
||||
|
||||
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 {
|
||||
name,
|
||||
bid,
|
||||
|
@ -87,6 +90,17 @@ export const doPublish = (params: PublishParams): ThunkAction => {
|
|||
sources,
|
||||
} = 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 fee = contentIsFree || !price.amount ? undefined : { ...price };
|
||||
|
||||
|
@ -120,13 +134,12 @@ export const doPublish = (params: PublishParams): ThunkAction => {
|
|||
publishPayload.sources = sources;
|
||||
}
|
||||
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({ type: ACTIONS.PUBLISH_START });
|
||||
|
||||
const success = () => {
|
||||
dispatch({
|
||||
type: ACTIONS.PUBLISH_SUCCESS,
|
||||
data: { pendingPublish: publishPayload },
|
||||
data: { pendingPublish: { ...publishPayload, isEdit } },
|
||||
});
|
||||
dispatch(doOpenModal(MODALS.PUBLISH, { uri }));
|
||||
};
|
||||
|
@ -137,7 +150,6 @@ export const doPublish = (params: PublishParams): ThunkAction => {
|
|||
};
|
||||
|
||||
return Lbry.publish(publishPayload).then(success, failure);
|
||||
};
|
||||
};
|
||||
|
||||
// Calls claim_list_mine until any pending publishes are confirmed
|
||||
|
|
|
@ -178,7 +178,7 @@ export const selectSearchDownloadUris = query =>
|
|||
|
||||
if (channelName) {
|
||||
const claim = claimsById[claimId];
|
||||
if (claim.value) {
|
||||
if (claim && claim.value) {
|
||||
uriParams.claimId = claim.value.publisherSignature.certificateId;
|
||||
} else {
|
||||
uriParams.claimId = claimId;
|
||||
|
|
|
@ -10,7 +10,7 @@ export const selectPendingPublishes = createSelector(
|
|||
|
||||
export const selectPendingPublishesLessEdits = createSelector(
|
||||
selectPendingPublishes,
|
||||
pendingPublishes => pendingPublishes.filter(pendingPublish => !pendingPublish.sources)
|
||||
pendingPublishes => pendingPublishes.filter(pendingPublish => !pendingPublish.isEdit)
|
||||
);
|
||||
|
||||
export const selectPublishFormValues = createSelector(selectState, state => {
|
||||
|
|
|
@ -86,7 +86,6 @@ input {
|
|||
&[type='file'] {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.input-copyable {
|
||||
flex: 1;
|
||||
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 {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
@ -338,3 +345,9 @@ p {
|
|||
color: var(--color-meta-light);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
&.qr-code--right-padding {
|
||||
padding-right: $spacing-vertical * 2/3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
&.form-row--stretch {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-field.form-field--stretch {
|
||||
width: 100%;
|
||||
|
||||
|
|
Loading…
Reference in a new issue