use @lbry/components
This commit is contained in:
parent
f9a681a425
commit
4c76050460
79 changed files with 1117 additions and 1671 deletions
|
@ -89,8 +89,7 @@
|
|||
"y18n": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lbry/color": "^1.0.2",
|
||||
"@lbry/components": "^1.5.1",
|
||||
"@lbry/components": "^2.2.0",
|
||||
"babel-eslint": "^8.2.2",
|
||||
"babel-plugin-module-resolver": "^3.1.1",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
|
|
|
@ -41,7 +41,7 @@ class App extends React.PureComponent<Props> {
|
|||
});
|
||||
|
||||
// $FlowFixMe
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
document.documentElement.setAttribute('data-mode', theme);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -78,7 +78,7 @@ class App extends React.PureComponent<Props> {
|
|||
|
||||
if (prevTheme !== theme) {
|
||||
// $FlowFixMe
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
document.documentElement.setAttribute('data-mode', theme);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ type Props = {
|
|||
type: string,
|
||||
button: ?string, // primary, secondary, alt, link
|
||||
noPadding: ?boolean, // to remove padding and allow circular buttons
|
||||
uppercase: ?boolean,
|
||||
iconColor?: string,
|
||||
iconSize?: number,
|
||||
constrict: ?boolean, // to shorten the button and ellipsis, only use for links
|
||||
|
@ -51,7 +50,6 @@ class Button extends React.PureComponent<Props> {
|
|||
button,
|
||||
type,
|
||||
noPadding,
|
||||
uppercase,
|
||||
iconColor,
|
||||
iconSize,
|
||||
constrict,
|
||||
|
@ -60,25 +58,23 @@ class Button extends React.PureComponent<Props> {
|
|||
} = this.props;
|
||||
|
||||
const combinedClassName = classnames(
|
||||
'btn',
|
||||
'button',
|
||||
{
|
||||
'btn--no-padding': noPadding,
|
||||
'button--no-padding': noPadding,
|
||||
},
|
||||
button
|
||||
? {
|
||||
'btn--primary': button === 'primary',
|
||||
'btn--secondary': button === 'secondary',
|
||||
'btn--alt': button === 'alt',
|
||||
'btn--danger': button === 'danger',
|
||||
'btn--inverse': button === 'inverse',
|
||||
'btn--disabled': disabled,
|
||||
'btn--link': button === 'link',
|
||||
'btn--external-link': button === 'link' && href,
|
||||
'btn--uppercase': uppercase,
|
||||
'btn--constrict': constrict,
|
||||
'btn--selected': selected,
|
||||
'button--primary': button === 'primary',
|
||||
'button--secondary': button === 'secondary',
|
||||
'button--alt': button === 'alt',
|
||||
'button--danger': button === 'danger',
|
||||
'button--inverse': button === 'inverse',
|
||||
'button--disabled': disabled,
|
||||
'button--link': button === 'link',
|
||||
'button--constrict': constrict,
|
||||
'button--selected': selected,
|
||||
}
|
||||
: 'btn--no-style',
|
||||
: 'button--no-style',
|
||||
className
|
||||
);
|
||||
|
||||
|
@ -91,9 +87,9 @@ class Button extends React.PureComponent<Props> {
|
|||
: onClick;
|
||||
|
||||
const content = (
|
||||
<span className="btn__content">
|
||||
<span className="button__content">
|
||||
{icon && <Icon icon={icon} iconColor={iconColor} size={iconSize} />}
|
||||
{label && <span className="btn__label">{label}</span>}
|
||||
{label && <span className="button__label">{label}</span>}
|
||||
{children && children}
|
||||
{iconRight && <Icon icon={iconRight} iconColor={iconColor} size={iconSize} />}
|
||||
</span>
|
||||
|
|
|
@ -309,7 +309,7 @@ class CategoryList extends PureComponent<Props, State> {
|
|||
)}
|
||||
</header>
|
||||
{obscureNsfw && isCommunityTopBids ? (
|
||||
<p className="media__message media__message--help">
|
||||
<p className="media__message help--warning">
|
||||
{__(
|
||||
'The community top bids section is only visible if you allow mature content in the app. You can change your content viewing preferences'
|
||||
)}{' '}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import React from 'react';
|
||||
import { remote } from 'electron';
|
||||
import Button from 'component/button';
|
||||
import { FormRow } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import path from 'path';
|
||||
|
||||
type FileFilters = {
|
||||
|
@ -63,22 +63,22 @@ class FileSelector extends React.PureComponent<Props> {
|
|||
type === 'file' ? fileLabel || __('Choose File') : directoryLabel || __('Choose Directory');
|
||||
|
||||
return (
|
||||
<FormRow>
|
||||
<Button button="primary" onClick={() => this.handleButtonClick()} label={label} />
|
||||
<input
|
||||
webkitdirectory="true"
|
||||
className="input-copyable"
|
||||
type="text"
|
||||
ref={input => {
|
||||
if (this.input) this.input = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.input) this.input.select();
|
||||
}}
|
||||
readOnly="readonly"
|
||||
value={currentPath || __('No File Chosen')}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
webkitdirectory="true"
|
||||
className="form-field--copyable"
|
||||
type="text"
|
||||
ref={input => {
|
||||
if (this.input) this.input = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.input) this.input.select();
|
||||
}}
|
||||
readOnly="readonly"
|
||||
value={currentPath || __('No File Chosen')}
|
||||
inputButton={
|
||||
<Button button="primary" onClick={() => this.handleButtonClick()} label={label} />
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import * as React from 'react';
|
||||
import type { Price } from 'page/settings';
|
||||
import { FormField } from './form-field';
|
||||
import { FormRow } from './form-row';
|
||||
|
||||
type Props = {
|
||||
price: Price,
|
||||
|
@ -11,7 +10,6 @@ type Props = {
|
|||
min: number,
|
||||
disabled: boolean,
|
||||
name: string,
|
||||
label: string,
|
||||
step: ?number,
|
||||
};
|
||||
|
||||
|
@ -41,35 +39,40 @@ export class FormFieldPrice extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { price, placeholder, min, disabled, name, label, step } = this.props;
|
||||
const { price, placeholder, min, disabled, name, step } = this.props;
|
||||
|
||||
return (
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
name={`${name}_amount`}
|
||||
label={label}
|
||||
type="number"
|
||||
className="form-field input--price-amount"
|
||||
min={min}
|
||||
value={price.amount}
|
||||
onChange={this.handleAmountChange}
|
||||
placeholder={placeholder || 5}
|
||||
disabled={disabled}
|
||||
step={step || 'any'}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
name={`${name}_currency`}
|
||||
type="select"
|
||||
id={`${name}_currency`}
|
||||
disabled={disabled}
|
||||
onChange={this.handleCurrencyChange}
|
||||
value={price.currency}
|
||||
>
|
||||
<option value="LBC">{__('LBRY Credits (LBC)')}</option>
|
||||
<option value="USD">{__('US Dollars')}</option>
|
||||
</FormField>
|
||||
</FormRow>
|
||||
<fieldset-group class="fieldset-group--smushed">
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
name={`${name}_amount`}
|
||||
label={__('Price')}
|
||||
type="number"
|
||||
className="form-field--price-amount"
|
||||
min={min}
|
||||
value={price.amount}
|
||||
onChange={this.handleAmountChange}
|
||||
placeholder={placeholder || 5}
|
||||
disabled={disabled}
|
||||
step={step || 'any'}
|
||||
/>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
label={__('Currency')}
|
||||
name={`${name}_currency`}
|
||||
type="select"
|
||||
id={`${name}_currency`}
|
||||
className="input--currency-select"
|
||||
disabled={disabled}
|
||||
onChange={this.handleCurrencyChange}
|
||||
value={price.currency}
|
||||
>
|
||||
<option value="LBC">{__('LBRY Credits (LBC)')}</option>
|
||||
<option value="USD">{__('US Dollars')}</option>
|
||||
</FormField>
|
||||
</fieldset-section>
|
||||
</fieldset-group>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import classnames from 'classnames';
|
||||
import MarkdownPreview from 'component/common/markdown-preview';
|
||||
import SimpleMDE from 'react-simplemde-editor';
|
||||
import 'simplemde/dist/simplemde.min.css'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
@ -25,12 +24,18 @@ type Props = {
|
|||
affixClass?: string, // class applied to prefix/postfix label
|
||||
firstInList?: boolean, // at the top of a list, no padding top
|
||||
autoFocus?: boolean,
|
||||
labelOnLeft: boolean,
|
||||
inputProps?: {
|
||||
disabled?: boolean,
|
||||
},
|
||||
inputButton: ?React.Node,
|
||||
};
|
||||
|
||||
export class FormField extends React.PureComponent<Props> {
|
||||
static defaultProps = {
|
||||
labelOnLeft: false,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.input = React.createRef();
|
||||
|
@ -59,20 +64,51 @@ export class FormField extends React.PureComponent<Props> {
|
|||
stretch,
|
||||
affixClass,
|
||||
autoFocus,
|
||||
inputButton,
|
||||
labelOnLeft,
|
||||
...inputProps
|
||||
} = this.props;
|
||||
|
||||
const errorMessage = typeof error === 'object' ? error.message : error;
|
||||
|
||||
let input;
|
||||
if (type) {
|
||||
if (type === 'select') {
|
||||
if (type === 'radio') {
|
||||
input = (
|
||||
<div className="form-field__select-wrapper">
|
||||
<select className="form-field__select" id={name} {...inputProps}>
|
||||
<fieldset-section>
|
||||
<radio-element>
|
||||
<input id={name} type="radio" {...inputProps} />
|
||||
<label htmlFor={name}>{label}</label>
|
||||
<radio-toggle onClick={inputProps.onChange} />
|
||||
</radio-element>
|
||||
</fieldset-section>
|
||||
);
|
||||
} else if (type === 'checkbox') {
|
||||
input = (
|
||||
<fieldset-section>
|
||||
<checkbox-element>
|
||||
<input id={name} type="checkbox" {...inputProps} />
|
||||
<label htmlFor={name}>{label}</label>
|
||||
<checkbox-toggle onClick={inputProps.onChange} />
|
||||
</checkbox-element>
|
||||
</fieldset-section>
|
||||
);
|
||||
} else if (type === 'setting') {
|
||||
// 'setting' should only be used for settings. Forms should use "checkbox"
|
||||
input = (
|
||||
<input-submit>
|
||||
{labelOnLeft && <label htmlFor={name}>{label}</label>}
|
||||
<Toggle id={name} {...inputProps} />
|
||||
{!labelOnLeft && <label htmlFor={name}>{label}</label>}
|
||||
</input-submit>
|
||||
);
|
||||
} else if (type === 'select') {
|
||||
input = (
|
||||
<fieldset-section>
|
||||
{label && <label htmlFor={name}>{label}</label>}
|
||||
<select id={name} {...inputProps}>
|
||||
{children}
|
||||
</select>
|
||||
</div>
|
||||
</fieldset-section>
|
||||
);
|
||||
} else if (type === 'markdown') {
|
||||
const handleEvents = {
|
||||
|
@ -81,64 +117,59 @@ export class FormField extends React.PureComponent<Props> {
|
|||
|
||||
input = (
|
||||
<div className="form-field--SimpleMDE" onContextMenu={stopContextMenu}>
|
||||
<SimpleMDE
|
||||
{...inputProps}
|
||||
type="textarea"
|
||||
events={handleEvents}
|
||||
options={{
|
||||
hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
|
||||
previewRender(plainText) {
|
||||
const preview = <MarkdownPreview content={plainText} />;
|
||||
return ReactDOMServer.renderToString(preview);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<fieldset-section>
|
||||
<label htmlFor={name}>{label}</label>
|
||||
<SimpleMDE
|
||||
{...inputProps}
|
||||
id={name}
|
||||
type="textarea"
|
||||
events={handleEvents}
|
||||
options={{
|
||||
hideIcons: ['heading', 'image', 'fullscreen', 'side-by-side'],
|
||||
previewRender(plainText) {
|
||||
const preview = <MarkdownPreview content={plainText} />;
|
||||
return ReactDOMServer.renderToString(preview);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</fieldset-section>
|
||||
</div>
|
||||
);
|
||||
} else if (type === 'textarea') {
|
||||
input = <textarea type={type} id={name} {...inputProps} />;
|
||||
} else if (type === 'checkbox') {
|
||||
input = <Toggle id={name} {...inputProps} />;
|
||||
input = (
|
||||
<fieldset-section>
|
||||
<textarea type={type} id={name} {...inputProps} />
|
||||
</fieldset-section>
|
||||
);
|
||||
} else {
|
||||
input = <input type={type} id={name} {...inputProps} ref={this.input} />;
|
||||
const inputElement = <input type={type} id={name} {...inputProps} ref={this.input} />;
|
||||
const inner = inputButton ? (
|
||||
<input-submit>
|
||||
{inputElement}
|
||||
{inputButton}
|
||||
</input-submit>
|
||||
) : (
|
||||
inputElement
|
||||
);
|
||||
|
||||
input = (
|
||||
<React.Fragment>
|
||||
<fieldset-section>
|
||||
<label htmlFor={name}>{label}</label>
|
||||
{inner}
|
||||
</fieldset-section>
|
||||
{errorMessage && <div className="error-text">{errorMessage}</div>}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classnames('form-field', {
|
||||
'form-field--stretch': stretch || type === 'markdown',
|
||||
'form-field--disabled': inputProps.disabled,
|
||||
})}
|
||||
>
|
||||
{(label || errorMessage) && (
|
||||
<label
|
||||
className={classnames('form-field__label', { 'form-field__error': errorMessage })}
|
||||
htmlFor={name}
|
||||
>
|
||||
{!errorMessage && label}
|
||||
{errorMessage}
|
||||
</label>
|
||||
)}
|
||||
<div
|
||||
className={classnames('form-field__input', {
|
||||
'form-field--auto-height': type === 'markdown',
|
||||
})}
|
||||
>
|
||||
{prefix && (
|
||||
<label htmlFor={name} className={classnames('form-field__prefix', affixClass)}>
|
||||
{prefix}
|
||||
</label>
|
||||
)}
|
||||
{input}
|
||||
{postfix && (
|
||||
<label htmlFor={name} className={classnames('form-field__postfix', affixClass)}>
|
||||
{postfix}
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
<React.Fragment>
|
||||
{input}
|
||||
|
||||
{helper && <div className="form-field__help">{helper}</div>}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
// @flow
|
||||
// Used as a wrapper for FormField to produce inline form elements
|
||||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
children: React.Node,
|
||||
padded?: boolean,
|
||||
verticallyCentered?: boolean,
|
||||
stretch?: boolean,
|
||||
alignRight?: boolean,
|
||||
centered?: boolean,
|
||||
};
|
||||
|
||||
export class FormRow extends React.PureComponent<Props> {
|
||||
static defaultProps = {
|
||||
padded: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { children, padded, verticallyCentered, stretch, alignRight, centered } = this.props;
|
||||
return (
|
||||
<div
|
||||
className={classnames('form-row', {
|
||||
'form-row--padded': padded,
|
||||
'form-row--vertically-centered': verticallyCentered,
|
||||
'form-row--stretch': stretch,
|
||||
'form-row--right': alignRight,
|
||||
'form-row--centered': centered,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default FormRow;
|
|
@ -1,5 +1,4 @@
|
|||
export { Form } from './form-components/form';
|
||||
export { FormRow } from './form-components/form-row';
|
||||
export { FormField } from './form-components/form-field';
|
||||
export { FormFieldPrice } from './form-components/form-field-price';
|
||||
export { Submit } from './form-components/submit';
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import * as ICONS from 'constants/icons';
|
||||
import * as React from 'react';
|
||||
import { clipboard } from 'electron';
|
||||
import { FormRow } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
|
||||
type Props = {
|
||||
|
@ -24,33 +24,32 @@ export default class CopyableText extends React.PureComponent<Props> {
|
|||
const { copyable, doToast, snackMessage } = this.props;
|
||||
|
||||
return (
|
||||
<FormRow verticallyCentered stretch>
|
||||
<input
|
||||
className="input-copyable form-field__input"
|
||||
readOnly
|
||||
value={copyable || ''}
|
||||
ref={input => {
|
||||
this.input = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.input) {
|
||||
this.input.select();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
noPadding
|
||||
button="secondary"
|
||||
icon={ICONS.CLIPBOARD}
|
||||
onClick={() => {
|
||||
clipboard.writeText(copyable);
|
||||
doToast({
|
||||
message: snackMessage || __('Text copied'),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
type="text"
|
||||
className="form-field--copyable"
|
||||
readOnly
|
||||
value={copyable || ''}
|
||||
ref={input => {
|
||||
this.input = input;
|
||||
}}
|
||||
onFocus={() => {
|
||||
if (this.input) {
|
||||
this.input.select();
|
||||
}
|
||||
}}
|
||||
inputButton={
|
||||
<Button
|
||||
button="primary"
|
||||
icon={ICONS.CLIPBOARD}
|
||||
onClick={() => {
|
||||
clipboard.writeText(copyable);
|
||||
doToast({
|
||||
message: snackMessage || __('Text copied'),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ class ExternalLink extends React.PureComponent<Props> {
|
|||
iconRight={ICONS.EXTERNAL}
|
||||
title={title || href}
|
||||
label={children}
|
||||
className="btn--external-link"
|
||||
className="button--external-link"
|
||||
onClick={() => openModal(MODALS.CONFIRM_EXTERNAL_LINK, { uri: href })}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { buildURI, SORT_OPTIONS } from 'lbry-redux';
|
||||
import { FormField } from 'component/common/form';
|
||||
import { FormField, Form } from 'component/common/form';
|
||||
import FileCard from 'component/fileCard';
|
||||
import type { FileInfo } from 'types/file_info';
|
||||
|
||||
|
@ -160,7 +160,7 @@ class FileList extends React.PureComponent<Props> {
|
|||
return (
|
||||
<section>
|
||||
{!hideFilter && (
|
||||
<div className="file-list__sort">
|
||||
<Form>
|
||||
<FormField
|
||||
prefix={__('Sort by')}
|
||||
affixClass="form-field--align-center"
|
||||
|
@ -172,7 +172,7 @@ class FileList extends React.PureComponent<Props> {
|
|||
<option value={SORT_OPTIONS.DATE_OLD}>{__('Oldest First')}</option>
|
||||
<option value={SORT_OPTIONS.TITLE}>{__('Title')}</option>
|
||||
</FormField>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
|
||||
<section className="media-group--list">
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import classnames from 'classnames';
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import * as ICONS from 'constants/icons';
|
||||
|
||||
type Props = {
|
||||
play: (SyntheticInputEvent<*>) => void,
|
||||
|
@ -17,16 +16,14 @@ class VideoPlayButton extends React.PureComponent<Props> {
|
|||
const disabled = isLoading || fileInfo === undefined;
|
||||
const doesPlayback = ['audio', 'video'].indexOf(mediaType) !== -1;
|
||||
const label = doesPlayback ? __('Play') : __('View');
|
||||
const icon = doesPlayback ? ICONS.PLAY : ICONS.VIEW;
|
||||
return (
|
||||
<Button
|
||||
disabled={disabled}
|
||||
label={label}
|
||||
icon={icon}
|
||||
iconSize={30}
|
||||
className={classnames('btn--icon', {
|
||||
'btn--play': doesPlayback,
|
||||
'btn--view': !doesPlayback,
|
||||
title={label}
|
||||
className={classnames('button--icon', {
|
||||
'button--play': doesPlayback,
|
||||
'button--view': !doesPlayback,
|
||||
})}
|
||||
onClick={play}
|
||||
/>
|
||||
|
|
|
@ -67,7 +67,7 @@ class InviteList extends React.PureComponent<Props> {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<table className="table table--invites table--stretch">
|
||||
<table className="table table--invites">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{__('Invitee Email')}</th>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable react/no-multi-comp */
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import { Form, FormRow, FormField, Submit } from 'component/common/form';
|
||||
import { Form, FormField, Submit } from 'component/common/form';
|
||||
|
||||
type FormProps = {
|
||||
inviteNew: string => void,
|
||||
|
@ -41,24 +41,19 @@ class FormInviteNew extends React.PureComponent<FormProps, FormState> {
|
|||
|
||||
return (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
stretch
|
||||
type="text"
|
||||
label="Email"
|
||||
placeholder="youremail@example.org"
|
||||
name="email"
|
||||
value={this.state.email}
|
||||
error={errorMessage}
|
||||
onChange={event => {
|
||||
this.handleEmailChanged(event);
|
||||
}}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<div className="card__actions">
|
||||
<Submit label="Invite" disabled={isPending} />
|
||||
</div>
|
||||
<FormField
|
||||
stretch
|
||||
type="text"
|
||||
label="Email"
|
||||
placeholder="youremail@example.org"
|
||||
name="email"
|
||||
value={this.state.email}
|
||||
error={errorMessage}
|
||||
inputButton={<Submit label="Invite" disabled={isPending} />}
|
||||
onChange={event => {
|
||||
this.handleEmailChanged(event);
|
||||
}}
|
||||
/>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { FormRow, FormField } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import { CC_LICENSES, COPYRIGHT, OTHER, PUBLIC_DOMAIN, NONE } from 'constants/licenses';
|
||||
|
||||
type Props = {
|
||||
|
@ -41,7 +41,7 @@ class LicenseType extends React.PureComponent<Props> {
|
|||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className="card__content">
|
||||
<React.Fragment>
|
||||
<FormField
|
||||
label={__('License (Optional)')}
|
||||
type="select"
|
||||
|
@ -61,41 +61,40 @@ class LicenseType extends React.PureComponent<Props> {
|
|||
</FormField>
|
||||
|
||||
{licenseType === COPYRIGHT && (
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
label={__('Copyright notice')}
|
||||
type="text"
|
||||
name="copyright-notice"
|
||||
value={otherLicenseDescription}
|
||||
onChange={handleLicenseDescriptionChange}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Copyright notice')}
|
||||
type="text"
|
||||
name="copyright-notice"
|
||||
value={otherLicenseDescription}
|
||||
onChange={handleLicenseDescriptionChange}
|
||||
/>
|
||||
)}
|
||||
|
||||
{licenseType === OTHER && (
|
||||
<React.Fragment>
|
||||
<FormRow padded>
|
||||
<fieldset>
|
||||
<legend>{__('Provide a description and link to your license')}</legend>
|
||||
<fieldset-group>
|
||||
<FormField
|
||||
label={__('License description')}
|
||||
placeholder={__("The 'cool' license - TM")}
|
||||
type="text"
|
||||
name="other-license-description"
|
||||
value={otherLicenseDescription}
|
||||
onChange={handleLicenseDescriptionChange}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow padded>
|
||||
|
||||
<FormField
|
||||
label={__('License URL')}
|
||||
placeholder={__('mywebsite.com/license')}
|
||||
type="text"
|
||||
name="other-license-url"
|
||||
value={licenseUrl}
|
||||
onChange={handleLicenseUrlChange}
|
||||
/>
|
||||
</FormRow>
|
||||
</React.Fragment>
|
||||
</fieldset-group>
|
||||
</fieldset>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,16 @@ class NameHelpText extends React.PureComponent<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
return <React.Fragment>{nameHelpText || __('Create a URL for this content.')}</React.Fragment>;
|
||||
return (
|
||||
<React.Fragment>
|
||||
{nameHelpText || (
|
||||
<span>
|
||||
{__('Create a URL for this content.')}{' '}
|
||||
{uri && `${__('The uri for this name is')} ${uri}`}
|
||||
</span>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { CHANNEL_NEW, CHANNEL_ANONYMOUS, MINIMUM_PUBLISH_BID } from 'constants/c
|
|||
import * as ICONS from 'constants/icons';
|
||||
import * as React from 'react';
|
||||
import { isNameValid, buildURI, regexInvalidURI, THUMBNAIL_STATUSES } from 'lbry-redux';
|
||||
import { Form, FormField, FormRow, FormFieldPrice, Submit } from 'component/common/form';
|
||||
import { Form, FormField, FormFieldPrice, Submit } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import ChannelSection from 'component/selectChannel';
|
||||
import classnames from 'classnames';
|
||||
|
@ -283,7 +283,7 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
// If there is an error it will be presented as an inline error as well
|
||||
return (
|
||||
!isFormValid && (
|
||||
<div className="card__content card__subtitle form-field__error">
|
||||
<div className="card__content card__subtitle error-text">
|
||||
{!title && <div>{__('A title is required')}</div>}
|
||||
{!name && <div>{__('A URL is required')}</div>}
|
||||
{name && nameError && <div>{__('The URL you created is not valid')}</div>}
|
||||
|
@ -349,7 +349,17 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
<Form onSubmit={this.handlePublish}>
|
||||
<section className={classnames('card card--section', { 'card--disabled': publishing })}>
|
||||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Content')}</h2>
|
||||
<h2 className="card__title card__title--flex-between">
|
||||
{__('Content')}
|
||||
{(filePath || !!editingURI) && (
|
||||
<Button
|
||||
button="inverse"
|
||||
icon={ICONS.CLOSE}
|
||||
label={__('Clear')}
|
||||
onClick={clearPublish}
|
||||
/>
|
||||
)}
|
||||
</h2>
|
||||
<p className="card__subtitle">
|
||||
{isStillEditing
|
||||
? __('You are currently editing a claim.')
|
||||
|
@ -360,16 +370,6 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
</p>
|
||||
</header>
|
||||
|
||||
{(filePath || !!editingURI) && (
|
||||
<div className="card__internal-links">
|
||||
<Button
|
||||
button="inverse"
|
||||
icon={ICONS.CLOSE}
|
||||
label={__('Clear')}
|
||||
onClick={clearPublish}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="card__content">
|
||||
<FileSelector currentPath={filePath} onFileChosen={this.handleFileChange} />
|
||||
{!!isStillEditing &&
|
||||
|
@ -384,9 +384,8 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
</section>
|
||||
<div className={classnames({ 'card--disabled': formDisabled })}>
|
||||
<section className="card card--section">
|
||||
<FormRow>
|
||||
<div className="card__content">
|
||||
<FormField
|
||||
stretch
|
||||
type="text"
|
||||
name="content_title"
|
||||
label={__('Title')}
|
||||
|
@ -395,10 +394,8 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
value={title}
|
||||
onChange={e => updatePublishForm({ title: e.target.value })}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow padded>
|
||||
|
||||
<FormField
|
||||
stretch
|
||||
type="markdown"
|
||||
name="content_description"
|
||||
label={__('Description')}
|
||||
|
@ -407,7 +404,7 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
disabled={formDisabled}
|
||||
onChange={text => updatePublishForm({ description: text })}
|
||||
/>
|
||||
</FormRow>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -443,22 +440,26 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormField
|
||||
type="radio"
|
||||
name="content_free"
|
||||
postfix={__('Free')}
|
||||
checked={contentIsFree}
|
||||
disabled={formDisabled}
|
||||
onChange={() => updatePublishForm({ contentIsFree: true })}
|
||||
/>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="content_cost"
|
||||
postfix={__('Choose price')}
|
||||
checked={!contentIsFree}
|
||||
disabled={formDisabled}
|
||||
onChange={() => updatePublishForm({ contentIsFree: false })}
|
||||
/>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="content_free"
|
||||
label={__('Free')}
|
||||
checked={contentIsFree}
|
||||
disabled={formDisabled}
|
||||
onChange={() => updatePublishForm({ contentIsFree: true })}
|
||||
/>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="content_cost"
|
||||
label={__('Choose price')}
|
||||
checked={!contentIsFree}
|
||||
disabled={formDisabled}
|
||||
onChange={() => updatePublishForm({ contentIsFree: false })}
|
||||
/>
|
||||
</fieldset-section>
|
||||
{!contentIsFree && (
|
||||
<FormFieldPrice
|
||||
name="content_cost_amount"
|
||||
|
@ -503,36 +504,33 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormRow>
|
||||
<FormField
|
||||
stretch
|
||||
label={__('Name')}
|
||||
prefix={`lbry://${
|
||||
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW
|
||||
? ''
|
||||
: `${channel}/`
|
||||
}`}
|
||||
type="text"
|
||||
name="content_name"
|
||||
placeholder="myname"
|
||||
value={name}
|
||||
onChange={event => this.handleNameChange(event.target.value)}
|
||||
error={nameError}
|
||||
helper={
|
||||
<NameHelpText
|
||||
isStillEditing={isStillEditing}
|
||||
uri={uri}
|
||||
myClaimForUri={myClaimForUri}
|
||||
onEditMyClaim={this.editExistingClaim}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Name')}
|
||||
prefix={`lbry://${
|
||||
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW
|
||||
? ''
|
||||
: `${channel}/`
|
||||
}`}
|
||||
type="text"
|
||||
name="content_name"
|
||||
placeholder="myname"
|
||||
value={name}
|
||||
onChange={event => this.handleNameChange(event.target.value)}
|
||||
error={nameError}
|
||||
helper={
|
||||
<NameHelpText
|
||||
isStillEditing={isStillEditing}
|
||||
uri={uri}
|
||||
myClaimForUri={myClaimForUri}
|
||||
onEditMyClaim={this.editExistingClaim}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={classnames('card__content', { 'card--disabled': !name })}>
|
||||
<FormField
|
||||
className="input--price-amount"
|
||||
className="form-field--price-amount"
|
||||
type="number"
|
||||
name="content_bid"
|
||||
step="any"
|
||||
|
@ -557,39 +555,35 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
|
||||
<section className="card card--section">
|
||||
<div className="card__content">
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="content_is_mature"
|
||||
postfix={__('Mature audiences only')}
|
||||
checked={nsfw}
|
||||
onChange={event => updatePublishForm({ nsfw: event.target.checked })}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="content_is_mature"
|
||||
label={__('Mature audiences only')}
|
||||
checked={nsfw}
|
||||
onChange={() => updatePublishForm({ nsfw: !nsfw })}
|
||||
/>
|
||||
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
label={__('Language')}
|
||||
type="select"
|
||||
name="content_language"
|
||||
value={language}
|
||||
onChange={event => updatePublishForm({ language: event.target.value })}
|
||||
>
|
||||
<option value="en">{__('English')}</option>
|
||||
<option value="zh">{__('Chinese')}</option>
|
||||
<option value="fr">{__('French')}</option>
|
||||
<option value="de">{__('German')}</option>
|
||||
<option value="jp">{__('Japanese')}</option>
|
||||
<option value="ru">{__('Russian')}</option>
|
||||
<option value="es">{__('Spanish')}</option>
|
||||
<option value="id">{__('Indonesian')}</option>
|
||||
<option value="it">{__('Italian')}</option>
|
||||
<option value="nl">{__('Dutch')}</option>
|
||||
<option value="tr">{__('Turkish')}</option>
|
||||
<option value="pl">{__('Polish')}</option>
|
||||
<option value="ms">{__('Malay')}</option>
|
||||
</FormField>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Language')}
|
||||
type="select"
|
||||
name="content_language"
|
||||
value={language}
|
||||
onChange={event => updatePublishForm({ language: event.target.value })}
|
||||
>
|
||||
<option value="en">{__('English')}</option>
|
||||
<option value="zh">{__('Chinese')}</option>
|
||||
<option value="fr">{__('French')}</option>
|
||||
<option value="de">{__('German')}</option>
|
||||
<option value="jp">{__('Japanese')}</option>
|
||||
<option value="ru">{__('Russian')}</option>
|
||||
<option value="es">{__('Spanish')}</option>
|
||||
<option value="id">{__('Indonesian')}</option>
|
||||
<option value="it">{__('Italian')}</option>
|
||||
<option value="nl">{__('Dutch')}</option>
|
||||
<option value="tr">{__('Turkish')}</option>
|
||||
<option value="pl">{__('Polish')}</option>
|
||||
<option value="ms">{__('Malay')}</option>
|
||||
</FormField>
|
||||
|
||||
<LicenseType
|
||||
licenseType={licenseType}
|
||||
|
@ -636,13 +630,13 @@ class PublishForm extends React.PureComponent<Props> {
|
|||
uploadThumbnailStatus === THUMBNAIL_STATUSES.IN_PROGRESS
|
||||
}
|
||||
/>
|
||||
<Button button="alt" onClick={this.handleCancelPublish} label={__('Cancel')} />
|
||||
<Button button="link" onClick={this.handleCancelPublish} label={__('Cancel')} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{!formDisabled && !formValid && this.renderFormErrors()}
|
||||
</div>
|
||||
|
||||
{!formDisabled && !formValid && this.renderFormErrors()}
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ const RewardListClaimed = (props: Props) => {
|
|||
</p>
|
||||
</header>
|
||||
|
||||
<table className="table table--rewards table--stretch">
|
||||
<table className="card__content table table--rewards">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{__('Title')}</th>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { isNameValid } from 'lbry-redux';
|
||||
import { FormRow, FormField } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import BusyIndicator from 'component/common/busy-indicator';
|
||||
import Button from 'component/button';
|
||||
import { CHANNEL_NEW, CHANNEL_ANONYMOUS } from 'constants/claim';
|
||||
|
@ -152,54 +152,54 @@ class ChannelSection extends React.PureComponent<Props, State> {
|
|||
|
||||
return (
|
||||
<div className="card__content">
|
||||
{createChannelError && <div className="form-field__error">{createChannelError}</div>}
|
||||
{createChannelError && <div className="error-text">{createChannelError}</div>}
|
||||
{fetchingChannels ? (
|
||||
<BusyIndicator message="Updating channels" />
|
||||
) : (
|
||||
<FormField
|
||||
key="channel"
|
||||
type="select"
|
||||
onChange={this.handleChannelChange}
|
||||
value={channel}
|
||||
>
|
||||
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
|
||||
{channels.map(({ name }) => (
|
||||
<option key={name} value={name}>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
<option value={CHANNEL_NEW}>{__('New channel...')}</option>
|
||||
</FormField>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
key="channel"
|
||||
type="select"
|
||||
onChange={this.handleChannelChange}
|
||||
value={channel}
|
||||
>
|
||||
<option value={CHANNEL_ANONYMOUS}>{__('Anonymous')}</option>
|
||||
{channels.map(({ name }) => (
|
||||
<option key={name} value={name}>
|
||||
{name}
|
||||
</option>
|
||||
))}
|
||||
<option value={CHANNEL_NEW}>{__('New channel...')}</option>
|
||||
</FormField>
|
||||
</fieldset-section>
|
||||
)}
|
||||
{addingChannel && (
|
||||
<div className="card__content">
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
label={__('Name')}
|
||||
type="text"
|
||||
prefix="@"
|
||||
placeholder={__('myChannelName')}
|
||||
error={newChannelNameError}
|
||||
value={newChannelName}
|
||||
onChange={this.handleNewChannelNameChange}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
className="input--price-amount"
|
||||
label={__('Deposit')}
|
||||
postfix="LBC"
|
||||
step="any"
|
||||
min="0"
|
||||
type="number"
|
||||
helper={__(
|
||||
'This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.'
|
||||
)}
|
||||
error={newChannelBidError}
|
||||
value={newChannelBid}
|
||||
onChange={event => this.handleNewChannelBidChange(parseFloat(event.target.value))}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Name')}
|
||||
type="text"
|
||||
prefix="@"
|
||||
placeholder={__('myChannelName')}
|
||||
error={newChannelNameError}
|
||||
value={newChannelName}
|
||||
onChange={this.handleNewChannelNameChange}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
className="form-field--price-amount"
|
||||
label={__('Deposit')}
|
||||
postfix="LBC"
|
||||
step="any"
|
||||
min="0"
|
||||
type="number"
|
||||
helper={__(
|
||||
'This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.'
|
||||
)}
|
||||
error={newChannelBidError}
|
||||
value={newChannelBid}
|
||||
onChange={event => this.handleNewChannelBidChange(parseFloat(event.target.value))}
|
||||
/>
|
||||
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
|
|
|
@ -92,7 +92,6 @@ class SelectThumbnail extends React.PureComponent<Props, State> {
|
|||
</div>
|
||||
<div className="column__item">
|
||||
<FormField
|
||||
className="input--thumbnail"
|
||||
type="text"
|
||||
name="content_thumbnail"
|
||||
label="URL"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import QRCode from 'component/common/qr-code';
|
||||
import { FormRow } from 'component/common/form';
|
||||
import * as statuses from 'constants/shape_shift';
|
||||
import CopyableText from 'component/copyableText';
|
||||
import Button from 'component/button';
|
||||
|
@ -94,10 +93,10 @@ class ActiveShapeShift extends React.PureComponent<Props> {
|
|||
/>
|
||||
|
||||
{shiftDepositAddress && (
|
||||
<FormRow verticallyCentered padded>
|
||||
<React.Fragment>
|
||||
<QRCode value={shiftDepositAddress} paddingRight />
|
||||
<CopyableText copyable={shiftDepositAddress} />
|
||||
</FormRow>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { getExampleAddress } from 'util/shape_shift';
|
||||
import { FormField, FormRow, Submit } from 'component/common/form';
|
||||
import { FormField, Submit } from 'component/common/form';
|
||||
import type { ShapeShiftFormValues, Action } from 'redux/actions/shape_shift';
|
||||
import type { Dispatch, ThunkAction } from 'types/redux';
|
||||
import ShiftMarketInfo from './market_info';
|
||||
|
@ -70,19 +70,17 @@ export default (props: Props) => {
|
|||
originCoinDepositMax={originCoinDepositMax}
|
||||
/>
|
||||
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
label={__('Return address')}
|
||||
error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress}
|
||||
type="text"
|
||||
name="returnAddress"
|
||||
className="input--address"
|
||||
placeholder={getExampleAddress(originCoin)}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.returnAddress}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Return address')}
|
||||
error={touched.returnAddress && !!errors.returnAddress && errors.returnAddress}
|
||||
type="text"
|
||||
name="returnAddress"
|
||||
className="form-field--address"
|
||||
placeholder={getExampleAddress(originCoin)}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.returnAddress}
|
||||
/>
|
||||
|
||||
<span className="help">
|
||||
({__('optional but recommended')})<br />
|
||||
|
|
|
@ -79,14 +79,13 @@ class ShapeShift extends React.PureComponent<Props> {
|
|||
<p className="card__subtitle">
|
||||
{__('Powered by ShapeShift. Read our FAQ')}{' '}
|
||||
<Button button="link" label={__('here')} href="https://lbry.io/faq/shapeshift" />.
|
||||
{hasActiveShift && shiftState !== 'complete' && (
|
||||
<span>{__('This will update automatically.')}</span>
|
||||
)}
|
||||
{hasActiveShift &&
|
||||
shiftState !== 'complete' && <span>{__('This will update automatically.')}</span>}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
{error && <div className="form-field__error">{error}</div>}
|
||||
{error && <div className="error-text">{error}</div>}
|
||||
{!hasActiveShift && (
|
||||
<Formik
|
||||
onSubmit={createShapeShift}
|
||||
|
|
|
@ -35,7 +35,7 @@ class LoadScreen extends React.PureComponent<Props> {
|
|||
<div className="load-screen__actions">
|
||||
<Button
|
||||
label="Refresh"
|
||||
className="btn--load-screen"
|
||||
className="button--load-screen"
|
||||
onClick={() => window.location.reload()}
|
||||
/>
|
||||
</div>
|
||||
|
@ -48,7 +48,7 @@ class LoadScreen extends React.PureComponent<Props> {
|
|||
<p>
|
||||
{__('Reach out to hello@lbry.io for help, or check out')}{' '}
|
||||
<Button
|
||||
className="btn--load-screen"
|
||||
className="button--load-screen"
|
||||
href="https://lbry.io/faq/startup-troubleshooting"
|
||||
label="this link"
|
||||
/>
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { Transaction } from 'types/transaction';
|
|||
import * as icons from 'constants/icons';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import * as React from 'react';
|
||||
import { FormField } from 'component/common/form';
|
||||
import { FormField, Form } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import FileExporter from 'component/common/file-exporter';
|
||||
import { TRANSACTIONS } from 'lbry-redux';
|
||||
|
@ -80,27 +80,29 @@ class TransactionList extends React.PureComponent<Props> {
|
|||
defaultPath={__('lbry-transactions-history')}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="select"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
affixClass="form-field--align-center"
|
||||
prefix={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.io/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
<Form>
|
||||
<FormField
|
||||
type="select"
|
||||
value={filterSetting || TRANSACTIONS.ALL}
|
||||
onChange={this.handleFilterChanged}
|
||||
affixClass="form-field--align-center"
|
||||
prefix={__('Show')}
|
||||
postfix={
|
||||
<Button
|
||||
button="link"
|
||||
icon={icons.HELP}
|
||||
href="https://lbry.io/faq/transaction-types"
|
||||
title={__('Help')}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{transactionTypes.map(tt => (
|
||||
<option key={tt} value={tt}>
|
||||
{__(`${this.capitalize(tt)}`)}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</Form>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
|
@ -110,7 +112,7 @@ class TransactionList extends React.PureComponent<Props> {
|
|||
|
||||
{!!transactionList.length && (
|
||||
<div className="card__content">
|
||||
<table className="table table--transactions table--stretch">
|
||||
<table className="table table--transactions">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{__('Amount')}</th>
|
||||
|
|
|
@ -12,7 +12,7 @@ type State = {
|
|||
disabled: boolean,
|
||||
};
|
||||
|
||||
class TransactionListRecent extends PureComponent<Props, State> {
|
||||
class TransactionRefreshButton extends PureComponent<Props, State> {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
@ -48,4 +48,4 @@ class TransactionListRecent extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
export default TransactionListRecent;
|
||||
export default TransactionRefreshButton;
|
||||
|
|
|
@ -61,7 +61,7 @@ class UriIndicator extends React.PureComponent<Props> {
|
|||
return (
|
||||
<Button
|
||||
noPadding
|
||||
className="btn--uri-indicator"
|
||||
className="button--uri-indicator"
|
||||
navigate="/show"
|
||||
navigateParams={{ uri: channelLink, page: 1 }}
|
||||
>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { FormField, Form, FormRow, Submit } from 'component/common/form';
|
||||
import { FormField, Form, Submit } from 'component/common/form';
|
||||
|
||||
type Props = {
|
||||
cancelButton: React.Node,
|
||||
|
@ -50,24 +50,18 @@ class UserEmailNew extends React.PureComponent<Props, State> {
|
|||
</header>
|
||||
|
||||
<Form className="card__content" onSubmit={this.handleSubmit}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
stretch
|
||||
type="email"
|
||||
label="Email"
|
||||
placeholder="youremail@example.org"
|
||||
name="email"
|
||||
value={this.state.email}
|
||||
error={errorMessage}
|
||||
onChange={this.handleEmailChanged}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<div className="card__actions">
|
||||
<Submit label="Submit" disabled={isPending || !this.state.email} />
|
||||
{cancelButton}
|
||||
</div>
|
||||
<FormField
|
||||
type="email"
|
||||
label="Email"
|
||||
placeholder="youremail@example.org"
|
||||
name="email"
|
||||
value={this.state.email}
|
||||
error={errorMessage}
|
||||
onChange={this.handleEmailChanged}
|
||||
inputButton={<Submit label="Submit" disabled={isPending || !this.state.email} />}
|
||||
/>
|
||||
</Form>
|
||||
<div className="card__actions">{cancelButton}</div>
|
||||
<p className="help">
|
||||
{__('Your email address will never be sold and you can unsubscribe at any time.')}
|
||||
</p>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import Button from 'component/button';
|
||||
import { FormField, FormRow } from 'component/common/form';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import ReactPaginate from 'react-paginate';
|
||||
import UserHistoryItem from 'component/userHistoryItem';
|
||||
|
||||
|
@ -94,9 +94,9 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { history, page, pageCount } = this.props;
|
||||
const { history, page } = this.props;
|
||||
const { itemsSelected } = this.state;
|
||||
|
||||
const pageCount = 20;
|
||||
const allSelected = Object.keys(itemsSelected).length === history.length;
|
||||
const selectHandler = allSelected ? this.unselectAll : this.selectAll;
|
||||
|
||||
|
@ -131,32 +131,35 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
|
|||
))}
|
||||
</section>
|
||||
)}
|
||||
{pageCount > 1 && (
|
||||
<FormRow padded verticallyCentered centered>
|
||||
<ReactPaginate
|
||||
pageCount={pageCount}
|
||||
pageRangeDisplayed={2}
|
||||
previousLabel="‹"
|
||||
nextLabel="›"
|
||||
activeClassName="pagination__item--selected"
|
||||
pageClassName="pagination__item"
|
||||
previousClassName="pagination__item pagination__item--previous"
|
||||
nextClassName="pagination__item pagination__item--next"
|
||||
breakClassName="pagination__item pagination__item--break"
|
||||
marginPagesDisplayed={2}
|
||||
onPageChange={e => this.changePage(e.selected)}
|
||||
forcePage={page}
|
||||
initialPage={page}
|
||||
containerClassName="pagination"
|
||||
/>
|
||||
|
||||
<FormField
|
||||
className="paginate-channel"
|
||||
onKeyUp={e => this.paginate(e)}
|
||||
prefix={__('Go to page:')}
|
||||
type="text"
|
||||
/>
|
||||
</FormRow>
|
||||
{pageCount > -1 && (
|
||||
<Form>
|
||||
<fieldset-group class="fieldset-group--smushed fieldgroup--paginate">
|
||||
<fieldset-section>
|
||||
<ReactPaginate
|
||||
pageCount={pageCount}
|
||||
pageRangeDisplayed={2}
|
||||
previousLabel="‹"
|
||||
nextLabel="›"
|
||||
activeClassName="pagination__item--selected"
|
||||
pageClassName="pagination__item"
|
||||
previousClassName="pagination__item pagination__item--previous"
|
||||
nextClassName="pagination__item pagination__item--next"
|
||||
breakClassName="pagination__item pagination__item--break"
|
||||
marginPagesDisplayed={2}
|
||||
onPageChange={e => this.changePage(e.selected)}
|
||||
forcePage={page}
|
||||
initialPage={page}
|
||||
containerClassName="pagination"
|
||||
/>
|
||||
</fieldset-section>
|
||||
<FormField
|
||||
className="paginate-channel"
|
||||
onKeyUp={e => this.paginate(e)}
|
||||
label={__('Go to page:')}
|
||||
type="text"
|
||||
/>
|
||||
</fieldset-group>
|
||||
</Form>
|
||||
)}
|
||||
</React.Fragment>
|
||||
) : (
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { Claim } from 'types/claim';
|
|||
import moment from 'moment';
|
||||
import classnames from 'classnames';
|
||||
import Button from 'component/button';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
type Props = {
|
||||
lastViewed: number,
|
||||
|
@ -43,7 +44,7 @@ class UserHistoryItem extends React.PureComponent<Props> {
|
|||
'item-list__item--selected': selected,
|
||||
})}
|
||||
>
|
||||
<input checked={selected} type="checkbox" onClick={onSelect} />
|
||||
<FormField checked={selected} type="checkbox" onClick={onSelect} />
|
||||
<span className="time time--ago">{moment(lastViewed).from(moment())}</span>
|
||||
<span className="item-list__item--cutoff">{title}</span>
|
||||
<Button
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { Form, FormRow, FormField, Submit } from 'component/common/form';
|
||||
import { Form, FormField, Submit } from 'component/common/form';
|
||||
|
||||
const os = require('os').type();
|
||||
const countryCodes = require('country-data')
|
||||
|
@ -95,27 +95,29 @@ class UserPhoneNew extends React.PureComponent<Props, State> {
|
|||
</section>
|
||||
|
||||
<Form className="card__content" onSubmit={this.handleSubmit}>
|
||||
<FormRow padded>
|
||||
<FormField type="select" name="country-codes" onChange={this.handleSelect}>
|
||||
{countryCodes.map((country, index) => (
|
||||
// eslint-disable-next-line
|
||||
<option key={index} value={country.countryCallingCode}>
|
||||
{os === 'Darwin' ? country.emoji : `(${country.alpha2})`}{' '}
|
||||
{country.countryCallingCode}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
<FormField
|
||||
type="text"
|
||||
placeholder={this.state.countryCode === '+1' ? '(555) 555-5555' : '5555555555'}
|
||||
name="phone"
|
||||
value={this.state.phone}
|
||||
error={phoneErrorMessage}
|
||||
onChange={event => {
|
||||
this.handleChanged(event);
|
||||
}}
|
||||
/>
|
||||
</FormRow>
|
||||
<fieldset-section>
|
||||
<fieldset-group class="fieldset-group--smushed">
|
||||
<FormField type="select" name="country-codes" onChange={this.handleSelect}>
|
||||
{countryCodes.map((country, index) => (
|
||||
// eslint-disable-next-line
|
||||
<option key={index} value={country.countryCallingCode}>
|
||||
{os === 'Darwin' ? country.emoji : `(${country.alpha2})`}{' '}
|
||||
{country.countryCallingCode}
|
||||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
<FormField
|
||||
type="text"
|
||||
placeholder={this.state.countryCode === '+1' ? '(555) 555-5555' : '5555555555'}
|
||||
name="phone"
|
||||
value={this.state.phone}
|
||||
error={phoneErrorMessage}
|
||||
onChange={event => {
|
||||
this.handleChanged(event);
|
||||
}}
|
||||
/>
|
||||
</fieldset-group>
|
||||
</fieldset-section>
|
||||
<div className="card__actions">
|
||||
<Submit label="Submit" disabled={isPending} />
|
||||
{cancelButton}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import { Form, FormField, Submit, FormRow } from 'component/common/form';
|
||||
import { Form, FormField, Submit } from 'component/common/form';
|
||||
|
||||
class UserPhoneVerify extends React.PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -43,24 +43,20 @@ class UserPhoneVerify extends React.PureComponent {
|
|||
</p>
|
||||
</section>
|
||||
<Form className="card__content" onSubmit={this.handleSubmit.bind(this)}>
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="text"
|
||||
name="code"
|
||||
placeholder="1234"
|
||||
value={this.state.code}
|
||||
onChange={event => {
|
||||
this.handleCodeChanged(event);
|
||||
}}
|
||||
label={__('Verification Code')}
|
||||
error={phoneErrorMessage}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
type="text"
|
||||
name="code"
|
||||
placeholder="1234"
|
||||
value={this.state.code}
|
||||
onChange={event => {
|
||||
this.handleCodeChanged(event);
|
||||
}}
|
||||
label={__('Verification Code')}
|
||||
error={phoneErrorMessage}
|
||||
inputButton={<Submit label={__('Verify')} />}
|
||||
/>
|
||||
|
||||
<div className="card__actions">
|
||||
<Submit label={__('Verify')} />
|
||||
{cancelButton}
|
||||
</div>
|
||||
<div className="card__actions">{cancelButton}</div>
|
||||
</Form>
|
||||
|
||||
<p className="help">
|
||||
|
|
|
@ -51,7 +51,7 @@ class UserVerify extends React.PureComponent<Props> {
|
|||
|
||||
<div className="card__content">
|
||||
<div className="card__actions">
|
||||
{errorMessage && <p className="form-field__error">{errorMessage}</p>}
|
||||
{errorMessage && <p className="error-text">{errorMessage}</p>}
|
||||
<CardVerify
|
||||
label={__('Perform Card Verification')}
|
||||
disabled={isPending}
|
||||
|
|
|
@ -16,9 +16,7 @@ const WalletBalance = (props: Props) => {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
{(balance || balance === 0) && (
|
||||
<CreditAmount badge={false} large amount={balance} precision={8} />
|
||||
)}
|
||||
{(balance || balance === 0) && <CreditAmount large amount={balance} precision={8} />}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import React from 'react';
|
||||
import * as MODALS from 'constants/modal_types';
|
||||
import Button from 'component/button';
|
||||
import { Form, FormRow, FormField } from 'component/common/form';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import { Formik } from 'formik';
|
||||
import { validateSendTx } from 'util/form-validation';
|
||||
|
||||
|
@ -39,25 +39,26 @@ class WalletSend extends React.PureComponent<Props> {
|
|||
<section className="card card--section">
|
||||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Send Credits')}</h2>
|
||||
<p className="card__subtitle">{__('Send LBC to your friends or favorite creators')}</p>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<Formik
|
||||
initialValues={{
|
||||
address: '',
|
||||
amount: '',
|
||||
}}
|
||||
onSubmit={this.handleSubmit}
|
||||
validate={validateSendTx}
|
||||
render={({ values, errors, touched, handleChange, handleBlur, handleSubmit }) => (
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<FormRow>
|
||||
<Formik
|
||||
initialValues={{
|
||||
address: '',
|
||||
amount: '',
|
||||
}}
|
||||
onSubmit={this.handleSubmit}
|
||||
validate={validateSendTx}
|
||||
render={({ values, errors, touched, handleChange, handleBlur, handleSubmit }) => (
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<div className="card__content">
|
||||
<fieldset-group class="fieldset-group--smushed">
|
||||
<FormField
|
||||
type="number"
|
||||
name="amount"
|
||||
label={__('Amount')}
|
||||
postfix={__('LBC')}
|
||||
className="input--price-amount"
|
||||
className="form-field--price-amount"
|
||||
affixClass="form-field--fix-no-height"
|
||||
min="0"
|
||||
step="any"
|
||||
|
@ -65,44 +66,45 @@ class WalletSend extends React.PureComponent<Props> {
|
|||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.amount}
|
||||
error={
|
||||
(!!values.amount && touched.amount && errors.amount) ||
|
||||
(values.amount === balance &&
|
||||
__('Decrease amount to account for transaction fee')) ||
|
||||
(values.amount > balance && __('Not enough credits'))
|
||||
}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
|
||||
<FormField
|
||||
type="text"
|
||||
name="address"
|
||||
placeholder="bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs"
|
||||
className="input--address"
|
||||
className="form-field--address"
|
||||
label={__('Recipient address')}
|
||||
error={!!values.address && touched.address && errors.address}
|
||||
onChange={handleChange}
|
||||
onBlur={handleBlur}
|
||||
value={values.address}
|
||||
/>
|
||||
</FormRow>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
type="submit"
|
||||
label={__('Send')}
|
||||
disabled={
|
||||
!values.address ||
|
||||
!!Object.keys(errors).length ||
|
||||
!(parseFloat(values.amount) > 0.0) ||
|
||||
parseFloat(values.amount) === balance
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</fieldset-group>
|
||||
</div>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
type="submit"
|
||||
label={__('Send')}
|
||||
disabled={
|
||||
!values.address ||
|
||||
!!Object.keys(errors).length ||
|
||||
!(parseFloat(values.amount) > 0.0) ||
|
||||
parseFloat(values.amount) === balance
|
||||
}
|
||||
/>
|
||||
{!!Object.keys(errors).length && (
|
||||
<span className="error-text">
|
||||
{(!!values.address && touched.address && errors.address) ||
|
||||
(!!values.amount && touched.amount && errors.amount) ||
|
||||
(values.amount === balance &&
|
||||
__('Decrease amount to account for transaction fee')) ||
|
||||
(values.amount > balance && __('Not enough credits'))}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
)}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import { FormField, FormRow } from 'component/common/form';
|
||||
import { FormField, Form } from 'component/common/form';
|
||||
import type { Claim } from 'types/claim';
|
||||
|
||||
type Props = {
|
||||
|
@ -75,7 +75,7 @@ class WalletSendTip extends React.PureComponent<Props, State> {
|
|||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<FormRow className="card__content">
|
||||
<Form>
|
||||
<FormField
|
||||
autoFocus
|
||||
label={
|
||||
|
@ -85,13 +85,21 @@ class WalletSendTip extends React.PureComponent<Props, State> {
|
|||
__('Amount')
|
||||
}
|
||||
postfix={__('LBC')}
|
||||
className="input--price-amount"
|
||||
className="form-field--price-amount"
|
||||
error={tipError}
|
||||
min="0"
|
||||
step="any"
|
||||
type="number"
|
||||
placeholder="1.23"
|
||||
onChange={event => this.handleSupportPriceChange(event)}
|
||||
inputButton={
|
||||
<Button
|
||||
button="primary"
|
||||
label={__('Send')}
|
||||
disabled={isPending || tipError}
|
||||
onClick={this.handleSendButtonClicked}
|
||||
/>
|
||||
}
|
||||
helper={
|
||||
<p>
|
||||
{__(`This will appear as a tip for "${title}".`)}{' '}
|
||||
|
@ -99,15 +107,8 @@ class WalletSendTip extends React.PureComponent<Props, State> {
|
|||
</p>
|
||||
}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
</Form>
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
label={__('Send')}
|
||||
disabled={isPending || tipError}
|
||||
onClick={this.handleSendButtonClicked}
|
||||
/>
|
||||
<Button button="link" label={__('Cancel')} onClick={onCancel} navigateParams={{ uri }} />
|
||||
</div>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Modal } from 'modal/modal';
|
||||
import { FormField, FormRow } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
type Props = {
|
||||
upload: (string, boolean) => void,
|
||||
|
@ -36,15 +36,14 @@ class ModalConfirmThumbnailUpload extends React.PureComponent<Props> {
|
|||
<p>{__('Are you sure you want to upload this thumbnail to spee.ch')}?</p>
|
||||
|
||||
<blockquote>{path}</blockquote>
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="content_is_mature"
|
||||
postfix={__('For mature audiences only')}
|
||||
checked={nsfw}
|
||||
onChange={event => updatePublishForm({ nsfw: event.target.checked })}
|
||||
/>
|
||||
</FormRow>
|
||||
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="content_is_mature"
|
||||
label={__('For mature audiences only')}
|
||||
checked={nsfw}
|
||||
onChange={event => updatePublishForm({ nsfw: event.target.checked })}
|
||||
/>
|
||||
</section>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -27,13 +27,13 @@ class ModalIncompatibleDaemon extends React.PureComponent<Props> {
|
|||
<p>
|
||||
{__(
|
||||
'This app is running with an incompatible version of the LBRY protocol. You can still use it, but there may be issues. Re-run the installation package for best results.'
|
||||
)}
|
||||
)}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Learn more')}
|
||||
href="https://lbry.io/faq/incompatible-protocol-version"
|
||||
/>.
|
||||
</p>
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Learn more')}
|
||||
href="https://lbry.io/faq/incompatible-protocol-version"
|
||||
/>.
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Modal } from 'modal/modal';
|
||||
import { FormRow, FormField } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
|
||||
type Props = {
|
||||
claimIsMine: boolean,
|
||||
|
@ -74,23 +74,20 @@ class ModalRemoveFile extends React.PureComponent<Props, State> {
|
|||
</p>
|
||||
</section>
|
||||
<section className="card__content">
|
||||
<FormRow>
|
||||
<FormField
|
||||
prefix={__('Also delete this file from my computer')}
|
||||
type="checkbox"
|
||||
checked={deleteChecked}
|
||||
onChange={this.handleDeleteCheckboxClicked}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Also delete this file from my computer')}
|
||||
type="checkbox"
|
||||
checked={deleteChecked}
|
||||
onChange={this.handleDeleteCheckboxClicked}
|
||||
/>
|
||||
|
||||
{claimIsMine && (
|
||||
<FormRow>
|
||||
<FormField
|
||||
prefix={__('Abandon the claim for this URI')}
|
||||
type="checkbox"
|
||||
checked={abandonClaimChecked}
|
||||
onChange={this.handleAbandonClaimCheckboxClicked}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
label={__('Abandon the claim for this URI')}
|
||||
type="checkbox"
|
||||
checked={abandonClaimChecked}
|
||||
onChange={this.handleAbandonClaimCheckboxClicked}
|
||||
/>
|
||||
)}
|
||||
</section>
|
||||
</Modal>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
import { FormRow, FormField } from 'component/common/form';
|
||||
import { FormField, Form, Submit } from 'component/common/form';
|
||||
import { Modal } from 'modal/modal';
|
||||
import Button from 'component/button';
|
||||
|
||||
|
@ -41,14 +41,10 @@ class ModalRewardCode extends React.PureComponent<Props, State> {
|
|||
isOpen
|
||||
title={__('Enter Reward Code')}
|
||||
contentLabel={__('Enter Reward Code')}
|
||||
type="confirm"
|
||||
confirmButtonLabel={__('Redeem')}
|
||||
abortButtonLabel={__('Cancel')}
|
||||
onConfirmed={this.handleSubmit}
|
||||
type="custom"
|
||||
onAborted={closeModal}
|
||||
confirmButtonDisabled={rewardIsPending}
|
||||
>
|
||||
<section className="card__content">
|
||||
<Form className="card__content" onSubmit={this.handleSubmit}>
|
||||
<p>
|
||||
{__('Redeem a custom reward code for LBC')}
|
||||
{'. '}
|
||||
|
@ -58,19 +54,25 @@ class ModalRewardCode extends React.PureComponent<Props, State> {
|
|||
label={__('Learn more')}
|
||||
/>.
|
||||
</p>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
autoFocus
|
||||
type="text"
|
||||
label={__('Code')}
|
||||
placeholder="0123abc"
|
||||
error={error}
|
||||
value={rewardCode}
|
||||
onChange={e => this.setState({ rewardCode: e.target.value })}
|
||||
/>
|
||||
</FormRow>
|
||||
</section>
|
||||
<FormField
|
||||
autoFocus
|
||||
type="text"
|
||||
inputButton={
|
||||
<Submit
|
||||
disabled={!rewardCode || rewardIsPending}
|
||||
label={rewardIsPending ? __('Redeeming') : __('Redeem')}
|
||||
/>
|
||||
}
|
||||
label={__('Code')}
|
||||
placeholder="0123abc"
|
||||
error={error}
|
||||
value={rewardCode}
|
||||
onChange={e => this.setState({ rewardCode: e.target.value })}
|
||||
/>
|
||||
</Form>
|
||||
<div className="card__actions">
|
||||
<Button button="link" label={__('Cancel')} onClick={closeModal} />
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Form, FormRow, FormField } from 'component/common/form';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import { Modal } from 'modal/modal';
|
||||
import Button from 'component/button';
|
||||
|
||||
|
@ -101,59 +101,53 @@ class ModalWalletEncrypt extends React.PureComponent<Props, State> {
|
|||
onConfirmed={() => this.submitEncryptForm()}
|
||||
onAborted={closeModal}
|
||||
>
|
||||
<Form onSubmit={() => this.submitEncryptForm()}>
|
||||
<section className="card__content">
|
||||
<p>
|
||||
{__(
|
||||
'Encrypting your wallet will require a password to access your local wallet data when LBRY starts. Please enter a new password for your wallet.'
|
||||
)}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Learn more')}
|
||||
href="https://lbry.io/faq/wallet-encryption"
|
||||
/>.
|
||||
</p>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
autoFocus
|
||||
error={passwordMismatch === true ? 'Passwords do not match' : false}
|
||||
label={__('Password')}
|
||||
type="password"
|
||||
name="wallet-new-password"
|
||||
onChange={event => this.onChangeNewPassword(event)}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
error={passwordMismatch === true ? 'Passwords do not match' : false}
|
||||
label={__('Confirm Password')}
|
||||
type="password"
|
||||
name="wallet-new-password-confirm"
|
||||
onChange={event => this.onChangeNewPasswordConfirm(event)}
|
||||
/>
|
||||
</FormRow>
|
||||
</section>
|
||||
<section className="card__content">
|
||||
<p>
|
||||
{__(
|
||||
'If your password is lost, it cannot be recovered. You will not be able to access your wallet without a password.'
|
||||
)}
|
||||
</p>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
error={understandError === true ? 'You must enter "I understand"' : false}
|
||||
label={__('Enter "I understand"')}
|
||||
type="text"
|
||||
name="wallet-understand"
|
||||
onChange={event => this.onChangeUnderstandConfirm(event)}
|
||||
/>
|
||||
</FormRow>
|
||||
<div className="card__actions" />
|
||||
{failMessage && <div className="error-text">{__(failMessage)}</div>}
|
||||
</section>
|
||||
<Form className="card__content" onSubmit={() => this.submitEncryptForm()}>
|
||||
<p>
|
||||
{__(
|
||||
'Encrypting your wallet will require a password to access your local wallet data when LBRY starts. Please enter a new password for your wallet.'
|
||||
)}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
label={__('Learn more')}
|
||||
href="https://lbry.io/faq/wallet-encryption"
|
||||
/>.
|
||||
</p>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
autoFocus
|
||||
error={passwordMismatch === true ? 'Passwords do not match' : false}
|
||||
label={__('Password')}
|
||||
placeholder={__('Shh...')}
|
||||
type="password"
|
||||
name="wallet-new-password"
|
||||
onChange={event => this.onChangeNewPassword(event)}
|
||||
/>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
error={passwordMismatch === true ? 'Passwords do not match' : false}
|
||||
label={__('Confirm Password')}
|
||||
placeholder={__('Your eyes only')}
|
||||
type="password"
|
||||
name="wallet-new-password-confirm"
|
||||
onChange={event => this.onChangeNewPasswordConfirm(event)}
|
||||
/>
|
||||
</fieldset-section>
|
||||
|
||||
<div className="help help--warning">
|
||||
{__(
|
||||
'If your password is lost, it cannot be recovered. You will not be able to access your wallet without a password.'
|
||||
)}
|
||||
</div>
|
||||
<FormField
|
||||
error={understandError === true ? 'You must enter "I understand"' : false}
|
||||
label={__('Enter "I understand"')}
|
||||
placeholder={__('Dear computer, I understand')}
|
||||
type="text"
|
||||
name="wallet-understand"
|
||||
onChange={event => this.onChangeUnderstandConfirm(event)}
|
||||
/>
|
||||
{failMessage && <div className="error-text">{__(failMessage)}</div>}
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { Form, FormRow, FormField } from 'component/common/form';
|
||||
import { Form, FormField } from 'component/common/form';
|
||||
import { Modal } from 'modal/modal';
|
||||
import Button from 'component/button';
|
||||
|
||||
|
@ -57,17 +57,14 @@ class ModalWalletUnlock extends React.PureComponent<Props> {
|
|||
href="https://lbry.io/faq/wallet-encryption"
|
||||
/>.
|
||||
</p>
|
||||
<FormRow padded>
|
||||
<FormField
|
||||
stretch
|
||||
autoFocus
|
||||
error={walletUnlockSucceded === false ? 'Incorrect Password' : false}
|
||||
label={__('Wallet Password')}
|
||||
type="password"
|
||||
name="wallet-password"
|
||||
onChange={event => this.onChangePassword(event)}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
autoFocus
|
||||
error={walletUnlockSucceded === false ? 'Incorrect Password' : false}
|
||||
label={__('Wallet Password')}
|
||||
type="password"
|
||||
name="wallet-password"
|
||||
onChange={event => this.onChangePassword(event)}
|
||||
/>
|
||||
</Form>
|
||||
</section>
|
||||
</Modal>
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as icons from 'constants/icons';
|
|||
import * as MODALS from 'constants/modal_types';
|
||||
import React from 'react';
|
||||
import BusyIndicator from 'component/common/busy-indicator';
|
||||
import { FormField, FormRow } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import ReactPaginate from 'react-paginate';
|
||||
import SubscribeButton from 'component/subscribeButton';
|
||||
import Page from 'component/page';
|
||||
|
@ -108,7 +108,7 @@ class ChannelPage extends React.PureComponent<Props> {
|
|||
|
||||
{(!fetching || (claimsInChannel && claimsInChannel.length)) &&
|
||||
totalPages > 1 && (
|
||||
<FormRow verticallyCentered centered>
|
||||
<React.Fragment>
|
||||
<ReactPaginate
|
||||
pageCount={totalPages}
|
||||
pageRangeDisplayed={2}
|
||||
|
@ -132,7 +132,7 @@ class ChannelPage extends React.PureComponent<Props> {
|
|||
prefix={__('Go to page:')}
|
||||
type="text"
|
||||
/>
|
||||
</FormRow>
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
{!channelIsMine && <HiddenNsfwClaims className="card__content help" uri={uri} />}
|
||||
|
|
|
@ -226,7 +226,7 @@ class HelpPage extends React.PureComponent<Props, State> {
|
|||
|
||||
<div className="card__content">
|
||||
{this.state.uiVersion && ver ? (
|
||||
<table className="table table--stretch table--help">
|
||||
<table className="table table--stretch">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{__('App')}</td>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import { FormRow, FormField } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import { Lbry, doToast } from 'lbry-redux';
|
||||
import Page from 'component/page';
|
||||
|
||||
|
@ -56,19 +56,18 @@ class ReportPage extends React.Component {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="textarea"
|
||||
rows="10"
|
||||
name="message"
|
||||
stretch
|
||||
value={this.state.message}
|
||||
onChange={event => {
|
||||
this.onMessageChange(event);
|
||||
}}
|
||||
placeholder={__('Description of your issue or feature request')}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormField
|
||||
type="textarea"
|
||||
rows="10"
|
||||
name="message"
|
||||
stretch
|
||||
value={this.state.message}
|
||||
onChange={event => {
|
||||
this.onMessageChange(event);
|
||||
}}
|
||||
placeholder={__('Description of your issue or feature request')}
|
||||
/>
|
||||
|
||||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as SETTINGS from 'constants/settings';
|
|||
import * as ICONS from 'constants/icons';
|
||||
import * as React from 'react';
|
||||
import { isURIValid, normalizeURI, parseURI } from 'lbry-redux';
|
||||
import { FormField, FormRow } from 'component/common/form';
|
||||
import { FormField } from 'component/common/form';
|
||||
import FileTile from 'component/fileTile';
|
||||
import ChannelTile from 'component/channelTile';
|
||||
import FileListSearch from 'component/fileListSearch';
|
||||
|
@ -49,49 +49,50 @@ class SearchPage extends React.PureComponent<Props> {
|
|||
return (
|
||||
<Page noPadding>
|
||||
<section className="search">
|
||||
{query && isValid && (
|
||||
<header className="search__header">
|
||||
<h1 className="search__title">
|
||||
{`lbry://${query}`}
|
||||
<ToolTip
|
||||
icon
|
||||
body={__('This is the resolution of a LBRY URL and not controlled by LBRY Inc.')}
|
||||
>
|
||||
<Icon icon={ICONS.HELP} />
|
||||
</ToolTip>
|
||||
</h1>
|
||||
{isChannel ? (
|
||||
<ChannelTile size="large" uri={uri} />
|
||||
) : (
|
||||
<FileTile size="large" displayHiddenMessage uri={uri} />
|
||||
)}
|
||||
</header>
|
||||
)}
|
||||
{query &&
|
||||
isValid && (
|
||||
<header className="search__header">
|
||||
<h1 className="search__title">
|
||||
{`lbry://${query}`}
|
||||
<ToolTip
|
||||
icon
|
||||
body={__(
|
||||
'This is the resolution of a LBRY URL and not controlled by LBRY Inc.'
|
||||
)}
|
||||
>
|
||||
<Icon icon={ICONS.HELP} />
|
||||
</ToolTip>
|
||||
</h1>
|
||||
{isChannel ? (
|
||||
<ChannelTile size="large" uri={uri} />
|
||||
) : (
|
||||
<FileTile size="large" displayHiddenMessage uri={uri} />
|
||||
)}
|
||||
</header>
|
||||
)}
|
||||
|
||||
<div className="search__results-wrapper">
|
||||
<FormRow alignRight>
|
||||
<FormField
|
||||
type="number"
|
||||
name="result_count"
|
||||
min={10}
|
||||
max={1000}
|
||||
value={resultCount}
|
||||
onChange={this.onSearchResultCountChange}
|
||||
postfix={__('returned results')}
|
||||
/>
|
||||
{
|
||||
// Removing this for now, it currently doesn't do anything but ideally it would
|
||||
// display content that we don't think is currently available to download
|
||||
// It is like a "display all" setting
|
||||
// <FormField
|
||||
// type="checkbox"
|
||||
// name="show_unavailable"
|
||||
// onChange={this.onShowUnavailableChange}
|
||||
// checked={showUnavailable}
|
||||
// postfix={__('Include unavailable content')}
|
||||
// />
|
||||
}
|
||||
</FormRow>
|
||||
<FormField
|
||||
type="number"
|
||||
name="result_count"
|
||||
min={10}
|
||||
max={1000}
|
||||
value={resultCount}
|
||||
onChange={this.onSearchResultCountChange}
|
||||
postfix={__('returned results')}
|
||||
/>
|
||||
{
|
||||
// Removing this for now, it currently doesn't do anything but ideally it would
|
||||
// display content that we don't think is currently available to download
|
||||
// It is like a "display all" setting
|
||||
// <FormField
|
||||
// type="checkbox"
|
||||
// name="show_unavailable"
|
||||
// onChange={this.onShowUnavailableChange}
|
||||
// checked={showUnavailable}
|
||||
// postfix={__('Include unavailable content')}
|
||||
// />
|
||||
}
|
||||
<FileListSearch query={query} />
|
||||
<div className="help">{__('These search results are provided by LBRY, Inc.')}</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import * as ICONS from 'constants/icons';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import * as React from 'react';
|
||||
import { FormField, FormFieldPrice, FormRow } from 'component/common/form';
|
||||
import { FormField, FormFieldPrice, Form } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import Page from 'component/page';
|
||||
import FileSelector from 'component/common/file-selector';
|
||||
|
@ -53,19 +53,12 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
clearingCache: false,
|
||||
};
|
||||
|
||||
(this: any).onDownloadDirChange = this.onDownloadDirChange.bind(this);
|
||||
(this: any).onKeyFeeChange = this.onKeyFeeChange.bind(this);
|
||||
(this: any).onKeyFeeDisableChange = this.onKeyFeeDisableChange.bind(this);
|
||||
(this: any).onInstantPurchaseMaxChange = this.onInstantPurchaseMaxChange.bind(this);
|
||||
(this: any).onShowNsfwChange = this.onShowNsfwChange.bind(this);
|
||||
(this: any).onShareDataChange = this.onShareDataChange.bind(this);
|
||||
(this: any).onThemeChange = this.onThemeChange.bind(this);
|
||||
(this: any).onAutomaticDarkModeChange = this.onAutomaticDarkModeChange.bind(this);
|
||||
(this: any).onAutoplayChange = this.onAutoplayChange.bind(this);
|
||||
(this: any).clearCache = this.clearCache.bind(this);
|
||||
(this: any).onDesktopNotificationsChange = this.onDesktopNotificationsChange.bind(this);
|
||||
(this: any).onAutoDownloadChange = this.onAutoDownloadChange.bind(this);
|
||||
// (this: any).onLanguageChange = this.onLanguageChange.bind(this)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
@ -73,18 +66,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
this.props.updateWalletStatus();
|
||||
}
|
||||
|
||||
onRunOnStartChange(event: SyntheticInputEvent<*>) {
|
||||
this.setDaemonSetting('run_on_startup', event.target.checked);
|
||||
}
|
||||
|
||||
onShareDataChange(event: SyntheticInputEvent<*>) {
|
||||
this.setDaemonSetting('share_usage_data', event.target.checked);
|
||||
}
|
||||
|
||||
onDownloadDirChange(newDirectory: string) {
|
||||
this.setDaemonSetting('download_dir', newDirectory);
|
||||
}
|
||||
|
||||
onKeyFeeChange(newValue: Price) {
|
||||
this.setDaemonSetting('max_key_fee', newValue);
|
||||
}
|
||||
|
@ -107,10 +88,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
this.props.setClientSetting(SETTINGS.AUTOMATIC_DARK_MODE_ENABLED, value);
|
||||
}
|
||||
|
||||
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
||||
this.props.setClientSetting(SETTINGS.AUTOPLAY, event.target.checked);
|
||||
}
|
||||
|
||||
onInstantPurchaseEnabledChange(enabled: boolean) {
|
||||
this.props.setClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED, enabled);
|
||||
}
|
||||
|
@ -119,14 +96,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
this.props.setClientSetting(SETTINGS.INSTANT_PURCHASE_MAX, newValue);
|
||||
}
|
||||
|
||||
onShowNsfwChange(event: SyntheticInputEvent<*>) {
|
||||
this.props.setClientSetting(SETTINGS.SHOW_NSFW, event.target.checked);
|
||||
}
|
||||
|
||||
onAutoDownloadChange(event: SyntheticInputEvent<*>) {
|
||||
this.props.setClientSetting(SETTINGS.AUTO_DOWNLOAD, event.target.checked);
|
||||
}
|
||||
|
||||
onChangeEncryptWallet() {
|
||||
const { decryptWallet, walletEncrypted, encryptWallet } = this.props;
|
||||
if (walletEncrypted) {
|
||||
|
@ -136,10 +105,6 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
onDesktopNotificationsChange(event: SyntheticInputEvent<*>) {
|
||||
this.props.setClientSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED, event.target.checked);
|
||||
}
|
||||
|
||||
setDaemonSetting(name: string, value: ?SetDaemonSettingArg): void {
|
||||
this.props.setDaemonSetting(name, value);
|
||||
}
|
||||
|
@ -170,6 +135,8 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
walletEncrypted,
|
||||
osNotificationsEnabled,
|
||||
autoDownload,
|
||||
setDaemonSetting,
|
||||
setClientSetting,
|
||||
} = this.props;
|
||||
|
||||
const noDaemonSettings = !daemonSettings || Object.keys(daemonSettings).length === 0;
|
||||
|
@ -193,11 +160,13 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FileSelector
|
||||
type="openDirectory"
|
||||
currentPath={daemonSettings.download_dir}
|
||||
onFileChosen={this.onDownloadDirChange}
|
||||
/>
|
||||
<Form>
|
||||
<FileSelector
|
||||
type="openDirectory"
|
||||
currentPath={daemonSettings.download_dir}
|
||||
onFileChosen={this.onDownloadDirChange}
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
@ -211,30 +180,34 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
</p>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormField
|
||||
type="radio"
|
||||
name="no_max_purchase_limit"
|
||||
checked={disableMaxKeyFee}
|
||||
postfix={__('No Limit')}
|
||||
onChange={() => {
|
||||
this.onKeyFeeDisableChange(true);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="max_purchase_limit"
|
||||
checked={!disableMaxKeyFee}
|
||||
onChange={() => {
|
||||
this.onKeyFeeDisableChange(false);
|
||||
this.onKeyFeeChange(defaultMaxKeyFee);
|
||||
}}
|
||||
postfix={__('Choose limit')}
|
||||
/>
|
||||
<Form className="card__content">
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="no_max_purchase_no_limit"
|
||||
checked={disableMaxKeyFee}
|
||||
label={__('No Limit')}
|
||||
onChange={() => {
|
||||
this.onKeyFeeDisableChange(true);
|
||||
}}
|
||||
/>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="max_purchase_limit"
|
||||
checked={!disableMaxKeyFee}
|
||||
onChange={() => {
|
||||
this.onKeyFeeDisableChange(false);
|
||||
this.onKeyFeeChange(defaultMaxKeyFee);
|
||||
}}
|
||||
label={__('Choose limit')}
|
||||
/>
|
||||
</fieldset-section>
|
||||
|
||||
{!disableMaxKeyFee && (
|
||||
<FormFieldPrice
|
||||
name="max_key_fee"
|
||||
label="Max purchase price"
|
||||
min={0}
|
||||
onChange={this.onKeyFeeChange}
|
||||
price={
|
||||
|
@ -242,7 +215,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -255,34 +228,38 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
</p>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormField
|
||||
type="radio"
|
||||
name="confirm_all_purchases"
|
||||
checked={!instantPurchaseEnabled}
|
||||
postfix={__('Always confirm before purchasing content')}
|
||||
onChange={() => {
|
||||
this.onInstantPurchaseEnabledChange(false);
|
||||
}}
|
||||
/>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="instant_purchases"
|
||||
checked={instantPurchaseEnabled}
|
||||
postfix={__('Only confirm purchases over a certain price')}
|
||||
onChange={() => {
|
||||
this.onInstantPurchaseEnabledChange(true);
|
||||
}}
|
||||
/>
|
||||
<Form className="card__content">
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="confirm_all_purchases"
|
||||
checked={!instantPurchaseEnabled}
|
||||
label={__('Always confirm before purchasing content')}
|
||||
onChange={() => {
|
||||
this.onInstantPurchaseEnabledChange(false);
|
||||
}}
|
||||
/>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="instant_purchases"
|
||||
checked={instantPurchaseEnabled}
|
||||
label={__('Only confirm purchases over a certain price')}
|
||||
onChange={() => {
|
||||
this.onInstantPurchaseEnabledChange(true);
|
||||
}}
|
||||
/>
|
||||
</fieldset-section>
|
||||
{instantPurchaseEnabled && (
|
||||
<FormFieldPrice
|
||||
label={__('Confirmation price')}
|
||||
name="confirmation_price"
|
||||
min={0.1}
|
||||
onChange={this.onInstantPurchaseMaxChange}
|
||||
price={instantPurchaseMax}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -290,36 +267,38 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
<h2 className="card__title">{__('Content Settings')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<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>
|
||||
<Form className="card__content">
|
||||
<FormField
|
||||
type="setting"
|
||||
name="show_nsfw"
|
||||
onChange={() => setClientSetting(SETTINGS.SHOW_NSFW, !showNsfw)}
|
||||
checked={showNsfw}
|
||||
label={__('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. '
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Notifications')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<Form className="card__content">
|
||||
<FormField
|
||||
type="checkbox"
|
||||
type="setting"
|
||||
name="desktopNotification"
|
||||
onChange={this.onDesktopNotificationsChange}
|
||||
onChange={() =>
|
||||
setClientSetting(SETTINGS.OS_NOTIFICATIONS_ENABLED, !osNotificationsEnabled)
|
||||
}
|
||||
checked={osNotificationsEnabled}
|
||||
postfix={__('Show Desktop Notifications')}
|
||||
label={__('Show Desktop Notifications')}
|
||||
helper={__(
|
||||
'Get notified when a publish is confirmed, or when new content is available to watch.'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -327,32 +306,35 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
<h2 className="card__title">{__('Share Diagnostic Data')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<Form className="card__content">
|
||||
<FormField
|
||||
type="checkbox"
|
||||
type="setting"
|
||||
name="share_usage_data"
|
||||
onChange={this.onShareDataChange}
|
||||
onChange={() =>
|
||||
setDaemonSetting('share_usage_data', !daemonSettings.share_usage_data)
|
||||
}
|
||||
checked={daemonSettings.share_usage_data}
|
||||
postfix={__(
|
||||
label={__(
|
||||
'Help make LBRY better by contributing analytics and diagnostic data about my usage.'
|
||||
)}
|
||||
helper={__(
|
||||
'You will be ineligible to earn rewards while diagnostics are not being shared.'
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
<header className="card__header">
|
||||
<h2 className="card__title">{__('Theme')}</h2>
|
||||
<h2 className="card__title">{__('Appearance')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormRow>
|
||||
<Form className="card__content">
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
name="theme_select"
|
||||
type="select"
|
||||
label={__('Theme')}
|
||||
onChange={this.onThemeChange}
|
||||
value={currentTheme}
|
||||
disabled={automaticDarkModeEnabled}
|
||||
|
@ -363,17 +345,18 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
</option>
|
||||
))}
|
||||
</FormField>
|
||||
</FormRow>
|
||||
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="automatic_dark_mode"
|
||||
onChange={e => this.onAutomaticDarkModeChange(e.target.checked)}
|
||||
checked={automaticDarkModeEnabled}
|
||||
disabled={isDarkModeEnabled}
|
||||
postfix={__('Automatic dark mode (9pm to 8am)')}
|
||||
/>
|
||||
</div>
|
||||
</fieldset-section>
|
||||
<fieldset-section>
|
||||
<FormField
|
||||
type="setting"
|
||||
name="automatic_dark_mode"
|
||||
onChange={() => this.onAutomaticDarkModeChange(!automaticDarkModeEnabled)}
|
||||
checked={automaticDarkModeEnabled}
|
||||
disabled={isDarkModeEnabled}
|
||||
label={__('Automatic dark mode (9pm to 8am)')}
|
||||
/>
|
||||
</fieldset-section>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -381,13 +364,13 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
<h2 className="card__title">{__('Wallet Security')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<Form className="card__content">
|
||||
<FormField
|
||||
type="checkbox"
|
||||
type="setting"
|
||||
name="encrypt_wallet"
|
||||
onChange={() => this.onChangeEncryptWallet()}
|
||||
checked={walletEncrypted}
|
||||
postfix={__('Encrypt my wallet with a custom password.')}
|
||||
label={__('Encrypt my wallet with a custom password.')}
|
||||
helper={
|
||||
<React.Fragment>
|
||||
{__('Secure your local wallet data with a custom password.')}{' '}
|
||||
|
@ -401,7 +384,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -409,32 +392,29 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
<h2 className="card__title">{__('Experimental Settings')}</h2>
|
||||
</header>
|
||||
|
||||
<div className="card__content">
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="auto_download"
|
||||
onChange={this.onAutoDownloadChange}
|
||||
checked={autoDownload}
|
||||
postfix={__('Automatically download new content from my subscriptions')}
|
||||
helper={__(
|
||||
"The latest file from each of your subscriptions will be downloaded for quick access as soon as it's published."
|
||||
)}
|
||||
/>
|
||||
</FormRow>
|
||||
<FormRow>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
name="autoplay"
|
||||
onChange={this.onAutoplayChange}
|
||||
checked={autoplay}
|
||||
postfix={__('Autoplay media files')}
|
||||
helper={__(
|
||||
'Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.'
|
||||
)}
|
||||
/>
|
||||
</FormRow>
|
||||
</div>
|
||||
<Form className="card__content">
|
||||
<FormField
|
||||
type="setting"
|
||||
name="auto_download"
|
||||
onChange={() => setClientSetting(SETTINGS.AUTO_DOWNLOAD, !autoDownload)}
|
||||
checked={autoDownload}
|
||||
label={__('Automatically download new content from my subscriptions')}
|
||||
helper={__(
|
||||
"The latest file from each of your subscriptions will be downloaded for quick access as soon as it's published."
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="setting"
|
||||
name="autoplay"
|
||||
onChange={() => setClientSetting(SETTINGS.AUTOPLAY, !autoplay)}
|
||||
checked={autoplay}
|
||||
label={__('Autoplay media files')}
|
||||
helper={__(
|
||||
'Autoplay video and audio files when navigating to a file, as well as the next related item when a file finishes playing.'
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
</section>
|
||||
|
||||
<section className="card card--section">
|
||||
|
@ -450,7 +430,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
|
|||
button="primary"
|
||||
label={this.state.clearingCache ? __('Clearing') : __('Clear Cache')}
|
||||
icon={ICONS.ALERT}
|
||||
onClick={this.clearCache}
|
||||
// onClick={this.clearCache}
|
||||
disabled={this.state.clearingCache}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -57,11 +57,12 @@ export default (props: Props) => {
|
|||
</div>
|
||||
<Tooltip onComponent body={__('Automatically download new subscriptions.')}>
|
||||
<FormField
|
||||
type="checkbox"
|
||||
type="setting"
|
||||
name="auto_download"
|
||||
onChange={onChangeAutoDownload}
|
||||
checked={autoDownload}
|
||||
prefix={__('Auto download')}
|
||||
label={__('Auto download')}
|
||||
labelOnLeft
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as ACTIONS from 'constants/action_types';
|
|||
const getCurrentPath = () => {
|
||||
const { hash } = document.location;
|
||||
if (hash !== '') return hash.replace(/^#/, '');
|
||||
return '/discover';
|
||||
return '/settings';
|
||||
};
|
||||
|
||||
const reducers = {};
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
@charset "utf-8";
|
||||
|
||||
@import '~@lbry/color/lbry-color';
|
||||
// @import "~@lbry/components/sass/index";
|
||||
// @import '~@lbry/color/lbry-color';
|
||||
@import '~@lbry/components/sass/init/_color.scss';
|
||||
@import '~@lbry/components/sass/init/_mixins.scss';
|
||||
@import '~@lbry/components/sass/init/_variables.scss';
|
||||
@import '~@lbry/components/sass/init/_reset.scss';
|
||||
@import 'init/vars';
|
||||
@import 'init/mixins';
|
||||
@import 'init/reset';
|
||||
@import 'init/type';
|
||||
@import 'init/gui';
|
||||
@import 'component/animation';
|
||||
|
@ -20,7 +22,6 @@
|
|||
@import 'component/file-download';
|
||||
@import 'component/file-render';
|
||||
@import 'component/form-field';
|
||||
@import 'component/form-row';
|
||||
@import 'component/header';
|
||||
@import 'component/item-list';
|
||||
@import 'component/load-screen';
|
||||
|
|
|
@ -1,54 +1 @@
|
|||
.badge {
|
||||
font-weight: 600;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(.badge--large) {
|
||||
border-radius: 0.2rem;
|
||||
display: inline-block;
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.05rem;
|
||||
line-height: 2;
|
||||
padding-right: var(--spacing-vertical-small);
|
||||
padding-left: var(--spacing-vertical-small);
|
||||
}
|
||||
}
|
||||
|
||||
.badge--alert {
|
||||
background-color: $lbry-red-2;
|
||||
color: $lbry-white;
|
||||
}
|
||||
|
||||
.badge--cost:not(.badge--large) {
|
||||
background-color: $lbry-yellow-2;
|
||||
color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: $lbry-yellow-3;
|
||||
color: $lbry-black;
|
||||
}
|
||||
}
|
||||
|
||||
.badge--free {
|
||||
background-color: $lbry-blue-2;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: $lbry-blue-3;
|
||||
color: $lbry-black;
|
||||
}
|
||||
}
|
||||
|
||||
.badge--large {
|
||||
font-weight: 600;
|
||||
font-size: 3.5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.badge--nsfw {
|
||||
background-color: $lbry-grape-2;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: $lbry-grape-3;
|
||||
color: $lbry-black;
|
||||
}
|
||||
}
|
||||
@import '~@lbry/components/sass/badge/_index.scss';
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
.btn {
|
||||
fill: currentColor;
|
||||
position: relative;
|
||||
@import '~@lbry/components/sass/button/_index.scss';
|
||||
|
||||
.button {
|
||||
border-radius: 0;
|
||||
|
||||
svg {
|
||||
stroke-width: 1.9;
|
||||
|
@ -19,123 +20,60 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn__label {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
svg + .btn__label {
|
||||
svg + .button__label {
|
||||
margin-left: var(--spacing-vertical-small);
|
||||
}
|
||||
}
|
||||
|
||||
.btn--alt {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
&.button--icon {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--constrict {
|
||||
@include constrict;
|
||||
}
|
||||
|
||||
.btn--disabled {
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.btn--external-link,
|
||||
.btn--link {
|
||||
transition: color 0.2s;
|
||||
|
||||
&:not(.btn--disabled):not(:hover) {
|
||||
color: $lbry-teal-5;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
color: $lbry-teal-3;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.btn--disabled):hover {
|
||||
color: $lbry-teal-3;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
color: $lbry-teal-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn--external-link {
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
// Large icons used for play/view on the file page
|
||||
.btn--icon {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
|
||||
background-repeat: no-repeat;
|
||||
background-size: 50%;
|
||||
border-radius: 50%;
|
||||
color: $lbry-white;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:not(:hover) {
|
||||
background-color: rgba($lbry-black, 0.7);
|
||||
}
|
||||
|
||||
// The play icon looks a little weird without this
|
||||
.btn--play {
|
||||
padding-left: 0.25rem;
|
||||
}
|
||||
|
||||
.btn__label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.button--primary,
|
||||
.button--alt,
|
||||
.button--no-style {
|
||||
svg {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
|
||||
margin-right: 0;
|
||||
position: relative;
|
||||
top: 0.1rem;
|
||||
width: 1.2rem;
|
||||
height: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--inverse {
|
||||
border: 1px solid $lbry-gray-1;
|
||||
border-radius: 1rem;
|
||||
color: inherit;
|
||||
.button--inverse {
|
||||
font-size: 1rem;
|
||||
padding: var(--spacing-vertical-miniscule) var(--spacing-vertical-medium);
|
||||
transition: background-color 0.2s;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-white, 0.1);
|
||||
background-color: rgba($lbry-black, 0.3);
|
||||
}
|
||||
|
||||
&:not(:hover) {
|
||||
background-color: transparent;
|
||||
background-color: $lbry-white;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $lbry-gray-1;
|
||||
color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
color: $lbry-white;
|
||||
}
|
||||
}
|
||||
|
||||
.btn__content {
|
||||
.button__content {
|
||||
svg {
|
||||
color: $lbry-gray-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
.button--link:not(:hover):not(:disabled) {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-teal-4;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--load-screen {
|
||||
.button--load-screen {
|
||||
border-bottom: 1px solid $lbry-white;
|
||||
display: inline-block;
|
||||
|
||||
|
@ -145,31 +83,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
align-self: center; // fixes buttons next to tall elements inside one with `display: flex`
|
||||
border-radius: 1rem;
|
||||
color: $lbry-white;
|
||||
padding: var(--spacing-vertical-miniscule) var(--spacing-vertical-medium);
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:not(:hover) {
|
||||
background-color: $lbry-teal-5;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $lbry-teal-3;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: $lbry-teal-4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn--uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.btn--selected {
|
||||
.button--selected {
|
||||
font-weight: 800;
|
||||
color: $lbry-teal-5;
|
||||
|
||||
|
@ -177,7 +91,7 @@
|
|||
opacity: 1;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-teal-3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
.card {
|
||||
background-color: $lbry-white;
|
||||
border: 1px solid $lbry-gray-1;
|
||||
border-radius: 0.5rem;
|
||||
margin-bottom: var(--spacing-vertical-large);
|
||||
position: relative;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
border-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
|
@ -199,8 +198,8 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.card__title + .btn,
|
||||
.btn:not(:first-of-type) {
|
||||
.card__title + .button,
|
||||
.button:not(:first-of-type) {
|
||||
margin-left: var(--spacing-vertical-medium);
|
||||
}
|
||||
}
|
||||
|
@ -209,9 +208,4 @@
|
|||
display: flex;
|
||||
@include between;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
font-size: 1.2rem; // Don't make buttons the size of the title
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
&:hover {
|
||||
cursor: pointer;
|
||||
|
||||
.btn--view,
|
||||
.btn--play {
|
||||
.button--view,
|
||||
.button--play {
|
||||
background-color: $lbry-green-3;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
margin-bottom: var(--spacing-vertical-medium);
|
||||
padding-bottom: var(--spacing-vertical-medium);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
|||
content: '';
|
||||
position: absolute;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-image: linear-gradient(to bottom, transparent 0%, $lbry-black 90%);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
margin-top: $spacing-vertical * 2/3;
|
||||
}
|
||||
|
||||
.file-list__sort {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.file-list__header {
|
||||
font-size: 24px;
|
||||
padding-top: $spacing-vertical * 4/3;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border: 1px solid rgba($lbry-gray-1, 0.3);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
|||
.document-viewer {
|
||||
background-color: $lbry-white;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,131 +1,113 @@
|
|||
.form-field {
|
||||
&.form-field--disabled {
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
@import '~@lbry/components/sass/form/_index.scss';
|
||||
|
||||
// lbry/components overrides and minor styles
|
||||
|
||||
checkbox-element,
|
||||
radio-element,
|
||||
fieldset:last-child,
|
||||
fieldset-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-field--SimpleMDE {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
fieldset-group.fieldset-group--smushed {
|
||||
justify-content: flex-start;
|
||||
|
||||
.form-field__input {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: 1.25rem;
|
||||
fieldset-section {
|
||||
width: auto;
|
||||
margin-bottom: 0;
|
||||
|
||||
&.form-field--auto-height {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.form-field--first-item {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input {
|
||||
&.paginate-channel {
|
||||
width: 35px;
|
||||
&:first-of-type {
|
||||
input {
|
||||
border-right: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.input--thumbnail {
|
||||
width: 400px;
|
||||
&.fieldgroup--paginate {
|
||||
margin-top: var(--spacing-vertical-medium);
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.pagination {
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-field__input--level {
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.form-field__help,
|
||||
.form-field__label,
|
||||
.form-field__error {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// TODO: Refactor to remove need for `!important`
|
||||
|
||||
.form-field__error {
|
||||
color: $lbry-red-5 !important;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
color: $lbry-red-2 !important;
|
||||
// form buttons are black by default
|
||||
form {
|
||||
[data-mode='dark'] & {
|
||||
.button--primary:not(:hover) {
|
||||
background-color: $lbry-teal-5;
|
||||
border-color: $lbry-teal-5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldset-section {
|
||||
[data-mode='dark'] & {
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
color: $lbry-white;
|
||||
}
|
||||
|
||||
input:not(:focus):not(.form-field--copyable),
|
||||
textarea:not(:focus),
|
||||
select:not(:focus) {
|
||||
border-color: $lbry-white;
|
||||
}
|
||||
|
||||
input-submit {
|
||||
input,
|
||||
select {
|
||||
&:first-child:not(:focus) {
|
||||
border-right-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 12em;
|
||||
background-color: $lbry-white;
|
||||
|
||||
[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-field--copyable {
|
||||
background-color: rgba($lbry-gray-1, 0.3);
|
||||
border: 1px solid $lbry-gray-1;
|
||||
color: $lbry-gray-5;
|
||||
flex: 1;
|
||||
padding: 0.2rem 0.75rem;
|
||||
text-overflow: ellipsis;
|
||||
user-select: text;
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.3);
|
||||
border-color: $lbry-gray-5;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
label + .react-toggle,
|
||||
.react-toggle + label {
|
||||
margin-left: var(--spacing-vertical-small);
|
||||
}
|
||||
|
||||
.form-field__help {
|
||||
color: $lbry-gray-5;
|
||||
padding-top: var(--spacing-vertical-small);
|
||||
@extend .help;
|
||||
margin-top: var(--spacing-vertical-small);
|
||||
}
|
||||
|
||||
.form-field__label {
|
||||
color: inherit;
|
||||
font-size: 1.25rem;
|
||||
opacity: 0.7;
|
||||
.form-field--price-amount {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.form-field__prefix,
|
||||
.form-field__postfix {
|
||||
font-weight: 500;
|
||||
// line-height: 2;
|
||||
|
||||
&.form-field--align-center {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
&.form-field--fix-no-height {
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.form-field__prefix {
|
||||
padding-right: var(--spacing-vertical-small);
|
||||
}
|
||||
|
||||
.form-field__postfix {
|
||||
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;
|
||||
height: 2rem;
|
||||
|
||||
&::after {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
// TRIANGLE_DOWN
|
||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'%3E %3Cpath d='M3 4 L21 4 12 20 3 4 Z' stroke='black' stroke-width='2' fill='black' fill-rule='evenodd' stroke-linejoin='round'/%3E %3C/svg%3E");
|
||||
background-position: 95% center, right top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 0.8rem, 100%;
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.form-field__select {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: $lbry-gray-1;
|
||||
border-radius: 0;
|
||||
padding: 0 var(--spacing-vertical-small);
|
||||
|
||||
-webkit-appearance: none;
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.form-field--address {
|
||||
width: 370px;
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
.form-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-end;
|
||||
|
||||
&:not(.form-row--padded):not(:last-of-type) {
|
||||
margin-bottom: var(--spacing-vertical-medium);
|
||||
}
|
||||
|
||||
.form-field {
|
||||
&:not(:first-of-type) {
|
||||
padding-left: var(--spacing-vertical-medium);
|
||||
}
|
||||
|
||||
&.form-field--stretch {
|
||||
width: 100%;
|
||||
|
||||
input {
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button + input,
|
||||
input + button {
|
||||
margin-left: var(--spacing-vertical-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.form-row--centered {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form-row--padded {
|
||||
// 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 {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.form-row--stretch {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.form-row--vertically-centered {
|
||||
align-items: center;
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
position: fixed;
|
||||
z-index: 1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-black, 0.9);
|
||||
color: $lbry-white;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
|||
display: flex;
|
||||
|
||||
&:first-of-type {
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
&:not(:disabled):hover {
|
||||
background-color: $lbry-gray-1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-gray-5;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@
|
|||
}
|
||||
|
||||
.header__navigation-item--back {
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
svg {
|
||||
stroke: $lbry-white;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@
|
|||
}
|
||||
|
||||
.header__navigation-item--forward {
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
svg {
|
||||
stroke: $lbry-white;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@
|
|||
}
|
||||
|
||||
.header__navigation-item--home {
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
svg {
|
||||
stroke: $lbry-white;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@
|
|||
}
|
||||
|
||||
.header__navigation-item--menu {
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
svg {
|
||||
stroke: $lbry-white;
|
||||
}
|
||||
|
@ -116,12 +116,12 @@
|
|||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
.btn__content {
|
||||
.button__content {
|
||||
display: flex;
|
||||
padding: 0 var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
.btn__label {
|
||||
.button__label {
|
||||
line-height: 1.4;
|
||||
padding-left: 0.5rem;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@
|
|||
border-right: 1px solid $lbry-gray-1;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
svg {
|
||||
stroke: $lbry-white;
|
||||
}
|
||||
|
@ -145,11 +145,11 @@
|
|||
border-right: 1px solid $lbry-gray-1;
|
||||
width: calc(100% - (var(--header-height) * 3));
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
|
||||
.btn__content {
|
||||
.button__content {
|
||||
line-height: var(--header-height);
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
margin-top: var(--spacing-vertical-large);
|
||||
padding: var(--spacing-vertical-large);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,10 @@
|
|||
.item-list__item--cutoff {
|
||||
margin-right: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
fieldset-section {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.item-list__item--cutoff {
|
||||
|
@ -29,7 +33,7 @@
|
|||
.item-list__item--selected {
|
||||
background-color: $lbry-gray-1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-black, 0.5);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
text-decoration-style: dotted;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-left: 1px solid rgba($lbry-white, 0.2);
|
||||
border-right: 1px solid rgba($lbry-white, 0.2);
|
||||
border-bottom: 1px solid rgba($lbry-white, 0.2);
|
||||
|
@ -91,7 +91,7 @@
|
|||
border: none;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.2);
|
||||
|
||||
a {
|
||||
|
@ -124,7 +124,11 @@
|
|||
font-size: 1rem;
|
||||
padding: var(--spacing-vertical-medium) 0; // overriding styles from elsewhere
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.form-field--SimpleMDE {
|
||||
margin-top: var(--spacing-vertical-large);
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
position: relative;
|
||||
top: 1rem;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -87,10 +87,6 @@
|
|||
font-family: Consolas, 'Lucida Console', 'Source Sans', monospace;
|
||||
}
|
||||
|
||||
table {
|
||||
@extend .table;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $lbry-blue-1;
|
||||
display: inline-block;
|
||||
|
|
|
@ -221,7 +221,7 @@
|
|||
.media__subtext {
|
||||
color: rgba($lbry-black, 0.8);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: rgba($lbry-white, 0.7);
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@
|
|||
position: relative;
|
||||
|
||||
// Quick fix to fix channel overlapping on the home page. This style shouldn't exist here.
|
||||
.btn--uri-indicator {
|
||||
.button--uri-indicator {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
|
@ -262,7 +262,7 @@
|
|||
.media__info {
|
||||
word-wrap: break-word;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -271,7 +271,7 @@
|
|||
border-top: 1px solid $lbry-gray-1;
|
||||
padding-top: var(--spacing-vertical-medium);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -300,42 +300,8 @@
|
|||
.media__message {
|
||||
font-size: 1.1rem;
|
||||
padding: var(--spacing-vertical-medium);
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.media__message--help {
|
||||
background-color: $lbry-yellow-3;
|
||||
margin: var(--spacing-vertical-medium) var(--spacing-vertical-large);
|
||||
|
||||
.btn--link {
|
||||
// The normal colors we use for .btn--link are too light for the warning background
|
||||
// This just darkens them a bit and adds an border-bottom so they are easier to see.
|
||||
$altered-color: mix($lbry-teal-5, $lbry-black, 80%);
|
||||
$altered-hover-color: mix($lbry-teal-5, $lbry-black, 60%);
|
||||
|
||||
&:not(.btn--disabled) {
|
||||
color: $altered-color;
|
||||
border-bottom: 1px solid $altered-color;
|
||||
|
||||
&:hover {
|
||||
color: $altered-hover-color;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
color: $altered-color;
|
||||
border-bottom: 1px solid $altered-color;
|
||||
|
||||
&:hover {
|
||||
color: $altered-hover-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: $lbry-yellow-4;
|
||||
color: $lbry-black;
|
||||
}
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
// M E D I A
|
||||
|
@ -391,7 +357,7 @@
|
|||
.media__text {
|
||||
font-size: 2.5rem;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-white;
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +374,7 @@
|
|||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
}
|
||||
|
@ -516,7 +482,7 @@
|
|||
width: 30rem;
|
||||
padding-left: var(--spacing-vertical-large);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
|
||||
|
@ -530,7 +496,7 @@
|
|||
padding-top: var(--spacing-vertical-small);
|
||||
padding-bottom: var(--spacing-vertical-medium);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -541,7 +507,7 @@
|
|||
white-space: nowrap;
|
||||
width: 100%;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: mix($lbry-white, $lbry-gray-3, 50%);
|
||||
}
|
||||
|
||||
|
@ -549,7 +515,7 @@
|
|||
background-image: linear-gradient(to bottom right, $lbry-black, $lbry-cyan-5 80%);
|
||||
color: $lbry-white;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-image: linear-gradient(
|
||||
to bottom right,
|
||||
transparent,
|
||||
|
@ -572,7 +538,7 @@
|
|||
&:not(:first-of-type):not(:last-of-type) {
|
||||
border-bottom: 1px solid rgba($lbry-gray-1, 0.7);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.2);
|
||||
}
|
||||
}
|
||||
|
@ -588,7 +554,7 @@
|
|||
-webkit-background-clip: text;
|
||||
background-image: linear-gradient(to right, $lbry-white 80%, transparent 100%);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
mix($lbry-white, $lbry-gray-3, 50%) 80%,
|
||||
|
@ -646,7 +612,7 @@
|
|||
button:first-of-type {
|
||||
font-size: 2rem;
|
||||
|
||||
.btn__label {
|
||||
.button__label {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
position: fixed;
|
||||
z-index: 9999;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-black, 0.7);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
|||
.modal {
|
||||
background-color: $lbry-white;
|
||||
border: 1px solid $lbry-gray-3;
|
||||
border-radius: 4px;
|
||||
line-height: 1.55;
|
||||
max-width: var(--modal-width);
|
||||
overflow: auto;
|
||||
|
@ -30,7 +29,7 @@
|
|||
min-width: 500px;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-black;
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
|
@ -39,10 +38,10 @@
|
|||
margin-bottom: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
.btn.btn--alt {
|
||||
.button.button--alt {
|
||||
background-color: $lbry-white; // Set modal buttons bg color
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
padding-right: var(--spacing-vertical-small);
|
||||
position: relative;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-black;
|
||||
border-right: 1px solid $lbry-black;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
|||
position: absolute;
|
||||
z-index: 0;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-image: linear-gradient(
|
||||
to bottom right,
|
||||
transparent,
|
||||
|
@ -78,7 +78,7 @@
|
|||
&.navigation__link--active {
|
||||
color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-gray-1;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@
|
|||
&.navigation__link--guide:not(:hover) {
|
||||
color: rgba($lbry-black, 0.75);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: rgba($lbry-white, 0.75);
|
||||
}
|
||||
|
||||
|
@ -145,7 +145,7 @@
|
|||
&::before {
|
||||
background-color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-gray-1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
position: absolute;
|
||||
z-index: 0;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-black;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-black;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
::-webkit-scrollbar-thumb {
|
||||
background-color: $lbry-gray-3;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-gray-5;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
min-height: 300px;
|
||||
padding: var(--spacing-vertical-large);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
border-bottom: 1px solid rgba($lbry-white, 0.1);
|
||||
}
|
||||
|
|
|
@ -1,85 +1,18 @@
|
|||
@import '~@lbry/components/sass/table/_index.scss';
|
||||
|
||||
.table {
|
||||
max-width: 100%;
|
||||
text-align: left;
|
||||
word-wrap: break-word;
|
||||
[data-mode='dark'] & {
|
||||
background-color: transparent;
|
||||
|
||||
th,
|
||||
td {
|
||||
&:first-of-type {
|
||||
padding-left: var(--spacing-vertical-medium);
|
||||
th {
|
||||
border-bottom: 2px solid $lbry-white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
padding-top: var(--spacing-vertical-small);
|
||||
padding-bottom: var(--spacing-vertical-small);
|
||||
}
|
||||
|
||||
td {
|
||||
color: $lbry-gray-5;
|
||||
font-weight: 500;
|
||||
padding-top: var(--spacing-vertical-small);
|
||||
padding-bottom: var(--spacing-vertical-small);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
padding-right: var(--spacing-vertical-large);
|
||||
}
|
||||
|
||||
.btn:not(.btn--link) {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
&.table__item--actionable {
|
||||
span + .btn {
|
||||
margin-left: var(--spacing-vertical-small);
|
||||
}
|
||||
.btn svg {
|
||||
top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
border-bottom: 1px solid rgba($lbry-gray-1, 0.7);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
border: 1px solid $lbry-gray-1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.3);
|
||||
}
|
||||
|
||||
tr {
|
||||
padding-top: var(--spacing-vertical-small);
|
||||
padding-bottom: var(--spacing-vertical-small);
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 1px solid $lbry-gray-1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
border-color: rgba($lbry-gray-5, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(even) {
|
||||
background-color: rgba($lbry-gray-1, 0.3);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
.table__item--actionable {
|
||||
.button svg {
|
||||
top: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,14 +23,10 @@
|
|||
}
|
||||
|
||||
td:nth-of-type(2) {
|
||||
@include constrict;
|
||||
@include constrict(20vw);
|
||||
}
|
||||
}
|
||||
|
||||
.table--stretch {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table--transactions {
|
||||
td:nth-of-type(1) {
|
||||
// TX amounts
|
||||
|
|
|
@ -129,14 +129,7 @@
|
|||
line-height: 0;
|
||||
position: absolute;
|
||||
transition: opacity 0.25s;
|
||||
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
@media (max-resolution: 1dppx) {
|
||||
top: 0;
|
||||
}
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.react-toggle-track-check {
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
width: 200px;
|
||||
background-color: $lbry-white;
|
||||
border: 1px solid $lbry-gray-1;
|
||||
box-shadow: 5px 5px 5px rgba($lbry-black, 0.15);
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0 2px 5px rgba($lbry-black, 0.15);
|
||||
|
||||
&.tooltip__body--short {
|
||||
width: 110px;
|
||||
|
@ -57,7 +56,7 @@
|
|||
border-color: $tooltip-border transparent transparent transparent;
|
||||
}
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
.tooltip__body {
|
||||
border: none;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-color: $lbry-gray-5;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
|||
position: absolute;
|
||||
z-index: 1;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-gray-5;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
|||
background-color: $lbry-blue-2;
|
||||
color: $lbry-black;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-blue-4;
|
||||
color: inherit;
|
||||
}
|
||||
|
@ -43,12 +43,14 @@
|
|||
align-items: center;
|
||||
border-right: 1px solid $lbry-gray-1;
|
||||
border-left: 1px solid $lbry-gray-1;
|
||||
border-bottom: none;
|
||||
border-top: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-left: var(--spacing-vertical-large);
|
||||
transition: background-color 0.2s;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
border-right: 1px solid;
|
||||
border-left: 1px solid;
|
||||
color: $lbry-white;
|
||||
|
@ -71,7 +73,7 @@
|
|||
min-width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-gray-5;
|
||||
color: $lbry-white;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ body {
|
|||
line-height: 1.5;
|
||||
overflow: hidden;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: mix($lbry-white, $lbry-gray-3, 50%);
|
||||
}
|
||||
}
|
||||
|
@ -48,37 +48,6 @@ code {
|
|||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
input {
|
||||
&.input-copyable {
|
||||
background-color: rgba($lbry-gray-1, 0.3);
|
||||
border: 1px dashed $lbry-gray-1;
|
||||
color: $lbry-gray-5;
|
||||
flex: 1;
|
||||
padding: 0.8rem 1rem;
|
||||
text-overflow: ellipsis;
|
||||
user-select: text;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
background-color: rgba($lbry-gray-1, 0.1);
|
||||
border-color: $lbry-gray-5;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: These need to be their own styles
|
||||
&:not(.input-copyable):not(.wunderbar__input) {
|
||||
border-bottom: var(--input-border-size) solid $lbry-gray-5;
|
||||
}
|
||||
}
|
||||
|
||||
.input--price-amount {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.input--address {
|
||||
width: 370px;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
@ -112,6 +81,7 @@ input {
|
|||
|
||||
.column__item:not(:first-child) {
|
||||
padding-left: $spacing-width * 2/3;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,31 +112,66 @@ input {
|
|||
color: $lbry-red-3;
|
||||
font-weight: 600;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: $lbry-red-1;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
.help {
|
||||
.help:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.help {
|
||||
font-size: 0.9em;
|
||||
background-color: rgba($lbry-blue-1, 0.1);
|
||||
border-radius: 0.5rem;
|
||||
color: $lbry-gray-5;
|
||||
display: block;
|
||||
padding: 1rem;
|
||||
margin-top: var(--spacing-vertical-large);
|
||||
margin-bottom: var(--spacing-vertical-large);
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.help--warning {
|
||||
background-color: $lbry-yellow-3;
|
||||
color: $lbry-black;
|
||||
|
||||
.button--link {
|
||||
// The normal colors we use for .button--link are too light for the warning background
|
||||
// This just darkens them a bit and adds an border-bottom so they are easier to see.
|
||||
$altered-color: mix($lbry-teal-5, $lbry-black, 80%);
|
||||
$altered-hover-color: mix($lbry-teal-5, $lbry-black, 60%);
|
||||
|
||||
&:not(.button--disabled) {
|
||||
color: $altered-color;
|
||||
border-bottom: 1px solid $altered-color;
|
||||
|
||||
&:hover {
|
||||
color: $altered-hover-color;
|
||||
}
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
color: $altered-color;
|
||||
border-bottom: 1px solid $altered-color;
|
||||
|
||||
&:hover {
|
||||
color: $altered-hover-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
html[data-mode='dark'] & {
|
||||
background-color: $lbry-yellow-4;
|
||||
color: $lbry-black;
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: $lbry-gray-1;
|
||||
font-size: 0.8rem;
|
||||
|
@ -176,7 +181,7 @@ input {
|
|||
color: $lbry-gray-5;
|
||||
font-style: italic;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,6 @@
|
|||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@mixin constrict {
|
||||
max-width: 20vw;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@mixin ellipsis {
|
||||
// to take over for truncate on LBRY Web
|
||||
overflow: hidden;
|
||||
|
@ -36,7 +29,7 @@
|
|||
animation: pulse 2s infinite ease-in-out;
|
||||
background-color: $lbry-gray-2;
|
||||
|
||||
html[data-theme='dark'] & {
|
||||
html[data-mode='dark'] & {
|
||||
background-color: rgba($lbry-white, 0.1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
// Mozilla prefixes are unnecessary for app, necessary for LBRY Web
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
border: none;
|
||||
box-sizing: inherit;
|
||||
outline: 0 !important;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
a,
|
||||
area,
|
||||
button,
|
||||
[role='button'],
|
||||
input,
|
||||
label,
|
||||
select,
|
||||
summary,
|
||||
textarea {
|
||||
// Remove touch delay on supported devices
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul {
|
||||
list-style-position: inside;
|
||||
|
||||
> li {
|
||||
list-style-position: inside;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
label[for] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
dl {
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
dt {
|
||||
float: left;
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
dd {
|
||||
float: left;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
textarea {
|
||||
border: 1px solid $lbry-gray-2;
|
||||
padding: $spacing-vertical * 1/3;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
input {
|
||||
background-color: transparent;
|
||||
line-height: 1;
|
||||
|
||||
&::placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
&:not(:disabled) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&:not([type='checkbox']),
|
||||
&:not([type='file']),
|
||||
&:not([type='radio']),
|
||||
&:not([type='select']) {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
&:not([type='file']):not(:disabled):not(.wunderbar__input):not(.input-copyable) {
|
||||
border-bottom: var(--input-border-size) dotted $lbry-gray-5;
|
||||
}
|
||||
|
||||
&[type='checkbox']:not(:disabled),
|
||||
&[type='file']:not(:disabled),
|
||||
&[type='radio']:not(:disabled),
|
||||
&[type='select']:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&[type='file'] {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
border-bottom: var(--input-border-size) solid $lbry-gray-3;
|
||||
color: $lbry-gray-3;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-webkit-search-cancel-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
|
||||
&:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: default;
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
|
@ -35,8 +35,8 @@ $large-breakpoint: 1921px;
|
|||
--select-height: 30px;
|
||||
|
||||
// Button
|
||||
--btn-radius: 20px;
|
||||
--btn-height: 36px;
|
||||
--button-radius: 20px;
|
||||
--button-height: 36px;
|
||||
|
||||
// Header
|
||||
--header-height: 3.25rem; // 60px;
|
||||
|
|
11
yarn.lock
11
yarn.lock
|
@ -111,13 +111,10 @@
|
|||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.1.tgz#e93c13942592cf5ef01aa8297444dc192beee52f"
|
||||
|
||||
"@lbry/color@^1.0.2":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@lbry/color/-/color-1.0.3.tgz#ec22b2c48b0e358759528fb3bbe7ba468d4e41ca"
|
||||
|
||||
"@lbry/components@^1.5.1":
|
||||
version "1.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@lbry/components/-/components-1.6.3.tgz#5187736e8d51d24a4678f972d3c062d880d6d853"
|
||||
"@lbry/components@^2.2.0":
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@lbry/components/-/components-2.2.0.tgz#ce9e7667f28be832014d8f29d12796ce514ce039"
|
||||
integrity sha512-AHzc3OZw6gtKESXm0IrGNMFLoJI2JJVDokRzoyHPOdYgLqqADqekC44u8dytGdPHixBo1kZKaoS2FTTXyZpqpw==
|
||||
|
||||
"@mapbox/hast-util-table-cell-style@^0.1.3":
|
||||
version "0.1.3"
|
||||
|
|
Loading…
Add table
Reference in a new issue