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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
// @flow // @flow
import type { Transaction } from 'types/transaction';
import * as icons from 'constants/icons'; import * as icons from 'constants/icons';
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import * as React from 'react'; import * as React from 'react';
@ -8,17 +9,6 @@ import FileExporter from 'component/common/file-exporter';
import { TRANSACTIONS } from 'lbry-redux'; import { TRANSACTIONS } from 'lbry-redux';
import TransactionListItem from './internal/transaction-list-item'; 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 = { type Props = {
emptyMessage: ?string, emptyMessage: ?string,
slim?: boolean, slim?: boolean,

View file

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

View file

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

View file

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

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, FormField, Submit } from 'component/common/form'; import { Form, FormField, Submit, FormRow } from 'component/common/form';
class UserPhoneVerify extends React.PureComponent { class UserPhoneVerify extends React.PureComponent {
constructor(props) { constructor(props) {
@ -32,16 +32,23 @@ class UserPhoneVerify extends React.PureComponent {
render() { render() {
const { cancelButton, phoneErrorMessage, phone, countryCode } = this.props; const { cancelButton, phoneErrorMessage, phone, countryCode } = this.props;
return ( return (
<Form onSubmit={this.handleSubmit.bind(this)}> <React.Fragment>
<p> <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? ` `Please enter the verification code sent to +${countryCode}${phone}. Didn't receive it? `
)} )}
<Button button="link" onClick={this.reset.bind(this)} label="Go back." /> <Button button="link" onClick={this.reset.bind(this)} label="Go back." />
</p> </p>
</header>
<Form className="card__content" onSubmit={this.handleSubmit.bind(this)}>
<FormRow padded>
<FormField <FormField
type="text" type="text"
name="code" name="code"
placeholder="1234"
value={this.state.code} value={this.state.code}
onChange={event => { onChange={event => {
this.handleCodeChanged(event); this.handleCodeChanged(event);
@ -49,18 +56,20 @@ class UserPhoneVerify extends React.PureComponent {
label={__('Verification Code')} label={__('Verification Code')}
error={phoneErrorMessage} error={phoneErrorMessage}
/> />
{/* render help separately so it always shows */} </FormRow>
<div className="card__actions card__actions--center">
<div className="card__actions">
<Submit label={__('Verify')} /> <Submit label={__('Verify')} />
{cancelButton} {cancelButton}
</div> </div>
</Form>
<p className="help"> <p className="help">
{__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" />{' '} {__('Email')} <Button button="link" href="mailto:help@lbry.io" label="help@lbry.io" /> or
or join our <Button button="link" href="https://chat.lbry.io" label="chat" />{' '} 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>
</Form> </React.Fragment>
); );
} }
} }

View file

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

View file

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

View file

@ -67,9 +67,11 @@ export class Modal extends React.PureComponent<ModalProps> {
![null, undefined, ''].includes(overlayClassName) ? overlayClassName : 'modal-overlay' ![null, undefined, ''].includes(overlayClassName) ? overlayClassName : 'modal-overlay'
} }
> >
{title && (
<header className="card__header"> <header className="card__header">
<h2 className="card__title">{title}</h2> <h1 className="card__title">{title}</h1>
</header> </header>
)}
<div className="card__content">{children}</div> <div className="card__content">{children}</div>
{type === 'custom' ? null : ( // custom modals define their own buttons {type === 'custom' ? null : ( // custom modals define their own buttons
<div className="card__actions"> <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.' '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"> <p className="help">
{__('Want to know what has changed?')} See the{' '} {__('Want to know what has changed?')} See the{' '}
<Button <Button
button="link" button="link"

View file

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

View file

@ -26,7 +26,7 @@ class ModalSendTip extends React.PureComponent<Props> {
> >
<section className="card__content"> <section className="card__content">
<p>{__('Your file has been published to LBRY at the address')}</p> <p>{__('Your file has been published to LBRY at the address')}</p>
<p className="card__success-msg">{uri}</p> <blockquote>{uri}</blockquote>
<p> <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.' '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.')}{' '} {__('An updated version of LBRY is now available.')}{' '}
{__('Your version is out of date and may be unreliable or insecure.')} {__('Your version is out of date and may be unreliable or insecure.')}
</p> </p>
<p className="meta"> <p className="help">
{__('Want to know what has changed?')} See the{' '} {__('Want to know what has changed?')} See the{' '}
<Button <Button
button="link" button="link"

View file

@ -158,7 +158,8 @@ class FilePage extends React.Component<Props> {
} }
return ( return (
<Page forContent> <Page notContained className="main--file-page">
<div className="grid-area--content">
{showFile && <FileViewer className="content__embedded" uri={uri} mediaType={mediaType} />} {showFile && <FileViewer className="content__embedded" uri={uri} mediaType={mediaType} />}
{!showFile && {!showFile &&
(thumbnail ? ( (thumbnail ? (
@ -174,8 +175,9 @@ class FilePage extends React.Component<Props> {
</div> </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> <h1 className="media__title media__title--large">{title}</h1>
<div className="media__properties media__properties--large"> <div className="media__properties media__properties--large">
@ -237,8 +239,9 @@ class FilePage extends React.Component<Props> {
<FileDetails uri={uri} /> <FileDetails uri={uri} />
</div> </div>
</div> </div>
<div className="grid-area--related">
<RecommendedContent uri={uri} /> <RecommendedContent uri={uri} />
</div>
</Page> </Page>
); );
} }

View file

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

View file

@ -2,7 +2,7 @@
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import * as SETTINGS from 'constants/settings'; import * as SETTINGS from 'constants/settings';
import * as React from 'react'; 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 Button from 'component/button';
import Page from 'component/page'; import Page from 'component/page';
import FileSelector from 'component/common/file-selector'; import FileSelector from 'component/common/file-selector';
@ -287,6 +287,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
</header> </header>
<div className="card__content"> <div className="card__content">
<FormRow>
<FormField <FormField
type="checkbox" type="checkbox"
name="autoplay" name="autoplay"
@ -294,7 +295,9 @@ class SettingsPage extends React.PureComponent<Props, State> {
checked={autoplay} checked={autoplay}
postfix={__('Autoplay media files')} postfix={__('Autoplay media files')}
/> />
</FormRow>
<FormRow>
<FormField <FormField
type="checkbox" type="checkbox"
name="auto_download" name="auto_download"
@ -302,7 +305,9 @@ class SettingsPage extends React.PureComponent<Props, State> {
checked={autoDownload} checked={autoDownload}
postfix={__('Automatically download new content from your subscriptions')} postfix={__('Automatically download new content from your subscriptions')}
/> />
</FormRow>
<FormRow>
<FormField <FormField
type="checkbox" type="checkbox"
name="show_nsfw" name="show_nsfw"
@ -313,6 +318,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
'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. ' '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> </div>
</section> </section>
@ -359,6 +365,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
</header> </header>
<div className="card__content"> <div className="card__content">
<FormRow>
<FormField <FormField
name="theme_select" name="theme_select"
type="select" type="select"
@ -372,6 +379,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
</option> </option>
))} ))}
</FormField> </FormField>
</FormRow>
<FormField <FormField
type="checkbox" type="checkbox"
@ -423,7 +431,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
<div className="card__content"> <div className="card__content">
<Button <Button
button="primary" button="primary"
label={this.state.clearingCache ? __('Clearing') : __('Clear the cache')} label={this.state.clearingCache ? __('Clearing') : __('Clear Cache')}
icon={ICONS.ALERT} icon={ICONS.ALERT}
onClick={this.clearCache} onClick={this.clearCache}
disabled={this.state.clearingCache} disabled={this.state.clearingCache}

View file

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

View file

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

View file

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

View file

@ -93,7 +93,7 @@
position: relative; position: relative;
+ .card__content { + .card__content {
padding-top: var(--spacing-vertical-medium); margin-top: var(--spacing-vertical-medium);
} }
&:not(.card__header--flat) { &:not(.card__header--flat) {
@ -118,6 +118,18 @@
grid-gap: var(--spacing-vertical-medium); 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 // C A R D
// M E T A // M E T A
@ -167,12 +179,6 @@
bottom: -0.12rem; bottom: -0.12rem;
position: relative; position: relative;
} }
&.card-row__scrollhouse--sub-component {
.card:first-of-type {
margin-left: 0;
}
}
} }
// C A R D // C A R D
@ -181,21 +187,19 @@
.card__title { .card__title {
font-size: 2rem; font-size: 2rem;
font-weight: 600; font-weight: 600;
&:not(.card__title--flex) {
.btn {
bottom: -0.5rem;
float: right;
font-size: 1rem;
}
}
.btn {
position: relative;
}
} }
.card__title--flex { .card__title--flex {
@include between;
display: flex; 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; bottom: 0;
right: 0; right: 0;
align-items: center;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
display: flex; display: flex;
align-items: center;
justify-content: center; justify-content: center;
position: absolute; position: absolute;
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; 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) { &:not(.card__media--nsfw) {
background-color: #000; // solid black to blend nicely when the video starts (if it doesn't take the full width) 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 { &:hover {
cursor: pointer; cursor: pointer;
.btn--view,
.btn--play {
background-color: $lbry-green-3;
}
} }
} }
.content__embedded { .content__embedded {
@include thumbnail; @include thumbnail;
align-items: center; background-color: #000;
background-color: $lbry-black;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
margin-bottom: var(--spacing-vertical-large); margin-bottom: var(--spacing-vertical-large);
max-height: 60vh;
position: relative; position: relative;
width: 100%; width: 100%;
max-height: var(--file-max-width);
video { video {
width: 100%; width: 100%;
@ -79,6 +83,7 @@
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
padding: 0 var(--spacing-vertical-large); padding: 0 var(--spacing-vertical-large);
background-color: rgba($lbry-black, 0.7);
} }
.content__loading-text { .content__loading-text {

View file

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

View file

@ -1,8 +1,4 @@
.form-field { .form-field {
&:not(:last-of-type) {
margin-bottom: var(--spacing-vertical-small);
}
&.form-field--disabled { &.form-field--disabled {
opacity: 0.4; opacity: 0.4;
pointer-events: none; pointer-events: none;
@ -91,6 +87,12 @@
padding-left: var(--spacing-vertical-small); 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 { .form-field__select-wrapper {
position: relative; position: relative;
width: 20rem; width: 20rem;

View file

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

View file

@ -28,4 +28,8 @@
.item-list__item--selected { .item-list__item--selected {
background-color: $lbry-gray-1; 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); 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; display: flex;
font-size: 1.5rem; font-size: 1.5rem;
.media__actions .btn__content {
svg {
width: 1.5rem;
height: 100%;
}
}
.media__info { .media__info {
margin-left: var(--spacing-vertical-large); margin-left: var(--spacing-vertical-large);
width: calc(100% - 20rem); 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 // M E D I A
// S E A R C H R E S U L T // S E A R C H R E S U L T
@ -86,14 +90,6 @@
margin-bottom: var(--spacing-vertical-large); margin-bottom: var(--spacing-vertical-large);
} }
.media__actions .btn__content {
display: inline-flex;
.btn__label {
margin-left: var(--spacing-vertical-small);
}
}
.media__info { .media__info {
margin-left: var(--spacing-vertical-medium); margin-left: var(--spacing-vertical-medium);
width: calc(100% - 20rem); 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 // M E D I A
// A C T I O N S // A C T I O N S
@ -179,27 +185,6 @@
&:not(:last-child) { &:not(:last-child) {
margin-right: var(--spacing-vertical-large); 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 // C O N T E N T
.media__content--large { .media__content--large {
float: left;
padding-right: var(--spacing-vertical-large); padding-right: var(--spacing-vertical-large);
width: calc(100% - 30rem);
} }
// M E D I A // M E D I A
@ -316,7 +299,6 @@
.badge { .badge {
align-items: center; align-items: center;
position: relative; position: relative;
top: 0.15rem;
> *:not(:last-child) { > *:not(:last-child) {
margin-right: var(--spacing-vertical-small); margin-right: var(--spacing-vertical-small);
@ -326,7 +308,7 @@
&:not(:empty) { &:not(:empty) {
height: 2.55rem; height: 2.55rem;
margin-bottom: var(--spacing-vertical-small); margin-bottom: var(--spacing-vertical-small);
padding-top: var(--spacing-vertical-miniscule); padding-top: var(--spacing-vertical-small);
padding-left: var(--spacing-vertical-small); padding-left: var(--spacing-vertical-small);
} }
} }
@ -374,10 +356,14 @@
@include thumbnail; @include thumbnail;
&:not(.media__thumb--nsfw):not(.media__thumb--placeholder) { &:not(.media__thumb--nsfw):not(.media__thumb--placeholder) {
background-color: $lbry-black; background-color: $lbry-gray-2;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: cover; background-size: cover;
html[data-theme='dark'] & {
background-color: rgba($lbry-white, 0.1);
}
} }
} }
@ -450,7 +436,6 @@
} }
.media-card { .media-card {
cursor: pointer;
display: inline-block; display: inline-block;
margin-bottom: var(--spacing-vertical-large); margin-bottom: var(--spacing-vertical-large);
vertical-align: top; vertical-align: top;
@ -668,11 +653,12 @@
@media (min-width: 601px) { @media (min-width: 601px) {
width: calc((100% / 6) - 2.25rem); width: calc((100% / 6) - 2.25rem);
margin-left: var(--spacing-vertical-large); margin-left: var(--spacing-vertical-large);
}
&:last-of-type { &:last-of-type {
// For some reason margin doesn't work here. // We can't use margin or padding because overlfow: hidden ignores those
padding-right: var(--spacing-vertical-large); // 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 // May be needed for mobile design

View file

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

View file

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

View file

@ -33,23 +33,11 @@
} }
@mixin placeholder { @mixin placeholder {
animation-duration: 4s; animation: pulse 2s infinite ease-in-out;
animation-fill-mode: forwards; background-color: $lbry-gray-2;
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;
html[data-theme='dark'] & { html[data-theme='dark'] & {
background-image: linear-gradient( background-color: rgba($lbry-white, 0.1);
to right,
rgba($lbry-white, 0.1) 10%,
transparent 80%,
rgba($lbry-white, 0.1) 100%
);
} }
} }

View file

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