Merge pull request #2170 from lbryio/newnew-fixes

Moar fixes
This commit is contained in:
Sean Yesmunt 2019-01-09 17:06:41 -05:00 committed by GitHub
commit e185cdc1d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 432 additions and 411 deletions

View file

@ -23,6 +23,7 @@ class CreditAmount extends React.PureComponent<Props> {
showFullPrice: false,
showPlus: false,
showLBC: true,
badge: true,
};
render() {
@ -77,7 +78,7 @@ class CreditAmount extends React.PureComponent<Props> {
title={fullPrice}
className={classnames('badge', {
badge,
'badge--cost': (badge && !isFree) || amount > 0,
'badge--cost': badge && amount > 0,
'badge--free': badge && isFree,
'badge--large': large,
})}

View file

@ -63,7 +63,7 @@ class FileSelector extends React.PureComponent<Props> {
type === 'file' ? fileLabel || __('Choose File') : directoryLabel || __('Choose Directory');
return (
<FormRow verticallyCentered>
<FormRow>
<Button button="primary" onClick={() => this.handleButtonClick()} label={label} />
<input
webkitdirectory="true"

View file

@ -76,7 +76,7 @@ class FileCard extends React.PureComponent<Props> {
if ((!claim && !pending) || placeholder) {
return (
<li className="media-card media--placeholder small">
<li className="media-card media--placeholder">
<div className="media__thumb media__thumb--placeholder" />
<div className="media__title media__title--placeholder" />
<div className="media__channel media__channel--placeholder" />
@ -110,7 +110,7 @@ class FileCard extends React.PureComponent<Props> {
role="button"
onClick={!pending ? () => navigate('/show', { uri }) : () => {}}
className={classnames('media-card', {
'media--link': !pending,
'card--link': !pending,
'media--pending': pending,
})}
onContextMenu={handleContextMenu}

View file

@ -62,6 +62,10 @@ class FileTile extends React.PureComponent<Props> {
} = this.props;
const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id);
if (!isNew && !isSubscribed && !isRewardContent && !isDownloaded) {
return null;
}
return (
<div className={classnames('media__properties', { card__subtitle: size === 'large' })}>
<FilePrice hideFree uri={uri} />

View file

@ -66,9 +66,7 @@ class InviteList extends React.PureComponent<Props> {
</tbody>
</table>
)}
</div>
<div className="card__content">
<div className="help">
{__(
'The maximum number of invite rewards is currently limited. Invite reward can only be claimed if the invitee passes the humanness test.'

View file

@ -33,7 +33,7 @@ class FormInviteNew extends React.PureComponent {
return (
<Form onSubmit={this.handleSubmit}>
<FormRow stretch>
<FormRow padded>
<FormField
stretch
type="text"
@ -48,10 +48,8 @@ class FormInviteNew extends React.PureComponent {
/>
</FormRow>
<div className="card__content">
<div className="card__actions">
<Submit label="Invite" disabled={isPending} />
</div>
<div className="card__actions">
<Submit label="Invite" disabled={isPending} />
</div>
</Form>
);
@ -94,9 +92,7 @@ class InviteNew extends React.PureComponent {
isPending={isPending}
rewardAmount={rewardAmount}
/>
</div>
<div className="card__content">
<p className="help">
{__('Read our')}{' '}
<Button button="link" label={__('FAQ')} href="https://lbry.io/faq/referrals" />{' '}

View file

@ -12,8 +12,8 @@ type Props = {
noPadding: ?boolean,
extraPadding: ?boolean,
notContained: ?boolean, // No max-width, but keep the padding
forContent: ?boolean,
loading: ?boolean,
className: ?string,
};
type State = {
@ -79,17 +79,16 @@ class Page extends React.PureComponent<Props, State> {
extraPadding,
notContained,
loading,
forContent,
className,
} = this.props;
const { showLoader } = this.state;
return (
<main
className={classnames('main', {
'main--contained': !notContained && !noPadding && !extraPadding && !forContent,
className={classnames('main', className, {
'main--contained': !notContained && !noPadding && !extraPadding,
'main--no-padding': noPadding,
'main--extra-padding': extraPadding,
'main--for-content': forContent,
})}
>
{pageTitle && (

View file

@ -1,5 +1,5 @@
// @flow
import type { Transaction } from '../view';
import type { Transaction } from 'types/transaction';
import * as ICONS from 'constants/icons';
import React from 'react';
import ButtonTransaction from 'component/common/transaction-link';
@ -53,12 +53,12 @@ class TransactionListItem extends React.PureComponent<Props> {
return (
<tr>
<td>
<CreditAmount inheritStyle showPlus amount={amount} precision={8} />
<CreditAmount badge={false} showPlus amount={amount} precision={8} />
<br />
{fee !== 0 && (
<span className="table__item-label">
<CreditAmount inheritStyle fee amount={fee} precision={8} />
<CreditAmount badge={false} fee amount={fee} precision={8} />
</span>
)}
</td>
@ -67,16 +67,17 @@ class TransactionListItem extends React.PureComponent<Props> {
</td>
<td className="table__item--actionable">
{reward && <span>{reward.reward_title}</span>}
{name && claimId && (
<Button
constrict
button="link"
navigate="/show"
navigateParams={{ uri: buildURI({ claimName: name, claimId }) }}
>
{name}
</Button>
)}
{name &&
claimId && (
<Button
constrict
button="link"
navigate="/show"
navigateParams={{ uri: buildURI({ claimName: name, claimId }) }}
>
{name}
</Button>
)}
</td>
<td>

View file

@ -1,4 +1,5 @@
// @flow
import type { Transaction } from 'types/transaction';
import * as icons from 'constants/icons';
import * as MODALS from 'constants/modal_types';
import * as React from 'react';
@ -8,17 +9,6 @@ import FileExporter from 'component/common/file-exporter';
import { TRANSACTIONS } from 'lbry-redux';
import TransactionListItem from './internal/transaction-list-item';
export type Transaction = {
amount: number,
claim_id: string,
claim_name: string,
fee: number,
nout: number,
txid: string,
type: string,
date: Date,
};
type Props = {
emptyMessage: ?string,
slim?: boolean,

View file

@ -1,5 +1,5 @@
// @flow
import type { Transaction } from 'component/transactionList/view';
import type { Transaction } from 'types/transaction';
import * as icons from 'constants/icons';
import React, { Fragment } from 'react';
import BusyIndicator from 'component/common/busy-indicator';
@ -28,7 +28,7 @@ class TransactionListRecent extends React.PureComponent<Props> {
return (
<section className="card card--section">
<header className="card__header card__header--flat">
<h2 className="card__title">
<h2 className="card__title card__title--flex-between">
{__('Recent Transactions')}
<RefreshTransactionButton />
</h2>
@ -39,11 +39,12 @@ class TransactionListRecent extends React.PureComponent<Props> {
</p>
</header>
{fetchingTransactions && !hasTransactions && (
<div className="card__content">
<BusyIndicator message={__('Loading transactions')} />
</div>
)}
{fetchingTransactions &&
!hasTransactions && (
<div className="card__content">
<BusyIndicator message={__('Loading transactions')} />
</div>
)}
{hasTransactions && (
<Fragment>

View file

@ -41,7 +41,7 @@ class UserEmailNew extends React.PureComponent<Props, State> {
const { cancelButton, errorMessage, isPending } = this.props;
return (
<span>
<React.Fragment>
<p>
{__("We'll let you know about LBRY updates, security issues, and great new content.")}
</p>
@ -71,7 +71,7 @@ class UserEmailNew extends React.PureComponent<Props, State> {
{cancelButton}
</div>
</Form>
</span>
</React.Fragment>
);
}
}

View file

@ -1,6 +1,5 @@
// I'll come back to this
/* eslint-disable */
import React from 'react';
// @flow
import * as React from 'react';
import { Form, FormRow, FormField, Submit } from 'component/common/form';
const os = require('os').type();
@ -20,67 +19,86 @@ const countryCodes = require('country-data')
return 0;
});
class UserPhoneNew extends React.PureComponent {
constructor(props) {
type Props = {
addUserPhone: (string, string) => void,
cancelButton: React.Node,
phoneErrorMessage: ?string,
isPending: boolean,
};
type State = {
phone: string,
countryCode: string,
};
class UserPhoneNew extends React.PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
phone: '',
country_code: '+1',
countryCode: '+1',
};
this.formatPhone = this.formatPhone.bind(this);
(this: any).formatPhone = this.formatPhone.bind(this);
(this: any).handleSubmit = this.handleSubmit.bind(this);
(this: any).handleSelect = this.handleSelect.bind(this);
}
formatPhone(value) {
const { country_code } = this.state;
value = value.replace(/\D/g, '');
if (country_code === '+1') {
if (!value) {
formatPhone(value: string) {
const { countryCode } = this.state;
const formattedNumber = value.replace(/\D/g, '');
if (countryCode === '+1') {
if (!formattedNumber) {
return '';
} else if (value.length < 4) {
return value;
} else if (value.length < 7) {
return `(${value.substring(0, 3)}) ${value.substring(3)}`;
} else if (formattedNumber.length < 4) {
return formattedNumber;
} else if (formattedNumber.length < 7) {
return `(${formattedNumber.substring(0, 3)}) ${formattedNumber.substring(3)}`;
}
const fullNumber = `(${value.substring(0, 3)}) ${value.substring(3, 6)}-${value.substring(
const fullNumber = `(${formattedNumber.substring(0, 3)}) ${formattedNumber.substring(
3,
6
)}`;
)}-${formattedNumber.substring(6)}`;
return fullNumber.length <= 14 ? fullNumber : fullNumber.substring(0, 14);
}
return value;
return formattedNumber;
}
handleChanged(event) {
handleChanged(event: SyntheticInputEvent<*>) {
this.setState({
phone: this.formatPhone(event.target.value),
});
}
handleSelect(event) {
this.setState({ country_code: event.target.value });
handleSelect(event: SyntheticInputEvent<*>) {
this.setState({ countryCode: event.target.value });
}
handleSubmit() {
const { phone, country_code } = this.state;
this.props.addUserPhone(phone.replace(/\D/g, ''), country_code.substring(1));
const { phone, countryCode } = this.state;
this.props.addUserPhone(phone.replace(/\D/g, ''), countryCode.substring(1));
}
render() {
const { cancelButton, phoneErrorMessage, isPending } = this.props;
return (
<div>
<p>
{__(
'Enter your phone number and we will send you a verification code. We will not share your phone number with third parties.'
)}
</p>
<Form onSubmit={this.handleSubmit.bind(this)}>
<FormRow>
<FormField type="select" name="country-codes" onChange={this.handleSelect.bind(this)}>
{countryCodes.map((country, index) => (
<option key={index} value={country.countryCallingCode}>
<React.Fragment>
<header className="card__header">
<h2 className="card__title">{__('Enter The Verification Code')}</h2>
<p className="card__subtitle">
{__(
'Enter your phone number and we will send you a verification code. We will not share your phone number with third parties.'
)}
</p>
</header>
<Form onSubmit={this.handleSubmit}>
<FormRow padded>
<FormField type="select" name="country-codes" onChange={this.handleSelect}>
{countryCodes.map(country => (
<option key={country.countryCallingCode} value={country.countryCallingCode}>
{os === 'Darwin' ? country.emoji : `(${country.alpha2})`}{' '}
{country.countryCallingCode}
</option>
@ -88,7 +106,7 @@ class UserPhoneNew extends React.PureComponent {
</FormField>
<FormField
type="text"
placeholder={this.state.country_code === '+1' ? '(555) 555-5555' : '5555555555'}
placeholder={this.state.countryCode === '+1' ? '(555) 555-5555' : '5555555555'}
name="phone"
value={this.state.phone}
error={phoneErrorMessage}
@ -102,10 +120,9 @@ class UserPhoneNew extends React.PureComponent {
{cancelButton}
</div>
</Form>
</div>
</React.Fragment>
);
}
}
export default UserPhoneNew;
/* eslint-enable */

View file

@ -2,7 +2,7 @@
/* eslint-disable */
import React from 'react';
import Button from 'component/button';
import { Form, FormField, Submit } from 'component/common/form';
import { Form, FormField, Submit, FormRow } from 'component/common/form';
class UserPhoneVerify extends React.PureComponent {
constructor(props) {
@ -32,35 +32,44 @@ class UserPhoneVerify extends React.PureComponent {
render() {
const { cancelButton, phoneErrorMessage, phone, countryCode } = this.props;
return (
<Form onSubmit={this.handleSubmit.bind(this)}>
<p>
{__(
`Please enter the verification code sent to +${countryCode}${phone}. Didn't receive it? `
)}
<Button button="link" onClick={this.reset.bind(this)} label="Go back." />
</p>
<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="card__actions card__actions--center">
<Submit label={__('Verify')} />
{cancelButton}
</div>
<React.Fragment>
<header className="card__header">
<h2 className="card__title">{__('Enter The Verification Code')}</h2>
<p className="card__subtitle">
{' '}
{__(
`Please enter the verification code sent to +${countryCode}${phone}. Didn't receive it? `
)}
<Button button="link" onClick={this.reset.bind(this)} label="Go back." />
</p>
</header>
<Form className="card__content" onSubmit={this.handleSubmit.bind(this)}>
<FormRow padded>
<FormField
type="text"
name="code"
placeholder="1234"
value={this.state.code}
onChange={event => {
this.handleCodeChanged(event);
}}
label={__('Verification Code')}
error={phoneErrorMessage}
/>
</FormRow>
<div className="card__actions">
<Submit label={__('Verify')} />
{cancelButton}
</div>
</Form>
<p className="help">
{__('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" />{' '}
{__('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>
</Form>
</React.Fragment>
);
}
}

View file

@ -31,29 +31,25 @@ class UserVerify extends React.PureComponent<Props> {
<section className="card card--section">
<header className="card__header">
<h1 className="card__title">{__('Final Human Proof')}</h1>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
Finally, please complete <strong>one and only one</strong> of the options below.
</p>
</div>
</header>
</section>
<section className="card card--section">
<header className="card__header">
<h2 className="card__title">{__('1) Proof via Credit')}</h2>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
{`${__(
'If you have a valid credit or debit card, you can use it to instantly prove your humanity.'
)} ${__(
'LBRY does not store your credit card information. There is no charge at all for this, now or in the future.'
)} `}
</p>
</header>
<div className="card__content">
<div className="card__actions">
{errorMessage && <p className="form-field__error">{errorMessage}</p>}
<CardVerify
@ -63,10 +59,8 @@ class UserVerify extends React.PureComponent<Props> {
stripeKey={Lbryio.getStripeToken()}
/>
</div>
</div>
<div className="card__content">
<div className="meta">
<div className="help">
{__('A $1 authorization may temporarily appear with your provider.')}{' '}
<Button
button="link"
@ -80,15 +74,14 @@ class UserVerify extends React.PureComponent<Props> {
<section className="card card--section">
<header className="card__header">
<h2 className="card__title">{__('2) Proof via Phone')}</h2>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
{`${__(
'You will receive an SMS text message confirming that your phone number is correct.'
)}`}
</p>
</header>
<div className="card__content">
<div className="card__actions">
<Button
onClick={() => {
@ -99,10 +92,8 @@ class UserVerify extends React.PureComponent<Props> {
label={__('Submit Phone Number')}
/>
</div>
</div>
<div className="card__content">
<div className="meta">
<div className="help">
{__('Standard messaging rates apply. Having trouble?')}{' '}
<Button button="link" href="https://lbry.io/faq/phone" label={__('Read more.')} />
</div>
@ -112,21 +103,17 @@ class UserVerify extends React.PureComponent<Props> {
<section className="card card--section">
<header className="card__header">
<h2 className="card__title">{__('3) Proof via Chat')}</h2>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
{__(
'A moderator capable of approving you is typically available in the #verification channel of our chat room.'
)}
</p>
<p>
)}{' '}
{__(
'This process will likely involve providing proof of a stable and established online or real-life identity.'
)}
</p>
</header>
<div className="card__content">
<div className="card__actions">
<Button
href="https://chat.lbry.io"
@ -141,14 +128,14 @@ class UserVerify extends React.PureComponent<Props> {
<section className="card card--section">
<header className="card__header">
<h2 className="card__title">{__('Or, Skip It Entirely')}</h2>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
{__(
'You can continue without this step, but you will not be eligible to earn rewards.'
)}
</p>
</header>
<div className="card__content">
<div className="card__actions">
<Button
onClick={() => navigate('/discover')}

View file

@ -73,7 +73,7 @@ class WalletSend extends React.PureComponent<Props> {
}
/>
</FormRow>
<FormRow padded>
<FormRow>
<FormField
type="text"
name="address"

View file

@ -67,9 +67,11 @@ export class Modal extends React.PureComponent<ModalProps> {
![null, undefined, ''].includes(overlayClassName) ? overlayClassName : 'modal-overlay'
}
>
<header className="card__header">
<h2 className="card__title">{title}</h2>
</header>
{title && (
<header className="card__header">
<h1 className="card__title">{title}</h1>
</header>
)}
<div className="card__content">{children}</div>
{type === 'custom' ? null : ( // custom modals define their own buttons
<div className="card__actions">

View file

@ -50,7 +50,7 @@ class ModalAutoUpdateDownloaded extends React.PureComponent<Props, State> {
'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">
<p className="help">
{__('Want to know what has changed?')} See the{' '}
<Button
button="link"

View file

@ -36,8 +36,8 @@ class ModalPhoneCollection extends React.PureComponent<Props> {
}
return (
<Modal type="custom" isOpen contentLabel="Phone" title={__('Verify Your Phone')}>
<section className="card__content">{this.renderInner()}</section>
<Modal type="custom" isOpen contentLabel="Phone">
{this.renderInner()}
</Modal>
);
}

View file

@ -26,7 +26,7 @@ class ModalSendTip extends React.PureComponent<Props> {
>
<section className="card__content">
<p>{__('Your file has been published to LBRY at the address')}</p>
<p className="card__success-msg">{uri}</p>
<blockquote>{uri}</blockquote>
<p>
{__(
'The file will take a few minutes to appear for other LBRY users. Until then it will be listed as "pending" under your published files.'

View file

@ -28,7 +28,7 @@ class ModalUpgrade extends React.PureComponent<Props> {
{__('An updated version of LBRY is now available.')}{' '}
{__('Your version is out of date and may be unreliable or insecure.')}
</p>
<p className="meta">
<p className="help">
{__('Want to know what has changed?')} See the{' '}
<Button
button="link"

View file

@ -158,24 +158,26 @@ class FilePage extends React.Component<Props> {
}
return (
<Page forContent>
{showFile && <FileViewer className="content__embedded" uri={uri} mediaType={mediaType} />}
{!showFile &&
(thumbnail ? (
<Thumbnail shouldObscure={shouldObscureThumbnail} src={thumbnail} />
) : (
<div
className={classnames('content__empty', {
'content__empty--nsfw': shouldObscureThumbnail,
})}
>
<div className="card__media-text">
{__("Sorry, looks like we can't preview this file.")}
<Page notContained className="main--file-page">
<div className="grid-area--content">
{showFile && <FileViewer className="content__embedded" uri={uri} mediaType={mediaType} />}
{!showFile &&
(thumbnail ? (
<Thumbnail shouldObscure={shouldObscureThumbnail} src={thumbnail} />
) : (
<div
className={classnames('content__empty', {
'content__empty--nsfw': shouldObscureThumbnail,
})}
>
<div className="card__media-text">
{__("Sorry, looks like we can't preview this file.")}
</div>
</div>
</div>
))}
))}
</div>
<div className="media__content media__content--large">
<div className="grid-area--info media__content media__content--large">
<h1 className="media__title media__title--large">{title}</h1>
<div className="media__properties media__properties--large">
@ -237,8 +239,9 @@ class FilePage extends React.Component<Props> {
<FileDetails uri={uri} />
</div>
</div>
<RecommendedContent uri={uri} />
<div className="grid-area--related">
<RecommendedContent uri={uri} />
</div>
</Page>
);
}

View file

@ -49,7 +49,7 @@ class RewardsPage extends PureComponent<Props> {
);
}
return (
<div className="card__content">
<section className="card card--section">
<p>
{__(
'This account must undergo review before you can participate in the rewards program.'
@ -70,7 +70,7 @@ class RewardsPage extends PureComponent<Props> {
<p>
<Button onClick={() => navigate('/discover')} button="primary" label="Return Home" />
</p>
</div>
</section>
);
}
@ -100,17 +100,14 @@ class RewardsPage extends PureComponent<Props> {
<section className="card card--section">
<header className="card__header">
<h2 className="card__title">{__('Disabled')}</h2>
</header>
<div className="card__content">
<p>
<p className="card__subtitle">
{__(
'Rewards are currently disabled for your account. Turn on diagnostic data sharing, in'
)}{' '}
<Button button="link" onClick={() => navigate('/settings')} label="Settings" />
{__(', in order to re-enable them.')}
</p>
</div>
</header>
</section>
);
} else if (fetching) {
@ -121,16 +118,16 @@ class RewardsPage extends PureComponent<Props> {
);
} else if (user === null) {
return (
<div className="card__content">
<section className="card card--section">
<p>
{__('This application is unable to earn rewards due to an authentication failure.')}
</p>
</div>
</section>
);
} else if (!rewards || rewards.length <= 0) {
return (
<Fragment>
<div className="card--section">
<section className="card card--section">
<h2 className="card__title">{__('No Rewards Available')}</h2>
<p>
{claimed && claimed.length
@ -139,9 +136,9 @@ class RewardsPage extends PureComponent<Props> {
)
: __('There are no rewards available at this time, please check back later.')}
</p>
</div>
</section>
<div className="card__content card__list--rewards">{this.renderCustomRewardCode()}</div>
<div className="card__list--rewards">{this.renderCustomRewardCode()}</div>
</Fragment>
);
}
@ -155,9 +152,7 @@ class RewardsPage extends PureComponent<Props> {
'card--disabled': isNotEligible,
})}
>
{rewards.map(reward => (
<RewardTile key={reward.reward_type} reward={reward} />
))}
{rewards.map(reward => <RewardTile key={reward.reward_type} reward={reward} />)}
{this.renderCustomRewardCode()}
</div>
);

View file

@ -2,7 +2,7 @@
import * as ICONS from 'constants/icons';
import * as SETTINGS from 'constants/settings';
import * as React from 'react';
import { FormField, FormFieldPrice } from 'component/common/form';
import { FormField, FormFieldPrice, FormRow } from 'component/common/form';
import Button from 'component/button';
import Page from 'component/page';
import FileSelector from 'component/common/file-selector';
@ -287,32 +287,38 @@ class SettingsPage extends React.PureComponent<Props, State> {
</header>
<div className="card__content">
<FormField
type="checkbox"
name="autoplay"
onChange={this.onAutoplayChange}
checked={autoplay}
postfix={__('Autoplay media files')}
/>
<FormRow>
<FormField
type="checkbox"
name="autoplay"
onChange={this.onAutoplayChange}
checked={autoplay}
postfix={__('Autoplay media files')}
/>
</FormRow>
<FormField
type="checkbox"
name="auto_download"
onChange={this.onAutoDownloadChange}
checked={autoDownload}
postfix={__('Automatically download new content from your subscriptions')}
/>
<FormRow>
<FormField
type="checkbox"
name="auto_download"
onChange={this.onAutoDownloadChange}
checked={autoDownload}
postfix={__('Automatically download new content from your subscriptions')}
/>
</FormRow>
<FormField
type="checkbox"
name="show_nsfw"
onChange={this.onShowNsfwChange}
checked={showNsfw}
postfix={__('Show NSFW content')}
helper={__(
'NSFW content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '
)}
/>
<FormRow>
<FormField
type="checkbox"
name="show_nsfw"
onChange={this.onShowNsfwChange}
checked={showNsfw}
postfix={__('Show NSFW content')}
helper={__(
'NSFW content may include nudity, intense sexuality, profanity, or other adult content. By displaying NSFW content, you are affirming you are of legal age to view mature content in your country or jurisdiction. '
)}
/>
</FormRow>
</div>
</section>
@ -359,19 +365,21 @@ class SettingsPage extends React.PureComponent<Props, State> {
</header>
<div className="card__content">
<FormField
name="theme_select"
type="select"
onChange={this.onThemeChange}
value={currentTheme}
disabled={automaticDarkModeEnabled}
>
{themes.map(theme => (
<option key={theme} value={theme}>
{theme}
</option>
))}
</FormField>
<FormRow>
<FormField
name="theme_select"
type="select"
onChange={this.onThemeChange}
value={currentTheme}
disabled={automaticDarkModeEnabled}
>
{themes.map(theme => (
<option key={theme} value={theme}>
{theme}
</option>
))}
</FormField>
</FormRow>
<FormField
type="checkbox"
@ -423,7 +431,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
<div className="card__content">
<Button
button="primary"
label={this.state.clearingCache ? __('Clearing') : __('Clear the cache')}
label={this.state.clearingCache ? __('Clearing') : __('Clear Cache')}
icon={ICONS.ALERT}
onClick={this.clearCache}
disabled={this.state.clearingCache}

View file

@ -12,6 +12,7 @@ import { parseURI } from 'lbry-redux';
import Native from 'native';
import SuggestedSubscriptions from 'component/subscribeSuggested';
import MarkAsRead from 'component/subscribeMarkAsRead';
import Tooltip from 'component/common/tooltip';
type Props = {
viewMode: ViewMode,
@ -45,29 +46,33 @@ export default (props: Props) => {
/>
{hasSubscriptions && (
<div className="card--space-between">
<div className="card__actions card__actions--no-margin">
<Button
disabled={viewMode === VIEW_ALL}
button="link"
label="All Subscriptions"
onClick={() => doSetViewMode(VIEW_ALL)}
/>
<Button
button="link"
disabled={viewMode === VIEW_LATEST_FIRST}
label={__('Latest Only')}
onClick={() => doSetViewMode(VIEW_LATEST_FIRST)}
/>
<section className="card card--section">
<div className="card__content card--space-between">
<div className="card__actions card__actions--no-margin">
<Button
disabled={viewMode === VIEW_ALL}
button="link"
label="All Subscriptions"
onClick={() => doSetViewMode(VIEW_ALL)}
/>
<Button
button="link"
disabled={viewMode === VIEW_LATEST_FIRST}
label={__('Latest Only')}
onClick={() => doSetViewMode(VIEW_LATEST_FIRST)}
/>
</div>
<Tooltip onComponent body={__('Automatically download new subscriptions.')}>
<FormField
type="checkbox"
name="auto_download"
onChange={onChangeAutoDownload}
checked={autoDownload}
prefix={__('Auto download')}
/>
</Tooltip>
</div>
<FormField
type="checkbox"
name="auto_download"
onChange={onChangeAutoDownload}
checked={autoDownload}
prefix={__('Auto download')}
/>
</div>
</section>
)}
{!hasSubscriptions && (
@ -91,7 +96,7 @@ export default (props: Props) => {
<div className="card__content">
{viewMode === VIEW_ALL && (
<Fragment>
<div className="card__title card__actions card__actions--no-margin">
<div className="card__title card__title--flex">
{__('Your subscriptions')}
{unreadSubscriptions.length > 0 && <MarkAsRead />}
</div>
@ -118,9 +123,7 @@ export default (props: Props) => {
<section className="media-group--list" key={channel}>
<ul className="card__list">
{uris.map(uri => (
<FileCard key={uri} uri={uri} />
))}
{uris.map(uri => <FileCard key={uri} uri={uri} />)}
</ul>
</section>
</span>

View file

@ -27,7 +27,7 @@ class TransactionHistoryPage extends React.PureComponent<Props> {
<Page>
<section className="card card--section">
<header className="card__header card__header--flat">
<h2 className="card__title">
<h2 className="card__title card__title--flex-between ">
{__('Transaction History')}
<RefreshTransactionButton />
</h2>

View file

@ -1,9 +1,21 @@
.btn {
fill: currentColor;
position: relative;
& svg {
stroke-width: 1;
svg {
stroke-width: 2;
width: 1.2rem;
height: 1.2rem;
position: relative;
top: 0.2rem;
}
.btn__label {
margin: 0;
}
svg + .btn__label {
margin-left: var(--spacing-vertical-small);
}
}
@ -47,6 +59,7 @@
text-align: left;
}
// Large icons used for play/view on the file page
.btn--icon {
width: 5rem;
height: 5rem;
@ -61,20 +74,23 @@
background-color: rgba($lbry-black, 0.7);
}
&:hover {
background-color: $lbry-green-3;
}
&.btn--play {
// The play icon looks a little weird without this
.btn--play {
padding-left: 0.25rem;
}
&.btn--view {
}
.btn__label {
display: none;
}
svg {
width: 3rem;
height: 3rem;
margin-right: 0;
position: relative;
top: 0.1rem;
}
}
.btn--inverse {
@ -95,42 +111,18 @@
&:hover {
background-color: $lbry-gray-1;
color: $lbry-black;
html[data-theme='dark'] & {
background-color: rgba($lbry-white, 0.1);
}
}
// TODO: Refactor to remove need for `!important`
.btn__label {
margin: 0 !important;
.btn__content {
svg {
color: $lbry-gray-4;
}
}
svg {
width: 1rem !important;
height: 1rem !important;
margin-right: var(--spacing-vertical-small);
position: relative;
top: 0.1rem;
}
// .btn__content {
// display: flex;
// svg {
// width: 1rem;
// height: 1rem;
// color: $lbry-gray-4;
// margin-right: var(--spacing-vertical-small);
// }
// .btn__label {
// line-height: 1rem;
// }
// }
}
.btn--load-screen {
@ -161,21 +153,6 @@
background-color: $lbry-teal-4;
}
}
// TODO: Refactor to remove need for `!important`
.btn__label {
margin: 0 !important;
}
svg {
width: 1rem !important;
height: 1rem !important;
margin-right: var(--spacing-vertical-small);
position: relative;
top: 0.1rem;
}
}
.btn--uppercase {

View file

@ -93,7 +93,7 @@
position: relative;
+ .card__content {
padding-top: var(--spacing-vertical-medium);
margin-top: var(--spacing-vertical-medium);
}
&:not(.card__header--flat) {
@ -118,6 +118,18 @@
grid-gap: var(--spacing-vertical-medium);
}
.card__list--rewards {
column-count: 2;
column-gap: var(--spacing-vertical-medium);
margin-bottom: var(--spacing-vertical-large);
.card {
display: inline-block;
margin: 0 0 var(--spacing-vertical-medium);
width: 100%;
}
}
// C A R D
// M E T A
@ -167,12 +179,6 @@
bottom: -0.12rem;
position: relative;
}
&.card-row__scrollhouse--sub-component {
.card:first-of-type {
margin-left: 0;
}
}
}
// C A R D
@ -181,21 +187,19 @@
.card__title {
font-size: 2rem;
font-weight: 600;
&:not(.card__title--flex) {
.btn {
bottom: -0.5rem;
float: right;
font-size: 1rem;
}
}
.btn {
position: relative;
}
}
.card__title--flex {
@include between;
display: flex;
align-items: center;
.btn:not(:first-of-type) {
margin-left: var(--spacing-vertical-medium);
}
}
.card__title--flex-between {
display: flex;
@include between;
align-items: center;
}

View file

@ -12,16 +12,15 @@
bottom: 0;
right: 0;
align-items: center;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: contain;
background-size: cover;
max-width: calc(var(--file-max-width) * (16 / 9));
margin: auto;
&:not(.card__media--nsfw) {
background-color: #000; // solid black to blend nicely when the video starts (if it doesn't take the full width)
@ -29,19 +28,24 @@
&:hover {
cursor: pointer;
.btn--view,
.btn--play {
background-color: $lbry-green-3;
}
}
}
.content__embedded {
@include thumbnail;
align-items: center;
background-color: $lbry-black;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: var(--spacing-vertical-large);
max-height: 60vh;
position: relative;
width: 100%;
max-height: var(--file-max-width);
video {
width: 100%;
@ -79,6 +83,7 @@
flex-direction: column;
justify-content: center;
padding: 0 var(--spacing-vertical-large);
background-color: rgba($lbry-black, 0.7);
}
.content__loading-text {

View file

@ -24,9 +24,10 @@
&::after {
width: 100%;
height: 100%;
height: 40%;
bottom: 0;
left: 0;
pointer-events: none;
background-image: linear-gradient(
to bottom,

View file

@ -1,8 +1,4 @@
.form-field {
&:not(:last-of-type) {
margin-bottom: var(--spacing-vertical-small);
}
&.form-field--disabled {
opacity: 0.4;
pointer-events: none;
@ -91,6 +87,12 @@
padding-left: var(--spacing-vertical-small);
}
// Keeps radio buttons aligned with the labels
// This can probably be done in a better way, but after setting align-items: center on the parent, the label is still off a bit.
input[type='radio'] + .form-field__postfix {
padding-top: 3px;
}
.form-field__select-wrapper {
position: relative;
width: 20rem;

View file

@ -1,9 +1,10 @@
.form-row {
display: flex;
flex-direction: row;
align-items: flex-end;
&:not(&--vertically-centered) {
align-items: flex-end;
&:not(.form-row--padded):not(:last-of-type) {
margin-bottom: var(--spacing-vertical-medium);
}
.form-field {
@ -32,8 +33,9 @@
}
.form-row--padded {
padding-top: var(--spacing-vertical-medium);
padding-bottom: var(--spacing-vertical-medium);
// Ignore the class name, margin allows these to collapse with other items
margin-top: var(--spacing-vertical-large);
margin-bottom: var(--spacing-vertical-large);
}
.form-row--right {

View file

@ -28,4 +28,8 @@
.item-list__item--selected {
background-color: $lbry-gray-1;
html[data-theme='dark'] & {
background-color: rgba($lbry-black, 0.5);
}
}

View file

@ -12,3 +12,29 @@
padding: var(--spacing-vertical-large);
}
}
.main--file-page {
display: grid;
grid-template-areas:
'content content'
'info related'
'info related';
@media (min-width: 1470px) {
grid-template-areas:
'content related'
'info related'
'info related';
grid-template-rows: 0fr 1fr;
}
.grid-area--content {
grid-area: content;
}
.grid-area--info {
grid-area: info;
}
.grid-area--related {
grid-area: related;
}
}

View file

@ -5,13 +5,6 @@
display: flex;
font-size: 1.5rem;
.media__actions .btn__content {
svg {
width: 1.5rem;
height: 100%;
}
}
.media__info {
margin-left: var(--spacing-vertical-large);
width: calc(100% - 20rem);
@ -76,6 +69,17 @@
}
}
// M E D I A
// P E N D I N G
.media--pending {
opacity: 0.5;
&:hover {
cursor: default;
}
}
// M E D I A
// S E A R C H R E S U L T
@ -86,14 +90,6 @@
margin-bottom: var(--spacing-vertical-large);
}
.media__actions .btn__content {
display: inline-flex;
.btn__label {
margin-left: var(--spacing-vertical-small);
}
}
.media__info {
margin-left: var(--spacing-vertical-medium);
width: calc(100% - 20rem);
@ -150,6 +146,16 @@
}
}
.media--search-result,
.media--small {
.media__properties {
padding: 0 var(--spacing-vertical-small);
border-radius: 5px;
background-color: $lbry-white;
color: $lbry-black;
}
}
// M E D I A
// A C T I O N S
@ -179,27 +185,6 @@
&:not(:last-child) {
margin-right: var(--spacing-vertical-large);
}
.btn__content {
display: inline-flex;
}
.btn__label {
margin-left: var(--spacing-vertical-small);
}
svg {
width: 1.5rem;
height: 1.5rem;
}
}
.btn--alt {
padding-top: 2px;
.btn__label {
padding-top: 1px;
}
}
}
@ -214,9 +199,7 @@
// C O N T E N T
.media__content--large {
float: left;
padding-right: var(--spacing-vertical-large);
width: calc(100% - 30rem);
}
// M E D I A
@ -316,7 +299,6 @@
.badge {
align-items: center;
position: relative;
top: 0.15rem;
> *:not(:last-child) {
margin-right: var(--spacing-vertical-small);
@ -326,7 +308,7 @@
&:not(:empty) {
height: 2.55rem;
margin-bottom: var(--spacing-vertical-small);
padding-top: var(--spacing-vertical-miniscule);
padding-top: var(--spacing-vertical-small);
padding-left: var(--spacing-vertical-small);
}
}
@ -374,10 +356,14 @@
@include thumbnail;
&:not(.media__thumb--nsfw):not(.media__thumb--placeholder) {
background-color: $lbry-black;
background-color: $lbry-gray-2;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
html[data-theme='dark'] & {
background-color: rgba($lbry-white, 0.1);
}
}
}
@ -450,7 +436,6 @@
}
.media-card {
cursor: pointer;
display: inline-block;
margin-bottom: var(--spacing-vertical-large);
vertical-align: top;
@ -668,11 +653,12 @@
@media (min-width: 601px) {
width: calc((100% / 6) - 2.25rem);
margin-left: var(--spacing-vertical-large);
}
&:last-of-type {
// For some reason margin doesn't work here.
padding-right: var(--spacing-vertical-large);
}
&:last-of-type {
// We can't use margin or padding because overlfow: hidden ignores those
// border-right ensures the last item in the scrollable list has some space to the right
border-right: var(--spacing-vertical-large) solid transparent;
}
// May be needed for mobile design

View file

@ -14,6 +14,10 @@
border-radius: 50%;
text-align: center;
&:not(.pagination__item--selected):hover {
color: $lbry-black;
}
&:not(.pagination__item--selected):not(.pagination__item--break):not(.disabled):hover {
background-color: $lbry-gray-1;
}

View file

@ -109,8 +109,4 @@
td:nth-of-type(5) {
width: 15%;
}
.badge {
background-color: transparent !important;
}
}

View file

@ -33,23 +33,11 @@
}
@mixin placeholder {
animation-duration: 4s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: loading-animation;
animation-timing-function: linear;
background-color: transparent;
background-image: linear-gradient(to right, $lbry-gray-3 10%, transparent 80%, $lbry-gray-3 100%);
background-repeat: repeat;
background-size: 500px;
animation: pulse 2s infinite ease-in-out;
background-color: $lbry-gray-2;
html[data-theme='dark'] & {
background-image: linear-gradient(
to right,
rgba($lbry-white, 0.1) 10%,
transparent 80%,
rgba($lbry-white, 0.1) 100%
);
background-color: rgba($lbry-white, 0.1);
}
}

View file

@ -18,6 +18,7 @@ $large-breakpoint: 1921px;
--spacing-vertical-medium: calc(2rem / 2);
--spacing-vertical-large: 2rem;
--file-max-width: 700px;
--video-aspect-ratio: 56.25%; // 9 x 16
// Text

View file

@ -0,0 +1,11 @@
// @flow
export type Transaction = {
amount: number,
claim_id: string,
claim_name: string,
fee: number,
nout: number,
txid: string,
type: string,
date: Date,
};