remove [data-mode='dark']

This commit is contained in:
Sean Yesmunt 2019-11-22 16:13:00 -05:00
parent 4fcef383e5
commit 15815e5071
129 changed files with 1288 additions and 2062 deletions

View file

@ -67,7 +67,7 @@
"@babel/register": "^7.0.0",
"@exponent/electron-cookies": "^2.0.0",
"@hot-loader/react-dom": "^16.8",
"@lbry/components": "^2.8.0",
"@lbry/components": "^3.0.0",
"@reach/menu-button": "^0.1.18",
"@reach/rect": "^0.2.1",
"@reach/tabs": "^0.1.5",

View file

@ -820,7 +820,6 @@
"Advanced Editor": "Advanced Editor",
"If you bid more than %amount% LBC, when someone navigates to %uri%, it will load your published content. However, you can get a longer version of this URL for any bid.": "If you bid more than %amount% LBC, when someone navigates to %uri%, it will load your published content. However, you can get a longer version of this URL for any bid.",
"%nameOrTitle% has been published to lbry://%name%. Click here to view it.": "%nameOrTitle% has been published to lbry://%name%. Click here to view it.",
"Discussion": "Discussion",
"If you don't choose a file, the file from your existing claim %name% will be used": "If you don't choose a file, the file from your existing claim %name% will be used",
"To enable this feature, check 'Save Password' the next time you start the app.": "To enable this feature, check 'Save Password' the next time you start the app.",
"for adding a subscription!": "for adding a subscription!",

View file

@ -113,7 +113,7 @@ function App(props: Props) {
useEffect(() => {
// $FlowFixMe
document.documentElement.setAttribute('data-mode', theme);
document.documentElement.setAttribute('theme', theme);
}, [theme]);
useEffect(() => {

View file

@ -26,7 +26,6 @@ export default function BlockButton(props: Props) {
return permanentUrl && !claimIsMine ? (
<Button
ref={blockRef}
iconColor="red"
icon={ICONS.BLOCK}
button={'alt'}
label={blockedOverride || blockLabel}

View file

@ -25,7 +25,6 @@ type Props = {
button: ?string, // primary, secondary, alt, link
iconSize?: number,
iconColor?: string,
constrict: ?boolean, // to shorten the button and ellipsis, only use for links
activeClass?: string,
innerRef: ?any,
// Events
@ -60,7 +59,6 @@ const Button = forwardRef<any, {}>((props: Props, ref: any) => {
button,
iconSize,
iconColor,
constrict,
activeClass,
emailVerified,
requiresAuth,
@ -81,7 +79,6 @@ const Button = forwardRef<any, {}>((props: Props, ref: any) => {
'button--close': button === 'close',
'button--disabled': disabled,
'button--link': button === 'link',
'button--constrict': constrict,
}
: 'button--no-style',
className

View file

@ -13,9 +13,11 @@ $transition-duration: 300ms;
z-index: $base-zindex;
vertical-align: top;
opacity: 0;
border-radius: var(--border-radius);
}
.ff-canvas {
border-radius: var(--border-radius);
display: inline-block;
position: absolute;
top: 0;

View file

@ -27,13 +27,13 @@ function ChannelContent(props: Props) {
{showAbout && (
<Fragment>
{description && (
<div className="media__info-text media__info-text--small">
<div className="media__info-text media__info-text--constrained">
<MarkdownPreview content={description} promptLinks />
</div>
)}
{email && (
<Fragment>
<div className="media__info-title">{__('Contact')}</div>
<label>{__('Contact')}</label>
<div className="media__info-text">
<MarkdownPreview content={formatEmail(email)} promptLinks />
</div>
@ -41,7 +41,7 @@ function ChannelContent(props: Props) {
)}
{website && (
<Fragment>
<div className="media__info-title">{__('Site')}</div>
<label>{__('Site')}</label>
<div className="media__info-text">
<MarkdownPreview content={website} promptLinks />
</div>

View file

@ -42,7 +42,7 @@ function ChannelContent(props: Props) {
{!fetching && !hasContent && !channelIsBlocked && !channelIsBlackListed && (
<div className="card--section">
<h2 className="help">{__("This channel hasn't uploaded anything.")}</h2>
<h2 className="section__subtitle">{__("This channel hasn't uploaded anything.")}</h2>
</div>
)}

View file

@ -3,9 +3,9 @@ import React, { useState } from 'react';
import { FormField } from 'component/common/form';
import Button from 'component/button';
import SelectAsset from 'component/selectAsset';
import TagsSelect from 'component/tagsSelect';
import * as PAGES from 'constants/pages';
import { MINIMUM_PUBLISH_BID } from 'constants/claim';
import TagsSearch from 'component/tagsSearch';
type Props = {
claim: ChannelClaim,
@ -173,13 +173,16 @@ function ChannelForm(props: Props) {
disabled={false}
onChange={text => setParams({ ...params, description: text })}
/>
<TagsSelect
title={__('Add Tags')}
<TagsSearch
suggestMature
disableAutoFocus
help={__('The better your tags are, the easier it will be for people to discover your channel.')}
empty={__('No tags added')}
placeholder={__('Add a tag')}
disabledAutoFocus
tagsPassedIn={params.tags || []}
label={__('Tags Selected')}
onRemove={clickedTag => {
const newTags = params.tags.slice().filter(tag => tag.name !== clickedTag.name);
setParams({ ...params, tags: newTags });
}}
onSelect={newTags => {
newTags.forEach(newTag => {
if (!params.tags.map(savedTag => savedTag.name).includes(newTag.name)) {
@ -190,11 +193,6 @@ function ChannelForm(props: Props) {
}
});
}}
onRemove={clickedTag => {
const newTags = params.tags.slice().filter(tag => tag.name !== clickedTag.name);
setParams({ ...params, tags: newTags });
}}
tagsChosen={params.tags || []}
/>
<div className={'card__actions'}>
<Button button="primary" label={__('Submit')} onClick={handleSubmit} />

View file

@ -18,7 +18,7 @@ function ChannelThumbnail(props: Props) {
// Generate a random color class based on the first letter of the channel name
const { channelName } = parseURI(uri);
const initializer = channelName.charCodeAt(0) - 65; // will be between 0 and 57
const colorClassName = `channel-thumbnail__default--${initializer % 4}`;
const colorClassName = `channel-thumbnail__default--${Math.abs(initializer % 4)}`;
const showThumb = !obscure && !!thumbnail;
return (
<div

View file

@ -121,7 +121,13 @@ export default function ClaimList(props: Props) {
{urisLength > 0 && (
<ul className="ul--no-style">
{sortedUris.map((uri, index) => (
<ClaimPreview key={uri} uri={uri} type={type} showUserBlocked={showHiddenByUser} />
<ClaimPreview
key={uri}
uri={uri}
type={type}
properties={type !== 'small' ? undefined : false}
showUserBlocked={showHiddenByUser}
/>
))}
</ul>
)}

View file

@ -234,9 +234,9 @@ function ClaimListDiscover(props: Props) {
</FormField>
{!hideCustomization && (
<Fragment>
<span>{__('For')}</span>
<span className="claim-list__conjuction">{__('for')}</span>
{!personalView && tags && tags.length ? (
tags.map(tag => <Tag key={tag} name={tag} disabled />)
tags.map(tag => <Tag key={tag} name={tag} disabled type="large" />)
) : (
<FormField
type="select"

View file

@ -49,6 +49,7 @@ type Props = {
actions: boolean | Node | string | number,
properties: boolean | Node | string | number,
onClick?: any => any,
hideBlock?: boolean,
};
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -77,6 +78,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
actions,
properties,
onClick,
hideBlock,
} = props;
const shouldFetch =
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
@ -184,6 +186,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
'claim-preview--large': type === 'large',
'claim-preview--inline': type === 'inline',
'claim-preview--tooltip': type === 'tooltip',
'claim-preview--channel': isChannel,
'claim-preview--visited': !isChannel && !claimIsMine && hasVisitedUri,
'claim-preview--pending': pending,
})}
@ -203,7 +206,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
{isChannel && !channelIsBlocked && !claimIsMine && (
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
)}
{isChannel && !isSubscribed && !claimIsMine && (
{!hideBlock && isChannel && !isSubscribed && !claimIsMine && (
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
)}
{!isChannel && claim && <FileProperties uri={uri} />}

View file

@ -1,5 +1,6 @@
// @flow
import React from 'react';
import classnames from 'classnames';
import { clipboard } from 'electron';
import Button from 'component/button';
@ -7,14 +8,15 @@ type Props = {
shortUrl: ?string,
uri: string,
doToast: ({ message: string }) => void,
inline?: boolean,
};
function ClaimUri(props: Props) {
const { shortUrl, uri, doToast } = props;
const { shortUrl, uri, doToast, inline = false } = props;
return (
<Button
className="media__uri"
className={classnames('media__uri', { 'media__uri--inline': inline })}
button="alt"
label={shortUrl || uri}
onClick={() => {

View file

@ -18,11 +18,16 @@ function Comment(props: Props) {
return (
<li className="comment">
<div className="comment__meta">
<Button
className="button--uri-indicator truncated-text comment__author"
navigate={authorUri}
label={author || __('Anonymous')}
/>
{!author ? (
<span className="comment__author">{__('Anonymous')}</span>
) : (
<Button
className="button--uri-indicator truncated-text comment__author"
navigate={authorUri}
label={author}
/>
)}
<time className="comment__time" dateTime={timePosted}>
{relativeDate(timePosted)}
</time>

View file

@ -10,19 +10,21 @@ type Props = {
body?: string | Node,
actions?: string | Node,
icon?: string,
className?: string,
actionIconPadding?: boolean,
};
export default function Card(props: Props) {
const { title, subtitle, body, actions, icon } = props;
const { title, subtitle, body, actions, icon, className, actionIconPadding = true } = props;
return (
<section className={classnames('card')}>
<section className={classnames(className, 'card')}>
{title && (
<div className="card__header">
<div className="section__flex">
{icon && <Icon sectionIcon icon={icon} />}
<div>
<h2 className="section__title">{title}</h2>
<div className="section__subtitle">{subtitle}</div>
{subtitle && <div className="section__subtitle">{subtitle}</div>}
</div>
</div>
</div>
@ -30,7 +32,11 @@ export default function Card(props: Props) {
{body && <div className={classnames('card__body', { 'card__body--with-icon': icon })}>{body}</div>}
{actions && (
<div className={classnames('card__main-actions', { 'card__main-actions--with-icon': icon })}>{actions}</div>
<div
className={classnames('card__main-actions', { 'card__main-actions--with-icon': icon && actionIconPadding })}
>
{actions}
</div>
)}
</section>
);

View file

@ -66,7 +66,7 @@ class FileSelector extends React.PureComponent<Props> {
readOnly="readonly"
value={placeHolder || __('Choose a file')}
inputButton={
<Button button="primary" disabled={disabled} onClick={this.fileInputButton} label={buttonLabel} />
<Button button="secondary" disabled={disabled} onClick={this.fileInputButton} label={buttonLabel} />
}
/>
<input

View file

@ -80,36 +80,24 @@ export class FormField extends React.PureComponent<Props> {
const errorMessage = typeof error === 'object' ? error.message : error;
const Wrapper = blockWrap
? ({ children: innerChildren }) => <fieldset-section>{innerChildren}</fieldset-section>
: ({ children: innerChildren }) => <React.Fragment>{innerChildren}</React.Fragment>;
? ({ children: innerChildren }) => <fieldset-section class="radio">{innerChildren}</fieldset-section>
: ({ children: innerChildren }) => <span className="radio">{innerChildren}</span>;
let input;
if (type) {
if (type === 'radio') {
input = (
<Wrapper>
<radio-element>
<input id={name} type="radio" {...inputProps} />
<label htmlFor={name}>{label}</label>
<radio-toggle onClick={inputProps.onChange} />
</radio-element>
<input id={name} type="radio" {...inputProps} />
<label htmlFor={name}>{label}</label>
</Wrapper>
);
} else if (type === 'checkbox') {
// web components treat props weird
// we need to fully remove it for proper component:attribute css styling
// $FlowFixMe
const elementProps = inputProps.disabled ? { disabled: true } : {};
input = (
<Wrapper>
<checkbox-element {...elementProps}>
<input id={name} type="checkbox" {...inputProps} tabIndex={0} />
<label htmlFor={name} tabIndex={-1}>
{label}
</label>
<checkbox-toggle onClick={inputProps.onChange} tabIndex={-1} />
</checkbox-element>
</Wrapper>
<div className="checkbox">
<input id={name} type="checkbox" {...inputProps} />
<label htmlFor={name}>{label}</label>
</div>
);
} else if (type === 'select') {
input = (
@ -172,7 +160,11 @@ export class FormField extends React.PureComponent<Props> {
input = (
<React.Fragment>
<fieldset-section>
<label htmlFor={name}>{errorMessage ? <span className="error-text">{errorMessage}</span> : label}</label>
{label && (
<label htmlFor={name}>
{errorMessage ? <span className="error-text">{errorMessage}</span> : label}
</label>
)}
{prefix && <label htmlFor={name}>{prefix}</label>}
{inner}
</fieldset-section>

View file

@ -11,7 +11,7 @@ export default function UnsupportedOnWeb(props: Props) {
return (
IS_WEB && (
<div className="card__subtitle--status">
<div className="section__subtitle--status">
{type === 'page' && __('This page is not currently supported on the web')}
{type === 'feature' && __('This feature is not currently supported on the web')}.{' '}
<Button button="link" label={__('Download the desktop app')} href="https://lbry.com/get" /> for full feature

View file

@ -9,10 +9,11 @@ type Props = {
snackMessage: ?string,
doToast: ({ message: string }) => void,
label?: string,
primaryButton?: boolean,
};
export default function CopyableText(props: Props) {
const { copyable, doToast, snackMessage, label } = props;
const { copyable, doToast, snackMessage, label, primaryButton = false } = props;
const input = useRef();
@ -43,7 +44,7 @@ export default function CopyableText(props: Props) {
onFocus={onFocus}
inputButton={
<Button
button="inverse"
button={primaryButton ? 'primary' : 'secondary'}
icon={ICONS.COPY}
onClick={() => {
copyToClipboard();

View file

@ -47,17 +47,18 @@ export default function EmbedArea(props: Props) {
label={label}
value={embedText || ''}
ref={input}
helper={
<Button
icon={ICONS.COPY}
button="link"
label={__('Copy')}
onClick={() => {
copyToClipboard();
}}
/>
}
onFocus={onFocus}
/>
<div className="card__actions card__actions--center">
<Button
icon={ICONS.COPY}
button="link"
onClick={() => {
copyToClipboard();
}}
/>
</div>
</fieldset-section>
);
}

View file

@ -23,7 +23,7 @@ export default function Expandable(props: Props) {
return (
<div ref={ref}>
{rect && rect.height > COLLAPSED_HEIGHT ? (
<div ref={ref} className="expandable">
<div ref={ref}>
<div
className={classnames({
'expandable--open': expanded,

View file

@ -22,7 +22,7 @@ class FileActions extends React.PureComponent<Props> {
{showDelete && (
<Tooltip label={__('Remove from your library')}>
<Button
button="link"
button="alt"
icon={ICONS.DELETE}
description={__('Delete')}
onClick={() => openModal(MODALS.CONFIRM_FILE_REMOVE, { uri })}
@ -31,7 +31,7 @@ class FileActions extends React.PureComponent<Props> {
)}
{!claimIsMine && (
<Tooltip label={__('Report content')}>
<Button button="link" icon={ICONS.REPORT} href={`https://lbry.com/dmca/${claimId}`} />
<Button button="alt" icon={ICONS.REPORT} href={`https://lbry.com/dmca/${claimId}`} />
</Tooltip>
)}
</React.Fragment>

View file

@ -4,8 +4,10 @@ import MarkdownPreview from 'component/common/markdown-preview';
import Button from 'component/button';
import Expandable from 'component/expandable';
import path from 'path';
import ClaimTags from 'component/claimTags';
type Props = {
uri: string,
claim: StreamClaim,
fileInfo: FileListItem,
metadata: StreamMetadata,
@ -16,7 +18,7 @@ type Props = {
class FileDetails extends PureComponent<Props> {
render() {
const { claim, contentType, fileInfo, metadata, openFolder } = this.props;
const { uri, claim, contentType, fileInfo, metadata, openFolder } = this.props;
if (!claim || !metadata) {
return <span className="empty">{__('Empty claim or metadata info.')}</span>;
@ -47,47 +49,49 @@ class FileDetails extends PureComponent<Props> {
</div>
</Fragment>
)}
<div className="media__info-title">Info</div>
<div className="media__info-text">
<div>
{__('Content-Type')}
{': '}
{mediaType}
</div>
{fileSize && (
<div>
{__('File Size')}
{': '}
{fileSize}
</div>
)}
<div>
{__('Languages')}
{': '}
{languages ? languages.join(' ') : null}
</div>
<div>
{__('License')}
{': '}
{license}
</div>
{downloadPath && (
<div>
{__('Downloaded to')}
{': '}
<Button
button="link"
className="button--download-link"
onClick={() => {
if (downloadPath) {
openFolder(downloadPath);
}
}}
label={downloadNote || downloadPath}
/>
</div>
)}
</div>
<ClaimTags uri={uri} type="large" />
<table className="table table--condensed table--fixed table--file-details">
<tbody>
<tr>
<td> {__('Content Type')}</td>
<td>{mediaType}</td>
</tr>
{fileSize && (
<tr>
<td> {__('File Size')}</td>
<td>{fileSize}</td>
</tr>
)}
{languages && (
<tr>
<td>{__('Languages')}</td>
<td>{languages.join(' ')}</td>
</tr>
)}
<tr>
<td>{__('License')}</td>
<td>{license}</td>
</tr>
{downloadPath && (
<tr>
<td>{__('Downloaded to')}</td>
<td>
{/* {downloadPath.replace(/(.{10})/g, '$1\u200b')} */}
<Button
button="link"
className="button--download-link"
onClick={() => {
if (downloadPath) {
openFolder(downloadPath);
}
}}
label={downloadNote || downloadPath.replace(/(.{10})/g, '$1\u200b')}
/>
</td>
</tr>
)}
</tbody>
</table>
</Expandable>
</Fragment>
);

View file

@ -32,7 +32,7 @@ function FileDownloadLink(props: Props) {
return (
<ToolTip label={__('Open file')}>
<Button
button="link"
button="alt"
icon={ICONS.EXTERNAL}
onClick={() => {
pause();
@ -45,7 +45,7 @@ function FileDownloadLink(props: Props) {
return (
<ToolTip label={__('Add to your library')}>
<Button
button="link"
button="alt"
icon={ICONS.DOWNLOAD}
onClick={() => {
download(uri);

View file

@ -18,10 +18,10 @@ export default function FileProperties(props: Props) {
return (
<div className="file-properties">
<FilePrice hideFree uri={uri} />
<VideoDuration uri={uri} />
{isSubscribed && <Icon tooltip icon={icons.SUBSCRIBE} />}
{!claimIsMine && downloaded && <Icon tooltip icon={icons.DOWNLOAD} />}
<FilePrice hideFree uri={uri} />
<VideoDuration className="media__subtitle" uri={uri} />
</div>
);
}

View file

@ -44,7 +44,7 @@ const Header = (props: Props) => {
} = props;
const authenticated = Boolean(email);
//on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
// on the verify page don't let anyone escape other than by closing the tab to keep session data consistent
const isVerifyPage = history.location.pathname.includes(PAGES.AUTH_VERIFY);
// Sign out if they click the "x" when they are on the password prompt
@ -78,6 +78,9 @@ const Header = (props: Props) => {
<header
className={classnames('header', {
'header--minimal': authHeader,
// @if TARGET='web'
'header--noauth-web': !authenticated,
// @endif
// @if TARGET='app'
'header--mac': IS_MAC,
// @endif
@ -118,8 +121,8 @@ const Header = (props: Props) => {
</div>
{!authHeader ? (
<div className={classnames('header__menu', { 'header__menu--small': IS_WEB && !authenticated })}>
{!IS_WEB || authenticated ? (
<div className={classnames('header__menu', { 'header__menu--with-balance': !IS_WEB || authenticated })}>
{(!IS_WEB || authenticated) && (
<Fragment>
<Menu>
<MenuButton className="header__navigation-item menu__title">{getWalletTitle()}</MenuButton>
@ -135,7 +138,7 @@ const Header = (props: Props) => {
</MenuList>
</Menu>
<Menu>
<MenuButton className="header__navigation-item menu__title">
<MenuButton className="header__navigation-item menu__title header__navigation-item--icon">
<Icon size={18} icon={ICONS.ACCOUNT} />
</MenuButton>
<MenuList className="menu__list--header">
@ -161,28 +164,28 @@ const Header = (props: Props) => {
)}
</MenuList>
</Menu>
<Menu>
<MenuButton className="header__navigation-item menu__title">
<Icon size={18} icon={ICONS.SETTINGS} />
</MenuButton>
<MenuList className="menu__list--header">
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.SETTINGS}`)}>
<Icon aria-hidden tootlip icon={ICONS.SETTINGS} />
{__('Settings')}
</MenuItem>
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.HELP}`)}>
<Icon aria-hidden icon={ICONS.HELP} />
{__('Help')}
</MenuItem>
<MenuItem className="menu__link" onSelect={handleThemeToggle}>
<Icon icon={currentTheme === 'light' ? ICONS.DARK : ICONS.LIGHT} />
{currentTheme === 'light' ? __('Dark') : __('Light')}
</MenuItem>
</MenuList>
</Menu>
</Fragment>
) : (
)}
<Menu>
<MenuButton className="header__navigation-item menu__title header__navigation-item--icon">
<Icon size={18} icon={ICONS.SETTINGS} />
</MenuButton>
<MenuList className="menu__list--header">
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.SETTINGS}`)}>
<Icon aria-hidden tootlip icon={ICONS.SETTINGS} />
{__('Settings')}
</MenuItem>
<MenuItem className="menu__link" onSelect={() => history.push(`/$/${PAGES.HELP}`)}>
<Icon aria-hidden icon={ICONS.HELP} />
{__('Help')}
</MenuItem>
<MenuItem className="menu__link" onSelect={handleThemeToggle}>
<Icon icon={currentTheme === 'light' ? ICONS.DARK : ICONS.LIGHT} />
{currentTheme === 'light' ? __('Dark') : __('Light')}
</MenuItem>
</MenuList>
</Menu>
{IS_WEB && !authenticated && (
<Button navigate={`/$/${PAGES.AUTH}`} button="primary" label={__('Sign In')} />
)}
</div>
@ -193,7 +196,7 @@ const Header = (props: Props) => {
{/* This pushes the close button to the right side */}
<span />
<Tooltip label={__('Go Back')}>
<Button icon={ICONS.REMOVE} {...closeButtonNavigationProps} />
<Button button="link" icon={ICONS.REMOVE} {...closeButtonNavigationProps} />
</Tooltip>
</div>
)

View file

@ -37,8 +37,12 @@ class InviteList extends React.PureComponent<Props> {
return (
<section className="card">
<div className="table__header">
<h2 className="card__title--between">
{__('Invite History')}
<div className="table__header-text--between">
<div>
<h2 className="card__title">{__('Invite History')}</h2>
<p className="section__subtitle">{rewardHelp}</p>
</div>
{referralReward && showClaimable && (
<RewardLink
button
@ -46,8 +50,7 @@ class InviteList extends React.PureComponent<Props> {
reward_type={rewards.TYPE_REFERRAL}
/>
)}
</h2>
<p className="section__subtitle">{rewardHelp}</p>
</div>
</div>
<table className="table section">

View file

@ -5,17 +5,18 @@ import { Form, FormField } from 'component/common/form';
import CopyableText from 'component/copyableText';
import Card from 'component/common/card';
type FormProps = {
inviteNew: string => void,
errorMessage: ?string,
isPending: boolean,
};
type FormState = {
email: string,
};
class FormInviteNew extends React.PureComponent<FormProps, FormState> {
type Props = {
errorMessage: ?string,
inviteNew: string => void,
isPending: boolean,
referralLink: string,
};
class InviteNew extends React.PureComponent<Props, FormState> {
constructor() {
super();
@ -26,7 +27,7 @@ class FormInviteNew extends React.PureComponent<FormProps, FormState> {
(this: any).handleSubmit = this.handleSubmit.bind(this);
}
handleEmailChanged(event) {
handleEmailChanged(event: any) {
this.setState({
email: event.target.value,
});
@ -38,40 +39,7 @@ class FormInviteNew extends React.PureComponent<FormProps, FormState> {
}
render() {
const { errorMessage, isPending } = this.props;
return (
<Form onSubmit={this.handleSubmit}>
<FormField
type="text"
label="Email"
placeholder="youremail@example.org"
name="email"
value={this.state.email}
error={errorMessage}
inputButton={
<Button button="inverse" type="submit" label="Invite" disabled={isPending || !this.state.email} />
}
onChange={event => {
this.handleEmailChanged(event);
}}
/>
</Form>
);
}
}
type Props = {
errorMessage: ?string,
inviteNew: string => void,
isPending: boolean,
rewardAmount: number,
referralLink: string,
};
class InviteNew extends React.PureComponent<Props> {
render() {
const { errorMessage, inviteNew, isPending, rewardAmount, referralLink } = this.props;
const { errorMessage, isPending, referralLink } = this.props;
return (
<Card
@ -79,20 +47,31 @@ class InviteNew extends React.PureComponent<Props> {
subtitle={__('When your friends start using LBRY, the network gets stronger!')}
actions={
<React.Fragment>
<FormInviteNew
errorMessage={errorMessage}
inviteNew={inviteNew}
isPending={isPending}
rewardAmount={rewardAmount}
/>
<CopyableText label={__('Or share this link with your friends')} copyable={referralLink} />
<Form onSubmit={this.handleSubmit}>
<FormField
type="text"
label="Email"
placeholder="youremail@example.org"
name="email"
value={this.state.email}
error={errorMessage}
inputButton={
<Button button="secondary" type="submit" label="Invite" disabled={isPending || !this.state.email} />
}
onChange={event => {
this.handleEmailChanged(event);
}}
/>
<p className="help">
{__('Earn')} <Button button="link" navigate="/$/rewards" label={__('rewards')} />{' '}
{__('for inviting your friends.')} {__('Read our')}{' '}
<Button button="link" label={__('FAQ')} href="https://lbry.com/faq/referrals" />{' '}
{__('to learn more about referrals')}.
</p>
<CopyableText label={__('Or share this link with your friends')} copyable={referralLink} />
<p className="help">
{__('Earn')} <Button button="link" navigate="/$/rewards" label={__('rewards')} />{' '}
{__('for inviting your friends.')} {__('Read our')}{' '}
<Button button="link" label={__('FAQ')} href="https://lbry.com/faq/referrals" />{' '}
{__('to learn more about referrals')}.
</p>
</Form>
</React.Fragment>
}
/>

View file

@ -106,7 +106,9 @@ class UserHistoryPage extends React.PureComponent<Props, State> {
) : (
<div className="main--empty">
<section className="card card--section">
<h2 className="card__title">{__('Your history is empty, what are you doing here?')}</h2>
<h2 className="card__title card__title--deprecated">
{__('Your history is empty, what are you doing here?')}
</h2>
<div className="card__actions card__actions--center">
<Button button="primary" navigate="/" label={__('Explore new content')} />

View file

@ -34,10 +34,8 @@ class NavigationHistoryItem extends React.PureComponent<Props> {
render() {
const { lastViewed, selected, onSelect, claim, uri, slim, history } = this.props;
let name;
let title;
if (claim && claim.value) {
({ name } = claim);
({ title } = claim.value);
}
@ -58,7 +56,7 @@ class NavigationHistoryItem extends React.PureComponent<Props> {
>
{!slim && <FormField checked={selected} type="checkbox" onChange={onSelect} />}
<span className="time time--ago">{moment(lastViewed).from(moment())}</span>
<Button className="item-list__element" constrict button="link" label={uri} navigate={uri} />
<Button className="item-list__element" button="link" label={uri} navigate={uri} />
<span className="item-list__element">{title}</span>
</div>
);

View file

@ -74,6 +74,7 @@ function PublishFile(props: Props) {
}
return (
<Card
actionIconPadding={false}
icon={ICONS.PUBLISH}
disabled={disabled || balance === 0}
title={title}

View file

@ -138,12 +138,12 @@ function PublishForm(props: Props) {
<Card actions={<SelectThumbnail />} />
<TagsSelect
title={__('Add Tags')}
suggestMature
disableAutoFocus
help={__('The better your tags are, the easier it will be for people to discover your content.')}
hideHeader
label={__('Selected Tags')}
empty={__('No tags added')}
placeholder={__('Add a tag')}
placeholder={__('Add a tag...')}
onSelect={newTags => {
const validatedTags = [];
newTags.forEach(newTag => {

View file

@ -28,13 +28,7 @@ function RewardAuthIntro(props: Props) {
and security updates.
</I18nMessage>
}
actions={
<Button
button="primary"
navigate={`/$/${PAGES.AUTH}?redirect=/$/${PAGES.REWARDS}`}
label={__('Unlock Rewards')}
/>
}
actions={<Button button="primary" requiresAuth label={__('Unlock Rewards')} />}
/>
);
}

View file

@ -25,14 +25,16 @@ const RewardListClaimed = (props: Props) => {
return (
<section className="card">
<header className="table__header">
<h2 className="card__title">{__('Claimed Rewards')}</h2>
<div className="table__header-text">
<h2 className="card__title card__title--deprecated">{__('Claimed Rewards')}</h2>
<p className="card__subtitle">
{__(
'Reward history is tied to your email. In case of lost or multiple wallets, your balance may differ from the amounts claimed'
)}
.
</p>
<p className="section__subtitle">
{__(
'Reward history is tied to your email. In case of lost or multiple wallets, your balance may differ from the amounts claimed'
)}
.
</p>
</div>
</header>
<table className="table table--rewards">

View file

@ -25,6 +25,7 @@ class RewardSummary extends React.Component<Props> {
tokens={{
credit_amount: <CreditAmount inheritStyle amount={unclaimedRewardAmount} precision={8} />,
}}
f
>
You have %credit_amount% in unclaimed rewards.
</I18nMessage>
@ -34,14 +35,14 @@ class RewardSummary extends React.Component<Props> {
</React.Fragment>
}
actions={
<div className="section__actions">
<React.Fragment>
<Button
button="primary"
navigate="/$/rewards"
label={hasRewards ? __('Claim Rewards') : __('View Rewards')}
/>
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/rewards" />.
</div>
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/rewards" />
</React.Fragment>
}
/>
);

View file

@ -1,6 +1,6 @@
// @flow
import * as PAGES from 'constants/pages';
import React, { useEffect, lazy, Suspense } from 'react';
import React, { useEffect, Suspense } from 'react';
import { Route, Redirect, Switch, withRouter } from 'react-router-dom';
import SettingsPage from 'page/settings';
import HelpPage from 'page/help';
@ -17,8 +17,6 @@ import InvitePage from 'page/invite';
import SearchPage from 'page/search';
import LibraryPage from 'page/library';
import WalletPage from 'page/wallet';
import WalletSendPage from 'page/walletSend';
import WalletReceivePage from 'page/walletReceive';
import TagsPage from 'page/tags';
import FollowingPage from 'page/following';
import ListBlockedPage from 'page/listBlocked';
@ -80,6 +78,7 @@ function AppRouter(props: Props) {
<Route path={`/$/${PAGES.HELP}`} exact component={HelpPage} />
<Route path={`/$/${PAGES.AUTH_VERIFY}`} exact component={SignInVerifyPage} />
<Route path={`/$/${PAGES.SEARCH}`} exact component={SearchPage} />
<Route path={`/$/${PAGES.SETTINGS}`} exact component={SettingsPage} />
<PrivateRoute {...props} path={`/$/${PAGES.INVITE}`} component={InvitePage} />
<PrivateRoute {...props} path={`/$/${PAGES.DOWNLOADED}`} component={FileListDownloaded} />
@ -87,15 +86,12 @@ function AppRouter(props: Props) {
<PrivateRoute {...props} path={`/$/${PAGES.PUBLISH}`} component={PublishPage} />
<PrivateRoute {...props} path={`/$/${PAGES.REPORT}`} component={ReportPage} />
<PrivateRoute {...props} path={`/$/${PAGES.REWARDS}`} component={RewardsPage} />
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS}`} component={SettingsPage} />
<PrivateRoute {...props} path={`/$/${PAGES.TRANSACTIONS}`} component={TransactionHistoryPage} />
<PrivateRoute {...props} path={`/$/${PAGES.LIBRARY}`} component={LibraryPage} />
<PrivateRoute {...props} path={`/$/${PAGES.ACCOUNT}`} component={AccountPage} />
<PrivateRoute {...props} path={`/$/${PAGES.FOLLOWING}`} component={FollowingPage} />
<PrivateRoute {...props} path={`/$/${PAGES.BLOCKED}`} component={ListBlockedPage} />
<PrivateRoute {...props} path={`/$/${PAGES.WALLET}`} exact component={WalletPage} />
<PrivateRoute {...props} path={`/$/${PAGES.WALLET_SEND}`} exact component={WalletSendPage} />
<PrivateRoute {...props} path={`/$/${PAGES.WALLET_RECEIVE}`} exact component={WalletReceivePage} />
<PrivateRoute {...props} path={`/$/${PAGES.CHANNELS}`} component={ChannelsPage} />
{/* Below need to go at the end to make sure we don't match any of our pages first */}

View file

@ -27,7 +27,7 @@ const SearchOptions = (props: Props) => {
{expanded && (
<Form className="search__options">
<fieldset>
<legend className="search__legend--1">{__('Search For')}</legend>
<legend className="search__legend">{__('Search For')}</legend>
{[
{
option: SEARCH_OPTIONS.INCLUDE_FILES,
@ -55,7 +55,7 @@ const SearchOptions = (props: Props) => {
</fieldset>
<fieldset>
<legend className="search__legend--2">{__('File Types')}</legend>
<legend className="search__legend">{__('File Types')}</legend>
{[
{
option: SEARCH_OPTIONS.MEDIA_VIDEO,
@ -92,7 +92,7 @@ const SearchOptions = (props: Props) => {
</fieldset>
<fieldset>
<legend className="search__legend--3">{__('Other Options')}</legend>
<legend className="search__legend">{__('Other Options')}</legend>
<FormField
type="select"
name="result-count"

View file

@ -31,7 +31,6 @@ function SideBar(props: Props) {
<div className="card navigation--placeholder">
<div className="wrap">
<h2>LBRY</h2>
<p>{__('The best decentralized content platform on the web.')}</p>
</div>
</div>

View file

@ -7,7 +7,6 @@ import EmbedArea from 'component/embedArea';
type Props = {
claim: Claim,
onDone: () => void,
webShareable: boolean,
isChannel: boolean,
};
@ -28,7 +27,7 @@ class SocialShare extends React.PureComponent<Props> {
render() {
const { claim, isChannel } = this.props;
const { canonical_url: canonicalUrl, permanent_url: permanentUrl } = claim;
const { webShareable, onDone } = this.props;
const { webShareable } = this.props;
const OPEN_URL = 'https://open.lbry.com/';
const lbryUrl = canonicalUrl ? canonicalUrl.split('lbry://')[1] : permanentUrl.split('lbry://')[1];
const lbryWebUrl = lbryUrl.replace(/#/g, ':');
@ -41,13 +40,13 @@ class SocialShare extends React.PureComponent<Props> {
return (
<React.Fragment>
<CopyableText label={__('LBRY App Link')} copyable={lbryURL} noSnackbar />
<div className="card__actions card__actions--center">
<div className="">
<Button
icon={ICONS.FACEBOOK}
button="link"
description={shareOnFb}
href={`https://facebook.com/sharer/sharer.php?u=${encodedLbryURL}`}
/>
/>{' '}
<Button
icon={ICONS.TWITTER}
button="link"
@ -56,9 +55,6 @@ class SocialShare extends React.PureComponent<Props> {
/>
</div>
{webShareable && !isChannel && <EmbedArea label={__('Embedded')} claim={claim} noSnackbar />}
<div className="card__actions">
<Button button="link" label={__('Done')} onClick={onDone} />
</div>
</React.Fragment>
);
}

View file

@ -8,6 +8,8 @@ import ModalWalletUnlock from 'modal/modalWalletUnlock';
import ModalIncompatibleDaemon from 'modal/modalIncompatibleDaemon';
import ModalUpgrade from 'modal/modalUpgrade';
import ModalDownloading from 'modal/modalDownloading';
import Card from 'component/common/card';
import I18nMessage from 'component/i18nMessage';
import 'css-doodle';
const FORTY_FIVE_SECONDS = 45 * 1000;
@ -227,7 +229,7 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
{!animationHidden && (
<css-doodle class="doodle">
{`
--color: @p(var(--lbry-teal-1), var(--lbry-orange-1), var(--lbry-cyan-3), var(--lbry-pink-5));
--color: @p(var(--color-primary), var(--color-secondary), var(--color-focus), var(--color-nothing));
:doodle {
@grid: 30x1 / 18vmin;
--deg: @p(-180deg, 180deg);
@ -267,21 +269,28 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
onClick={() => setClientSetting(SETTINGS.HIDE_SPLASH_ANIMATION, !animationHidden)}
/>
{error && (
<div className="splash__error card card--section">
<p className="card__subtitle">
{__('Uh oh. The flux in our Retro Encabulator must be out of whack. Try refreshing to fix it.')}
</p>
<div className="card__actions--center">
<Button button="primary" label={__('Refresh')} onClick={() => window.location.reload()} />
</div>
<div className="help">
<p>{__('If you still have issues, your anti-virus software or firewall may be preventing startup.')}</p>
<p>
{__('Reach out to hello@lbry.com for help, or check out')}{' '}
<Button button="link" href="https://lbry.com/faq/startup-troubleshooting" label="this link" />.
</p>
</div>
</div>
<Card
className="splash__error"
title={__('Error Starting Up')}
subtitle={
<React.Fragment>
<p>
Try refreshing to fix it. If you still have issues, your anti-virus software or firewall may be
preventing startup.
</p>
<I18nMessage
tokens={{
help_link: (
<Button button="link" href="https://lbry.com/faq/startup-troubleshooting" label="this link" />
),
}}
>
Reach out to hello@lbry.com for help, or check out %help_link%.
</I18nMessage>
</React.Fragment>
}
actions={<Button button="primary" label={__('Refresh')} onClick={() => window.location.reload()} />}
/>
)}
{/* Temp hack: don't show any modals on splash screen daemon is running;
daemon doesn't let you quit during startup, so the "Quit" buttons

View file

@ -30,6 +30,7 @@ export default function Tag(props: Props) {
disabled={disabled}
title={title}
className={classnames('tag', {
'tag--large': type === 'large',
'tag--remove': type === 'remove',
// tag--add only adjusts the color, which causes issues with mature tag color clashing
'tag--add': !isMature && type === 'add',
@ -37,7 +38,7 @@ export default function Tag(props: Props) {
})}
label={name}
iconSize={12}
iconRight={type !== 'link' && (type === 'remove' ? ICONS.REMOVE : ICONS.ADD)}
iconRight={type !== 'link' && type !== 'large' && (type === 'remove' ? ICONS.REMOVE : ICONS.ADD)}
/>
);
}

View file

@ -15,6 +15,7 @@ type Props = {
disableAutoFocus?: boolean,
onRemove: Tag => void,
placeholder?: string,
label?: string,
};
/*
@ -36,6 +37,7 @@ export default function TagsSearch(props: Props) {
suggestMature,
disableAutoFocus,
placeholder,
label,
} = props;
const [newTag, setNewTag] = useState('');
const doesTagMatch = name => {
@ -107,6 +109,7 @@ export default function TagsSearch(props: Props) {
return (
<React.Fragment>
<Form className="tags__input-wrapper" onSubmit={handleSubmit}>
<label>{label || __('Following')}</label>
<ul className="tags--remove">
{tagsPassedIn.map(tag => (
<Tag
@ -130,6 +133,7 @@ export default function TagsSearch(props: Props) {
</li>
</ul>
</Form>
<label>{__('Suggested')}</label>
<ul className="tags">
{suggestedTags.map(tag => (
<Tag key={`suggested${tag}`} name={tag} type="add" onClick={() => handleTagClick(tag)} />

View file

@ -17,11 +17,13 @@ type Props = {
// The default component is for following tags
title?: string | boolean,
help?: string,
label?: string,
tagsChosen?: Array<Tag>,
onSelect?: (Array<Tag>) => void,
onRemove?: Tag => void,
placeholder?: string,
disableAutoFocus?: boolean,
hideHeader?: boolean,
};
/*
@ -40,6 +42,8 @@ export default function TagsSelect(props: Props) {
suggestMature,
disableAutoFocus,
placeholder,
hideHeader,
label,
} = props;
const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false);
const tagsToDisplay = tagsChosen || followedTags;
@ -71,14 +75,17 @@ export default function TagsSelect(props: Props) {
return (
((showClose && !hasClosed) || !showClose) && (
<Card
actionIconPadding={false}
icon={ICONS.TAG}
title={
<React.Fragment>
{title}
{showClose && tagsToDisplay.length > 0 && !hasClosed && (
<Button button="close" icon={ICONS.REMOVE} onClick={handleClose} />
)}
</React.Fragment>
hideHeader ? null : (
<React.Fragment>
{title}
{showClose && tagsToDisplay.length > 0 && !hasClosed && (
<Button button="close" icon={ICONS.REMOVE} onClick={handleClose} />
)}
</React.Fragment>
)
}
subtitle={
help !== false && (
@ -91,6 +98,7 @@ export default function TagsSelect(props: Props) {
actions={
<React.Fragment>
<TagsSearch
label={label}
onRemove={handleTagClick}
onSelect={onSelect}
suggestMature={suggestMature && !hasMatureTag}

View file

@ -42,8 +42,8 @@ function TransactionList(props: Props) {
return (
<React.Fragment>
<header className="table__header">
<h2 className="card__title--between">
{title}
<div className="table__header-text--between">
<h2 className="card__title">{title}</h2>
<div className="card__actions--inline">
<RefreshTransactionButton slim={slim} />
{/* @if TARGET='app' */}
@ -82,7 +82,7 @@ function TransactionList(props: Props) {
)}
{slim && <Button button="primary" navigate={`/$/${PAGES.TRANSACTIONS}`} label={__('Full History')} />}
</div>
</h2>
</div>
</header>
{((loading && !transactions.length) || !transactions.length) && (

View file

@ -26,9 +26,9 @@ class TransactionListItem extends React.PureComponent<Props> {
getLink(type: string) {
if (type === TXN_TYPES.TIP) {
return <Button icon={ICONS.UNLOCK} onClick={this.abandonClaim} title={__('Unlock Tip')} />;
return <Button button="secondary" icon={ICONS.UNLOCK} onClick={this.abandonClaim} title={__('Unlock Tip')} />;
}
return <Button icon={ICONS.DELETE} onClick={this.abandonClaim} title={__('Abandon Claim')} />;
return <Button button="secondary" icon={ICONS.DELETE} onClick={this.abandonClaim} title={__('Abandon Claim')} />;
}
abandonClaim() {
@ -65,13 +65,15 @@ class TransactionListItem extends React.PureComponent<Props> {
return (
<tr>
<td>
<CreditAmount badge={false} showPlus amount={amount} precision={8} />
<br />
{fee !== 0 && (
<span className="table__item-label">
<CreditAmount badge={false} fee amount={fee} precision={8} />
</span>
{date ? (
<div>
<DateTime date={date} show={DateTime.SHOW_DATE} formatOptions={dateFormat} />
<div className="table__item-label">
<DateTime date={date} show={DateTime.SHOW_TIME} />
</div>
</div>
) : (
<span className="empty">{__('Pending')}</span>
)}
</td>
<td className="table__item--actionable">
@ -85,16 +87,14 @@ class TransactionListItem extends React.PureComponent<Props> {
<td>
<ButtonTransaction id={txid} />
</td>
<td>
{date ? (
<div>
<DateTime date={date} show={DateTime.SHOW_DATE} formatOptions={dateFormat} />
<div className="table__item-label">
<DateTime date={date} show={DateTime.SHOW_TIME} />
</div>
</div>
) : (
<span className="empty">{__('Pending')}</span>
<td className="table__item--align-right">
<CreditAmount badge={false} showPlus amount={amount} precision={8} />
<br />
{fee !== 0 && (
<span className="table__item-label">
<CreditAmount badge={false} fee amount={fee} precision={8} />
</span>
)}
</td>
</tr>

View file

@ -36,11 +36,11 @@ function TransactionListTable(props: Props) {
<table className="table table--transactions">
<thead>
<tr>
<th>{__('Amount')}</th>
<th>{__('Date')}</th>
<th>{__('Type')} </th>
<th>{__('Details')} </th>
<th>{__('Transaction')}</th>
<th>{__('Date')}</th>
<th className="table__item--align-right">{__('Amount')}</th>
</tr>
</thead>
<tbody>

View file

@ -45,7 +45,7 @@ class TransactionRefreshButton extends PureComponent<Props, State> {
const { fetchingTransactions } = this.props;
const { label, disabled } = this.state;
return (
<Button button="link" label={label} onClick={this.handleClick} disabled={disabled || fetchingTransactions} />
<Button button="secondary" label={label} onClick={this.handleClick} disabled={disabled || fetchingTransactions} />
);
}
}

View file

@ -59,7 +59,7 @@ function UserEmail(props: Props) {
/>
</React.Fragment>
}
inputButton={<UserSignOutButton button="inverse" />}
inputButton={<UserSignOutButton button="secondary" />}
value={email || ''}
/>
) : (

View file

@ -72,7 +72,12 @@ function UserEmailNew(props: Props) {
<I18nMessage
tokens={{
terms: (
<Button button="link" href="https://www.lbry.com/termsofservice" label={__('Terms of Service')} />
<Button
tabIndex="2"
button="link"
href="https://www.lbry.com/termsofservice"
label={__('Terms of Service')}
/>
),
}}
>

View file

@ -83,7 +83,7 @@ class UserPhoneNew extends React.PureComponent<Props, State> {
return (
<React.Fragment>
<p className="card__subtitle">
<p className="section__subtitle">
{__(
'Enter your phone number and we will send you a verification code. We will not share your phone number with third parties.'
)}

View file

@ -1,6 +1,5 @@
// @flow
import React from 'react';
import * as ICONS from 'constants/icons';
import Button from 'component/button';
import CopyableText from 'component/copyableText';
import QRCode from 'component/common/qr-code';
@ -11,7 +10,6 @@ type Props = {
receiveAddress: string,
getNewAddress: () => void,
gettingNewAddress: boolean,
history: { goBack: () => void },
};
type State = {
@ -45,26 +43,26 @@ class WalletAddress extends React.PureComponent<Props, State> {
}
render() {
const { receiveAddress, getNewAddress, gettingNewAddress, history } = this.props;
const { receiveAddress, getNewAddress, gettingNewAddress } = this.props;
const { showQR } = this.state;
return (
<Card
title={
<React.Fragment>
{__('Receive Credits')}
<Button button="close" icon={ICONS.REMOVE} onClick={() => history.goBack()} />
</React.Fragment>
}
title={__('Receive Credits')}
subtitle={__('Use this address to receive LBC.')}
actions={
<React.Fragment>
<CopyableText label={__('Your Address')} copyable={receiveAddress} snackMessage={__('Address copied.')} />
<CopyableText
primaryButton
label={__('Your Address')}
copyable={receiveAddress}
snackMessage={__('Address copied.')}
/>
<div className="card__actions">
{!IS_WEB && (
<Button
button="inverse"
button="secondary"
label={__('Get New Address')}
onClick={getNewAddress}
disabled={gettingNewAddress}

View file

@ -6,6 +6,7 @@ import {
selectSupportsBalance,
selectTipsBalance,
} from 'lbry-redux';
import { doOpenModal } from 'redux/actions/app';
import { selectClaimedRewards } from 'lbryinc';
import WalletBalance from './view';
@ -18,4 +19,9 @@ const select = state => ({
rewards: selectClaimedRewards(state),
});
export default connect(select)(WalletBalance);
export default connect(
select,
{
doOpenModal,
}
)(WalletBalance);

View file

@ -1,6 +1,6 @@
// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import * as MODALS from 'constants/modal_types';
import React from 'react';
import CreditAmount from 'component/common/credit-amount';
import Button from 'component/button';
@ -12,10 +12,11 @@ type Props = {
claimsBalance: number,
supportsBalance: number,
tipsBalance: number,
doOpenModal: string => void,
};
const WalletBalance = (props: Props) => {
const { balance, claimsBalance, supportsBalance, tipsBalance } = props;
const { balance, claimsBalance, supportsBalance, tipsBalance, doOpenModal } = props;
return (
<React.Fragment>
@ -27,8 +28,13 @@ const WalletBalance = (props: Props) => {
</span>
<div className="section__actions">
<Button button="inverse" icon={ICONS.SEND} label={__('Send Credits')} navigate={`$/${PAGES.WALLET_SEND}`} />
<Button button="inverse" label={__('Your Address')} navigate={`$/${PAGES.WALLET_RECEIVE}`} />
<Button button="primary" label={__('Your Address')} onClick={() => doOpenModal(MODALS.WALLET_RECEIVE)} />
<Button
button="secondary"
icon={ICONS.SEND}
label={__('Send Credits')}
onClick={() => doOpenModal(MODALS.WALLET_SEND)}
/>
</div>
</div>

View file

@ -1,6 +1,5 @@
// @flow
import * as MODALS from 'constants/modal_types';
import * as ICONS from 'constants/icons';
import React from 'react';
import Button from 'component/button';
import { Form, FormField } from 'component/common/form';
@ -16,7 +15,6 @@ type DraftTransaction = {
type Props = {
openModal: (id: string, { address: string, amount: number }) => void,
balance: number,
history: { goBack: () => void },
};
class WalletSend extends React.PureComponent<Props> {
@ -36,16 +34,11 @@ class WalletSend extends React.PureComponent<Props> {
}
render() {
const { balance, history } = this.props;
const { balance } = this.props;
return (
<Card
title={
<React.Fragment>
{__('Send Credits')}
<Button button="close" icon={ICONS.REMOVE} onClick={() => history.goBack()} />
</React.Fragment>
}
title={__('Send Credits')}
subtitle={__('Send LBC to your friends or favorite creators.')}
actions={
<Formik

View file

@ -370,11 +370,10 @@ export default class Autocomplete extends React.Component {
const matchedItem = this.getFilteredItems(props)[index];
if (value !== '' && matchedItem) {
const itemValue = getItemValue(matchedItem);
const itemValueDoesMatch =
itemValue.toLowerCase().includes(
value.toLowerCase()
// below line is the the only thing that is changed from the real component
);
const itemValueDoesMatch = itemValue.toLowerCase().includes(
value.toLowerCase()
// below line is the the only thing that is changed from the real component
);
if (itemValueDoesMatch) {
return { highlightedIndex: index };
}

View file

@ -31,7 +31,7 @@ export default class extends React.PureComponent<Props> {
<img alt="Friendly gerbil" className={classnames('yrbl', className)} src={`${image}`} />
{title && subtitle && (
<div className="yrbl__content">
<h2 className="card__title">{title}</h2>
<h2 className="card__title card__title--deprecated">{title}</h2>
<p>{subtitle}</p>
</div>
)}

View file

@ -29,3 +29,5 @@ export const WALLET_DECRYPT = 'wallet_decrypt';
export const WALLET_UNLOCK = 'wallet_unlock';
export const WALLET_SYNC = 'wallet_sync';
export const WALLET_PASSWORD_UNSAVE = 'wallet_password_unsave';
export const WALLET_SEND = 'wallet_send';
export const WALLET_RECEIVE = 'wallet_receive';

View file

@ -21,7 +21,5 @@ export const SEARCH = 'search';
export const TRANSACTIONS = 'transactions';
export const TAGS = 'tags';
export const WALLET = 'wallet';
export const WALLET_SEND = 'wallet/send';
export const WALLET_RECEIVE = 'wallet/receive';
export const BLOCKED = 'blocked';
export const CHANNELS = 'channels';

View file

@ -1,5 +1,6 @@
// @flow
// These should probably just be combined into one modal component
import * as ICONS from 'constants/icons';
import * as React from 'react';
import ReactModal from 'react-modal';
import Button from 'component/button';
@ -50,12 +51,15 @@ export class Modal extends React.PureComponent<ModalProps> {
<ReactModal
{...modalProps}
onRequestClose={onAborted || onConfirmed}
className={classnames('card modal', className)}
className={classnames('modal', className, {
'modal--card-internal': type === 'card',
})}
overlayClassName="modal-overlay"
>
{title && <h1 className="card__title">{title}</h1>}
{title && <h1 className="card__title card__title--deprecated">{title}</h1>}
{type === 'card' && <Button button="close" icon={ICONS.REMOVE} onClick={onAborted} />}
{children}
{type === 'custom' ? null : ( // custom modals define their own buttons
{type === 'custom' || type === 'card' ? null : ( // custom modals define their own buttons
<div className="card__actions">
<Button
button="primary"

View file

@ -39,7 +39,7 @@ class ModalAffirmPurchase extends React.PureComponent<Props> {
onConfirmed={this.onAffirmPurchase}
onAborted={cancelPurchase}
>
<p className="card__subtitle">
<p className="section__subtitle">
{__('This will purchase')} <strong>{title ? `"${title}"` : uri}</strong> {__('for')}{' '}
<strong>
<FilePrice uri={uri} showFullPrice inheritStyle showLBC={false} />

View file

@ -22,8 +22,11 @@ function ModalAutoGenerateThumbnail(props: Props) {
function uploadImage() {
const imageBuffer = captureSnapshot();
// $FlowFixMe
const file = new File([imageBuffer], 'thumbnail.png', { type: 'image/png' });
if (imageBuffer) {
// $FlowFixMe
upload(file);
closeModal();
} else {
@ -75,7 +78,7 @@ function ModalAutoGenerateThumbnail(props: Props) {
onConfirmed={uploadImage}
onAborted={closeModal}
>
<p className="card__subtitle">{__('Pause at any time to select a thumbnail from your video')}.</p>
<p className="section__subtitle">{__('Pause at any time to select a thumbnail from your video')}.</p>
<video ref={playerRef} src={videoSrc} onLoadedMetadata={resize} onError={onError} controls />
</Modal>
);

View file

@ -27,6 +27,8 @@ import ModalWalletUnlock from 'modal/modalWalletUnlock';
import ModalRewardCode from 'modal/modalRewardCode';
import ModalPasswordUnsave from 'modal/modalPasswordUnsave';
import ModalCommentAcknowledgement from 'modal/modalCommentAcknowledgement';
import ModalWalletSend from 'modal/modalWalletSend';
import ModalWalletReceive from 'modal/modalWalletReceive';
type Props = {
modal: { id: string, modalProps: {} },
@ -99,6 +101,10 @@ function ModalRouter(props: Props) {
return <ModalRewardCode {...modalProps} />;
case MODALS.COMMENT_ACKNOWEDGEMENT:
return <ModalCommentAcknowledgement {...modalProps} />;
case MODALS.WALLET_SEND:
return <ModalWalletSend {...modalProps} />;
case MODALS.WALLET_RECEIVE:
return <ModalWalletReceive {...modalProps} />;
default:
return null;
}

View file

@ -14,8 +14,8 @@ class ModalSocialShare extends React.PureComponent<Props> {
render() {
const { closeModal, uri, webShareable, isChannel } = this.props;
return (
<Modal isOpen onAborted={closeModal} type="custom" title={__('Share')}>
<SocialShare uri={uri} onDone={closeModal} webShareable={webShareable} isChannel={isChannel} />
<Modal isOpen onAborted={closeModal} onConfirmed={closeModal} title={__('Share')}>
<SocialShare uri={uri} webShareable={webShareable} isChannel={isChannel} />
</Modal>
);
}

View file

@ -150,7 +150,7 @@ class ModalWalletEncrypt extends React.PureComponent<Props, State> {
/>
</fieldset-section>
<div className="card__subtitle--status">
<div className="section__subtitle--status">
{__(
'If your password is lost, it cannot be recovered. You will not be able to access your wallet without a password.'
)}

View file

@ -1,9 +1,12 @@
import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import WalletReceive from './view';
const select = state => ({});
const perform = dispatch => ({});
const perform = {
doHideModal,
};
export default connect(
select,

View file

@ -0,0 +1,16 @@
// @flow
import React from 'react';
import WalletAddress from 'component/walletAddress';
import { Modal } from 'modal/modal';
type Props = { doHideModal: () => void };
const WalletAddressPage = (props: Props) => {
const { doHideModal } = props;
return (
<Modal isOpen type="card" onAborted={doHideModal}>
<WalletAddress />
</Modal>
);
};
export default WalletAddressPage;

View file

@ -1,9 +1,12 @@
import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app';
import WalletSend from './view';
const select = state => ({});
const perform = dispatch => ({});
const perform = {
doHideModal,
};
export default connect(
select,

View file

@ -0,0 +1,16 @@
// @flow
import React from 'react';
import WalletSend from 'component/walletSend';
import { Modal } from 'modal/modal';
type Props = { doHideModal: () => void };
const WalletSendModal = (props: Props) => {
const { doHideModal } = props;
return (
<Modal isOpen type="card" onAborted={doHideModal}>
<WalletSend />
</Modal>
);
};
export default WalletSendModal;

View file

@ -1,6 +1,6 @@
import React from 'react';
import WalletAddress from 'component/walletAddress';
import Page from 'component/page';
import WalletAddress from './node_modules/component/walletAddress';
import Page from './node_modules/component/page';
const WalletAddressPage = () => (
<Page className="main--contained">

View file

@ -0,0 +1,10 @@
import React from 'react';
import WalletSend from './node_modules/component/walletSend';
const WalletSendModal = () => (
<div>
<WalletSend />
</div>
);
export default WalletSendModal;

View file

@ -196,7 +196,7 @@ function ChannelPage(props: Props) {
)}
{editing && <img className="channel-cover__custom" src={coverPreview} />}
{/* component that offers select/upload */}
<div className="channel__primary-info ">
<div className="channel__primary-info">
{!editing && (
<ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} obscure={channelIsBlocked} />
)}
@ -207,14 +207,12 @@ function ChannelPage(props: Props) {
thumbnailPreview={thumbPreview}
/>
)}
<h1 className="channel__title">
{title || '@' + channelName}
{channelIsMine && !editing && (
<Button title={__('Edit')} onClick={() => setEditing(!editing)} icon={ICONS.EDIT} iconSize={49} />
)}
</h1>
<h1 className="channel__title">{title || '@' + channelName}</h1>
{channelIsMine && !editing && (
<Button button="alt" title={__('Edit')} onClick={() => setEditing(!editing)} icon={ICONS.EDIT} />
)}
<div className="channel__meta">
<ClaimUri uri={uri} />
<ClaimUri uri={uri} inline />
<span>
{subCount} {subCount !== 1 ? __('Subscribers') : __('Subscriber')}
<HelpLink href="https://lbry.com/faq/views" />
@ -226,7 +224,7 @@ function ChannelPage(props: Props) {
<TabList className="tabs__list--channel-page">
<Tab disabled={editing}>{__('Content')}</Tab>
<Tab>{editing ? __('Editing Your Channel') : __('About')}</Tab>
<Tab disabled={editing}>{__('Discussion')}</Tab>
<Tab disabled={editing}>{__('Comments')}</Tab>
{/* only render searchbar on content page (tab index 0 === content page) */}
{tabIndex === 0 ? (
<Form onSubmit={handleSearch} className="wunderbar--inline">

View file

@ -12,7 +12,7 @@ import Button from 'component/button';
import Page from 'component/page';
import FileDownloadLink from 'component/fileDownloadLink';
import RecommendedContent from 'component/recommendedContent';
import ClaimTags from 'component/claimTags';
import CommentsList from 'component/commentsList';
import CommentCreate from 'component/commentCreate';
import ClaimUri from 'component/claimUri';
@ -137,6 +137,8 @@ class FilePage extends React.Component<Props> {
return (
<Page className="main--file-page">
<ClaimUri uri={uri} />
<div className={`card ${FILE_WRAPPER_CLASS}`}>
{!fileInfo && insufficientCredits && (
<div className="media__insufficient-credits help--warning">
@ -153,82 +155,87 @@ class FilePage extends React.Component<Props> {
<FileViewerInitiator uri={uri} insufficientCredits={insufficientCredits} />
</div>
<div className="media__title">
<span className="media__title-price">
<FilePrice badge uri={normalizeURI(uri)} />
</span>
<h1 className="media__title-text">{title}</h1>
</div>
<div className="columns">
<div className="grid-area--info">
<h1 className="media__title media__title--large">{title}</h1>
<div className="media__subtitle">
<div className="media__actions media__actions--between">
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
<span>
{viewCount} {viewCount !== 1 ? __('Views') : __('View')}
<HelpLink href="https://lbry.com/faq/views" />
</span>
</div>
<div className="media__actions media__actions--between">
<div className="media__action-group--large">
{claimIsMine && (
<Button
button="primary"
icon={icons.EDIT}
label={__('Edit')}
navigate="/$/publish"
onClick={() => {
prepareEdit(claim, editUri, fileInfo);
}}
/>
)}
{!claimIsMine && (
<Button
button="alt"
icon={icons.TIP}
label={__('Tip')}
requiresAuth={IS_WEB}
title={__('Send a tip to this creator')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: false })}
/>
)}
{(claimIsMine || (!claimIsMine && supportOption)) && (
<Button
button="alt"
icon={icons.SUPPORT}
label={__('Support')}
requiresAuth={IS_WEB}
title={__('Support this claim')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: true })}
/>
)}
<div className="media__subtitle--between">
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
<span>
{viewCount} {viewCount !== 1 ? __('Views') : __('View')}
<HelpLink href="https://lbry.com/faq/views" />
</span>
</div>
<div className="media__actions">
<div className="section__actions">
{claimIsMine && (
<Button
button="alt"
icon={icons.SHARE}
label={__('Share')}
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })}
icon={icons.EDIT}
label={__('Edit')}
navigate="/$/publish"
onClick={() => {
prepareEdit(claim, editUri, fileInfo);
}}
/>
</div>
<div className="media__action-group--large">
{/* @if TARGET='app' */}
<FileDownloadLink uri={uri} />
{/* @endif */}
<FileActions uri={uri} claimId={claim.claim_id} />
</div>
)}
<Button
button="alt"
icon={icons.SHARE}
label={__('Share')}
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })}
/>
{!claimIsMine && (
<Button
button="alt"
icon={icons.TIP}
label={__('Tip')}
requiresAuth={IS_WEB}
title={__('Send a tip to this creator')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: false })}
/>
)}
{(claimIsMine || (!claimIsMine && supportOption)) && (
<Button
button="alt"
icon={icons.SUPPORT}
label={__('Support')}
requiresAuth={IS_WEB}
title={__('Support this claim')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: true })}
/>
)}
</div>
<div className="section__actions">
{/* @if TARGET='app' */}
<FileDownloadLink uri={uri} />
{/* @endif */}
<FileActions uri={uri} claimId={claim.claim_id} />
</div>
</div>
<hr />
<div className="section__divider">
<hr />
</div>
{channelUri ? (
<ClaimPreview uri={channelUri} type="inline" properties={false} />
<ClaimPreview uri={channelUri} type="inline" properties={false} hideBlock />
) : (
<div className="claim-preview--inline claim-preview-title">{__('Anonymous')}</div>
)}
<div className="media__info--large">
<FileDetails uri={uri} />
<ClaimTags uri={uri} type="large" />
<FileDetails uri={uri} />
<div className="section__divider">
<hr />
</div>
<div className="media__info-title">{__('Comments')}</div>
<div className="section__title--small">{__('Comments')}</div>
<section className="section">
<CommentCreate uri={uri} />
</section>
@ -237,13 +244,8 @@ class FilePage extends React.Component<Props> {
</section>
</div>
<div className="grid-area--related">
<div className="media__actions media__actions--between media__actions--nowrap">
<ClaimUri uri={uri} />
<div className="file-properties">
{nsfw && <div className="badge badge--mature">{__('Mature')}</div>}
<FilePrice badge uri={normalizeURI(uri)} />
</div>
</div>
{nsfw && <div className="badge badge--mature">{__('Mature')}</div>}
<RecommendedContent uri={uri} />
</div>
</div>

View file

@ -65,7 +65,9 @@ function FileListDownloaded(props: Props) {
) : (
<div className="main--empty">
<section className="card card--section">
<h2 className="card__title">{__("You haven't downloaded anything from LBRY yet.")}</h2>
<h2 className="card__title card__title--deprecated">
{__("You haven't downloaded anything from LBRY yet.")}
</h2>
<div className="card__actions card__actions--center">
<Button button="primary" navigate="/" label={__('Explore new content')} />
</div>

View file

@ -133,9 +133,14 @@ class HelpPage extends React.PureComponent<Props, State> {
href="https://lbry.com/faq/lbry-basics"
label={__('Read the App Basics FAQ')}
icon={icons.HELP}
button="inverse"
button="secondary"
/>
<Button
href="https://lbry.com/faq"
label={__('View all LBRY FAQs')}
icon={icons.HELP}
button="secondary"
/>
<Button href="https://lbry.com/faq" label={__('View all LBRY FAQs')} icon={icons.HELP} button="inverse" />
</div>
}
/>
@ -150,8 +155,8 @@ class HelpPage extends React.PureComponent<Props, State> {
}
actions={
<div className="section__actions">
<Button button="inverse" label={__('Join Our Chat')} icon={icons.CHAT} href="https://chat.lbry.com" />
<Button button="inverse" label={__('Email Us')} icon={icons.WEB} href="mailto:help@lbry.com" />
<Button button="secondary" label={__('Join Our Chat')} icon={icons.CHAT} href="https://chat.lbry.com" />
<Button button="secondary" label={__('Email Us')} icon={icons.WEB} href="mailto:help@lbry.com" />
</div>
}
/>
@ -159,14 +164,14 @@ class HelpPage extends React.PureComponent<Props, State> {
<Card
title={__('Report a Bug or Suggest a New Feature')}
subtitle={
<p>
<React.Fragment>
{__('Did you find something wrong? Think LBRY could add something useful and cool?')}{' '}
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/support" />.
</p>
</React.Fragment>
}
actions={
<div className="section__actions">
<Button navigate="/$/report" label={__('Help Us Out')} button="inverse" />
<Button navigate="/$/report" label={__('Submit Feedback')} button="secondary" />
</div>
}
/>
@ -175,15 +180,15 @@ class HelpPage extends React.PureComponent<Props, State> {
<Card
title={__('View your Log')}
subtitle={
<p>
<React.Fragment>
{__('Did something go wrong? Have a look in your log file, or send it to')}{' '}
<Button button="link" label={__('support')} href="https://lbry.com/faq/support" />.
</p>
</React.Fragment>
}
actions={
<div className="section__actions">
<Button button="inverse" label={__('Open Log')} onClick={() => this.openLogFile(dataDirectory)} />
<Button button="link" label={__('Open Log Folder')} onClick={() => shell.openItem(dataDirectory)} />
<Button button="secondary" label={__('Open Log')} onClick={() => this.openLogFile(dataDirectory)} />
<Button button="secondary" label={__('Open Log Folder')} onClick={() => shell.openItem(dataDirectory)} />
</div>
}
/>
@ -193,14 +198,16 @@ class HelpPage extends React.PureComponent<Props, State> {
<section className="card">
<header className="table__header">
<h2 className="section__title">{__('About')}</h2>
<div className="table__header-text">
<h2 className="section__title">{__('About')}</h2>
{this.state.upgradeAvailable !== null && this.state.upgradeAvailable && (
<p className="section__subtitle">
{__('A newer version of LBRY is available.')}{' '}
<Button button="link" href={newVerLink} label={__('Download now!')} />
</p>
)}
{this.state.upgradeAvailable !== null && this.state.upgradeAvailable && (
<p className="section__subtitle">
{__('A newer version of LBRY is available.')}{' '}
<Button button="link" href={newVerLink} label={__('Download now!')} />
</p>
)}
</div>
</header>
<table className="table table--stretch">
@ -254,7 +261,7 @@ class HelpPage extends React.PureComponent<Props, State> {
{!this.state.accessTokenHidden && accessToken && (
<div>
<p>{accessToken}</p>
<div className="alert-text">
<div className="help--warning">
{__('This is equivalent to a password. Do not post or share this.')}
</div>
</div>

View file

@ -25,8 +25,10 @@ function ListBlocked(props: Props) {
) : (
<div className="main--empty">
<section className="card card--section">
<h2 className="card__title">{__('You arent blocking any channels')}</h2>
<p className="card__subtitle">{__('When you block a channel, all content from that channel will be hidden.')}</p>
<h2 className="card__title card__title--deprecated">{__('You arent blocking any channels')}</h2>
<p className="section__subtitle">
{__('When you block a channel, all content from that channel will be hidden.')}
</p>
</section>
</div>
)}

View file

@ -1,9 +1,10 @@
import React from 'react';
import React, { Fragment } from 'react';
import Button from 'component/button';
import { FormField } from 'component/common/form';
import { doToast } from 'lbry-redux';
import { Lbryio } from 'lbryinc';
import Page from 'component/page';
import Card from 'component/common/card';
class ReportPage extends React.Component {
constructor(props) {
@ -46,58 +47,65 @@ class ReportPage extends React.Component {
render() {
return (
<Page>
<section className="card card--section">
<h2 className="card__title">{__('Report an Issue/Request a Feature')}</h2>
<p className="card__subtitle">
{__(
'Please describe the problem you experienced or the feature you want to see and any information you think might be useful to us. Links to screenshots are great!'
)}
</p>
<Card
title={__('Report an Issue/Request a Feature')}
subtitle={__(
'Please describe the problem you experienced or the feature you want to see and any information you think might be useful to us. Links to screenshots are great!'
)}
actions={
<Fragment>
<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')}
/>
<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')}
/>
<Button
button="primary"
onClick={event => {
this.submitMessage(event);
}}
className={`button-block button-primary ${this.state.submitting ? 'disabled' : ''}`}
>
{this.state.submitting ? __('Submitting...') : __('Submit Report')}
</Button>
</Fragment>
}
/>
<div className="card__actions">
<Button
button="primary"
onClick={event => {
this.submitMessage(event);
}}
className={`button-block button-primary ${this.state.submitting ? 'disabled' : ''}`}
>
{this.state.submitting ? __('Submitting...') : __('Submit Report')}
</Button>
</div>
</section>
<section className="card card--section">
<h2 className="card__title">{__('Developer?')}</h2>
<p>
{__('You can also')}{' '}
<Button
button="link"
href="https://github.com/lbryio/lbry-desktop/issues"
label={__('submit an issue on GitHub')}
/>
.
</p>
<p>
{__('Explore our')} <Button button="link" href="https://lbry.tech" label={__('technical resources')} />.
</p>
<p>
{__('Join our')} <Button button="link" href="https://discourse.lbry.com/" label={__('tech forum')} />.
</p>
</section>
<Card
title={__('Developer?')}
actions={
<Fragment>
<div className="markdown-preview">
<p>{__('You can also:')}</p>
<ul>
<li>
<Button
button="link"
href="https://github.com/lbryio/lbry-desktop/issues"
label={__('Submit an issue on GitHub')}
/>
.
</li>
<li>
{__('Explore our')}{' '}
<Button button="link" href="https://lbry.tech" label={__('technical resources')} />.
</li>
<li>
{__('Join our')} <Button button="link" href="https://forum.lbry.tech" label={__('tech forum')} />.
</li>
</ul>
</div>
</Fragment>
}
/>
</Page>
);
}

View file

@ -1,5 +1,6 @@
// @flow
import React, { PureComponent, Fragment } from 'react';
import * as PAGES from 'constants/pages';
import React, { PureComponent } from 'react';
import BusyIndicator from 'component/common/busy-indicator';
import RewardListClaimed from 'component/rewardListClaimed';
import RewardTile from 'component/rewardTile';
@ -8,6 +9,7 @@ import Page from 'component/page';
import classnames from 'classnames';
import { rewards as REWARD_TYPES } from 'lbryinc';
import RewardAuthIntro from 'component/rewardAuthIntro';
import Card from 'component/common/card';
type Props = {
doAuth: () => void,
@ -82,8 +84,8 @@ class RewardsPage extends PureComponent<Props> {
if (!IS_WEB && daemonSettings && !daemonSettings.share_usage_data) {
return (
<section className="card card--section">
<h2 className="card__title">{__('Disabled')}</h2>
<p className="card__subtitle">
<h2 className="card__title card__title--deprecated">{__('Disabled')}</h2>
<p className="section__subtitle">
{__('Rewards are currently disabled for your account. Turn on diagnostic data sharing, in')}{' '}
<Button button="link" navigate="/$/settings" label="Settings" />
{__(', in order to re-enable them.')}
@ -98,20 +100,17 @@ class RewardsPage extends PureComponent<Props> {
);
} else if (!rewards || rewards.length <= 0) {
return (
<Fragment>
<section className="card card--section">
<h2 className="card__title">{__('No Rewards Available')}</h2>
<p>
{claimed && claimed.length
? __(
"You have claimed all available rewards! We're regularly adding more so be sure to check back later."
)
: __('There are no rewards available at this time, please check back later.')}
</p>
</section>
<div className="card__list">{this.renderCustomRewardCode()}</div>
</Fragment>
<Card
title={__('No Rewards Available')}
subtitle={
claimed && claimed.length
? __(
"You have claimed all available rewards! We're regularly adding more so be sure to check back later."
)
: __('There are no rewards available at this time, please check back later.')
}
actions={<Button button="primary" navigate={`/$/${PAGES.DISCOVER}`} label={__('Go Home')} />}
/>
);
}

View file

@ -7,6 +7,7 @@ import ClaimList from 'component/claimList';
import Page from 'component/page';
import SearchOptions from 'component/searchOptions';
import Button from 'component/button';
import ClaimUri from 'component/claimUri';
type Props = {
search: string => void,
@ -41,9 +42,7 @@ export default function SearchPage(props: Props) {
<Fragment>
{isValid && (
<header className="search__header">
<Button button="alt" navigate={uri} className="media__uri--large">
{uri}
</Button>
<ClaimUri uri={uri} />
<div className="card">
<ClaimPreview uri={uri} type="large" placeholder="publish" />
</div>

View file

@ -6,9 +6,11 @@ import { doSetPlayingUri } from 'redux/actions/content';
import { makeSelectClientSetting, selectDaemonSettings, selectosNotificationsEnabled } from 'redux/selectors/settings';
import { doWalletStatus, selectWalletIsEncrypted, selectBlockedChannelsCount } from 'lbry-redux';
import SettingsPage from './view';
import { selectUserVerifiedEmail } from 'lbryinc';
const select = state => ({
daemonSettings: selectDaemonSettings(state),
isAuthenticated: selectUserVerifiedEmail(state),
showNsfw: makeSelectClientSetting(SETTINGS.SHOW_MATURE)(state),
instantPurchaseEnabled: makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_ENABLED)(state),
instantPurchaseMax: makeSelectClientSetting(SETTINGS.INSTANT_PURCHASE_MAX)(state),

View file

@ -53,6 +53,7 @@ type Props = {
clearCache: () => Promise<any>,
daemonSettings: DaemonSettings,
showNsfw: boolean,
isAuthenticated: boolean,
instantPurchaseEnabled: boolean,
instantPurchaseMax: Price,
currentTheme: string,
@ -185,6 +186,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
showNsfw,
instantPurchaseEnabled,
instantPurchaseMax,
isAuthenticated,
currentTheme,
themes,
automaticDarkModeEnabled,
@ -217,7 +219,7 @@ class SettingsPage extends React.PureComponent<Props, State> {
<Page>
{!IS_WEB && noDaemonSettings ? (
<section className="card card--section">
<div className="card__title">{__('Failed to load settings.')}</div>
<div className="card__title card__title--deprecated">{__('Failed to load settings.')}</div>
</section>
) : (
<div>
@ -410,17 +412,19 @@ class SettingsPage extends React.PureComponent<Props, State> {
}
/>
<Card
title={__('Blocked Channels')}
actions={
<p>
{__('You have')} {userBlockedChannelsCount} {__('blocked')}{' '}
{userBlockedChannelsCount === 1 && __('channel')}
{userBlockedChannelsCount !== 1 && __('channels')}.{' '}
<Button button="link" label={__('Manage')} navigate={`/$/${PAGES.BLOCKED}`} />.
</p>
}
/>
{isAuthenticated && (
<Card
title={__('Blocked Channels')}
actions={
<p>
{__('You have')} {userBlockedChannelsCount} {__('blocked')}{' '}
{userBlockedChannelsCount === 1 && __('channel')}
{userBlockedChannelsCount !== 1 && __('channels')}.{' '}
<Button button="link" label={__('Manage')} navigate={`/$/${PAGES.BLOCKED}`} />.
</p>
}
/>
)}
{/* @if TARGET='app' */}
<Card
@ -518,90 +522,98 @@ class SettingsPage extends React.PureComponent<Props, State> {
</React.Fragment>
}
/>
<Card
title={__('Wallet Security')}
actions={
<React.Fragment>
{/* @if TARGET='app' */}
<FormField
disabled
type="checkbox"
name="encrypt_wallet"
onChange={() => this.onChangeEncryptWallet()}
checked={walletEncrypted}
label={__('Encrypt my wallet with a custom password')}
helper={
<React.Fragment>
{(isAuthenticated || !IS_WEB) && (
<Card
title={__('Wallet Security')}
actions={
<React.Fragment>
{/* @if TARGET='app' */}
<FormField
disabled
type="checkbox"
name="encrypt_wallet"
onChange={() => this.onChangeEncryptWallet()}
checked={walletEncrypted}
label={__('Encrypt my wallet with a custom password')}
helper={
<React.Fragment>
<I18nMessage
tokens={{
learn_more: (
<Button
button="link"
label={__('Learn more')}
href="https://lbry.com/faq/account-sync"
/>
),
}}
>
Wallet encryption is currently unavailable until it's supported for synced accounts. It will
be added back soon. %learn_more%.
</I18nMessage>
{/* {__('Secure your local wallet data with a custom password.')}{' '}
<strong>{__('Lost passwords cannot be recovered.')} </strong>
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/wallet-encryption" />. */}
</React.Fragment>
}
/>
{walletEncrypted && this.state.storedPassword && (
<FormField
type="checkbox"
name="save_password"
onChange={this.onConfirmForgetPassword}
checked={this.state.storedPassword}
label={__('Save Password')}
helper={<React.Fragment>{__('Automatically unlock your wallet on startup')}</React.Fragment>}
/>
)}
{/* @endif */}
<FormField
type="checkbox"
name="hide_balance"
onChange={() => setClientSetting(SETTINGS.HIDE_BALANCE, !hideBalance)}
checked={hideBalance}
label={__('Hide wallet balance in header')}
/>
</React.Fragment>
}
/>
)}
{(!IS_WEB || isAuthenticated) && (
<Card
title={__('Experimental Settings')}
actions={
<React.Fragment>
<FormField
type="checkbox"
name="support_option"
onChange={() => setClientSetting(SETTINGS.SUPPORT_OPTION, !supportOption)}
checked={supportOption}
label={__('Enable claim support')}
helper={
<I18nMessage
tokens={{
learn_more: (
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/account-sync" />
discovery_link: (
<Button button="link" label={__('discovery')} href="https://lbry.com/faq/trending" />
),
vanity_names_link: (
<Button button="link" label={__('vanity names')} href="https://lbry.com/faq/naming" />
),
}}
>
Wallet encryption is currently unavailable until it's supported for synced accounts. It will
be added back soon. %learn_more%.
This will add a Support button along side tipping. Similar to tips, supports help
%discovery_link% but the LBC is returned to your wallet if revoked. Both also help secure your
%vanity_names_link%.
</I18nMessage>
{/* {__('Secure your local wallet data with a custom password.')}{' '}
<strong>{__('Lost passwords cannot be recovered.')} </strong>
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/wallet-encryption" />. */}
</React.Fragment>
}
/>
{walletEncrypted && this.state.storedPassword && (
<FormField
type="checkbox"
name="save_password"
onChange={this.onConfirmForgetPassword}
checked={this.state.storedPassword}
label={__('Save Password')}
helper={<React.Fragment>{__('Automatically unlock your wallet on startup')}</React.Fragment>}
}
/>
)}
{/* @endif */}
<FormField
type="checkbox"
name="hide_balance"
onChange={() => setClientSetting(SETTINGS.HIDE_BALANCE, !hideBalance)}
checked={hideBalance}
label={__('Hide wallet balance in header')}
/>
</React.Fragment>
}
/>
<Card
title={__('Experimental Settings')}
actions={
<React.Fragment>
<FormField
type="checkbox"
name="support_option"
onChange={() => setClientSetting(SETTINGS.SUPPORT_OPTION, !supportOption)}
checked={supportOption}
label={__('Enable claim support')}
helper={
<I18nMessage
tokens={{
discovery_link: (
<Button button="link" label={__('discovery')} href="https://lbry.com/faq/trending" />
),
vanity_names_link: (
<Button button="link" label={__('vanity names')} href="https://lbry.com/faq/naming" />
),
}}
>
This will add a Support button along side tipping. Similar to tips, supports help
%discovery_link% but the LBC is returned to your wallet if revoked. Both also help secure your
%vanity_names_link%.
</I18nMessage>
}
/>
{/* @if TARGET='app' */}
{/*
{/* @if TARGET='app' */}
{/*
Disabling below until we get downloads to work with shared subscriptions code
<FormField
type="checkbox"
@ -613,30 +625,31 @@ class SettingsPage extends React.PureComponent<Props, State> {
"The latest file from each of your subscriptions will be downloaded for quick access as soon as it's published."
)}
/> */}
<fieldset-section>
<FormField
name="max_connections"
type="select"
label={__('Max Connections')}
helper={__(
'For users with good bandwidth, try a higher value to improve streaming and download speeds. Low bandwidth users may benefit from a lower setting. Default is 4.'
)}
min={1}
max={100}
onChange={this.onMaxConnectionsChange}
value={daemonSettings.max_connections_per_download}
>
{connectionOptions.map(connectionOption => (
<option key={connectionOption} value={connectionOption}>
{connectionOption}
</option>
))}
</FormField>
</fieldset-section>
{/* @endif */}
</React.Fragment>
}
/>
<fieldset-section>
<FormField
name="max_connections"
type="select"
label={__('Max Connections')}
helper={__(
'For users with good bandwidth, try a higher value to improve streaming and download speeds. Low bandwidth users may benefit from a lower setting. Default is 4.'
)}
min={1}
max={100}
onChange={this.onMaxConnectionsChange}
value={daemonSettings.max_connections_per_download}
>
{connectionOptions.map(connectionOption => (
<option key={connectionOption} value={connectionOption}>
{connectionOption}
</option>
))}
</FormField>
</fieldset-section>
{/* @endif */}
</React.Fragment>
}
/>
)}
{/* @if TARGET='app' */}
{/* Auto launch in a hidden state doesn't work on mac https://github.com/Teamwork/node-auto-launch/issues/81 */}
@ -646,15 +659,15 @@ class SettingsPage extends React.PureComponent<Props, State> {
<Card
title={__('Application Cache')}
subtitle={
<p className="card__subtitle--status">
<p className="section__subtitle">
{__(
'This will clear the application cache. Your wallet will not be affected and you will not lose any data.'
'This will clear the application cache, and might fix issues you are having. Your wallet will not be affected. '
)}
</p>
}
actions={
<Button
button="inverse"
button="secondary"
label={this.state.clearingCache ? __('Clearing') : __('Clear Cache')}
onClick={clearCache}
disabled={this.state.clearingCache}

View file

@ -90,7 +90,7 @@ function ShowPage(props: Props) {
innerContent = (
<Page>
<section className="card card--section">
<div className="card__title">{uri}</div>
<div className="card__title card__title--deprecated">{uri}</div>
<p>
{__(
'In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.'

View file

@ -1,4 +1,5 @@
// @flow
import * as ICONS from 'constants/icons';
import React, { useRef } from 'react';
import Page from 'component/page';
import ClaimListDiscover from 'component/claimListDiscover';
@ -47,7 +48,17 @@ function TagsPage(props: Props) {
<ClaimListDiscover
tags={tags}
hiddenNsfwMessage={<HiddenNsfw type="page" />}
meta={<Button ref={buttonRef} button="link" onClick={handleFollowClick} requiresAuth={IS_WEB} label={label} />}
meta={
<Button
ref={buttonRef}
button="alt"
icon={ICONS.SUBSCRIBE}
iconColor="red"
onClick={handleFollowClick}
requiresAuth={IS_WEB}
label={label}
/>
}
/>
</Page>
);

View file

@ -1,11 +0,0 @@
import React from 'react';
import WalletSend from 'component/walletSend';
import Page from 'component/page';
const WalletSendPage = () => (
<Page className="main--contained">
<WalletSend />
</Page>
);
export default WalletSendPage;

View file

@ -1,15 +1,13 @@
@charset "utf-8";
@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 '@lbry/components/sass/index.scss';
@import 'themes/light.scss';
@import 'themes/dark.scss';
@import 'init/vars';
@import 'init/mixins';
@import 'init/type';
@import 'init/gui';
@import 'component/animation';
@import 'component/badge';
@import 'component/button';
@import 'component/card';
@import 'component/channel';
@ -23,7 +21,6 @@
@import 'component/form-field';
@import 'component/header';
@import 'component/icon';
@import 'component/item-list';
@import 'component/main';
@import 'component/markdown-editor';
@import 'component/markdown-preview';
@ -44,6 +41,5 @@
@import 'component/tabs';
@import 'component/tags';
@import 'component/time';
@import 'component/tooltip';
@import 'component/wunderbar';
@import 'component/yrbl';

View file

@ -1,39 +0,0 @@
@import '~@lbry/components/sass/badge/_index.scss';
.badge {
vertical-align: middle;
white-space: nowrap;
}
.badge--tag {
@extend .badge;
background-color: lighten($lbry-teal-5, 55%);
color: darken($lbry-teal-5, 20%);
svg {
stroke: $lbry-teal-5;
}
[data-mode='dark'] & {
color: var(--dm-color-01);
background-color: lighten(mix($lbry-black, $lbry-teal-5, 80%), 10%);
}
}
.badge--alert {
@extend .badge;
background-color: $lbry-red-2;
color: $lbry-white;
}
.badge--mature {
background-color: lighten($lbry-grape-1, 10%);
color: $lbry-black;
svg {
stroke: $lbry-black;
}
[data-mode='dark'] & {
background-color: darken(mix($lbry-grape-1, $lbry-gray-5, 50%), 20%);
}
}

View file

@ -1,88 +1,10 @@
@import '~@lbry/components/sass/button/_index.scss';
.button {
display: inline-block;
font-weight: var(--font-weight-base);
svg {
// Buttons that don't have a label
&:only-child {
color: inherit;
width: 1.3rem;
height: 1.3rem;
}
}
}
.button--primary {
background-color: $lbry-teal-5;
&:hover {
background-color: $lbry-teal-4;
}
&:active {
background-color: $lbry-teal-3;
}
&:disabled {
opacity: 0.5;
}
}
// Play/View button that is overlayed ontop of the video player
.button--icon {
height: 5rem;
width: 5rem;
border-radius: 2.5rem;
&:not(:hover) {
background-color: $lbry-teal-4;
}
}
.button--primary,
.button--inverse {
height: var(--button-height);
border-radius: var(--button-radius);
font-size: var(--font-body);
padding-top: 0;
padding-bottom: 0;
box-sizing: border-box;
}
.button--inverse {
border-color: $lbry-teal-4;
color: $lbry-teal-5;
&:hover {
color: $lbry-white;
background-color: $lbry-teal-4;
.icon {
stroke: $lbry-white;
}
}
[data-mode='dark'] & {
border-color: $lbry-teal-4;
color: $lbry-teal-3;
}
}
.button--alt {
padding: 0;
}
.button--link {
[data-mode='dark'] & {
color: $lbry-teal-4;
&:hover {
color: $lbry-teal-3;
}
}
}
.button--uri-indicator {
@extend .button--link;
max-width: 100%;
height: 1.2em;
vertical-align: text-top;
@ -90,50 +12,28 @@
text-overflow: ellipsis;
transition: color 0.2s;
&:hover {
color: $lbry-teal-5;
}
.markdown-preview & {
height: initial;
vertical-align: initial;
color: $lbry-teal-5;
&:hover {
color: $lbry-teal-3;
}
[data-mode='dark'] & {
color: $lbry-teal-4;
&:hover {
color: $lbry-teal-3;
}
}
}
}
.button--close {
z-index: 1;
position: absolute;
top: var(--spacing-miniscule);
right: var(--spacing-miniscule);
padding: 0.3rem;
transition: all var(--transition-duration) var(--transition-style);
border-radius: var(--card-radius);
color: var(--color-text);
&:hover {
background-color: $lbry-black;
color: $lbry-white;
color: var(--color-button-primary-text);
background-color: var(--color-button-primary-bg);
}
}
.button--subscribe {
vertical-align: text-top;
align-items: flex-start;
}
// Quick fix because this is a pain
// There is something weird with wrapping buttons. Some places we want to wrap and others we want to ellips
// Probably requires some nested style cleanup
.button--download-link {
.button__label {
white-space: normal;

View file

@ -1,15 +1,10 @@
.card {
background-color: $lbry-white;
background-color: var(--color-card-background);
margin-bottom: var(--spacing-large);
position: relative;
border-radius: var(--card-radius);
box-shadow: var(--card-box-shadow) $lbry-gray-1;
box-shadow: var(--card-box-shadow) var(--color-box-shadow);
overflow: hidden;
[data-mode='dark'] & {
background-color: var(--dm-color-05);
box-shadow: var(--card-box-shadow) darken($lbry-gray-1, 80%);
}
}
.card--disabled {
@ -25,30 +20,26 @@
.card--wallet-balance {
background-repeat: no-repeat;
background-size: cover;
color: $lbry-white;
color: black; //white;
justify-content: space-between;
}
.card--reward-total {
background-repeat: no-repeat;
background-size: cover;
color: $lbry-white;
font-size: var(--font-title);
color: var(--color-white); //white;
font-size: var(--font-large);
font-weight: var(--font-weight-bold);
}
.card--inline {
border: 1px solid $lbry-gray-1;
border: 1px solid black; //gray-1;
border-radius: var(--card-radius);
margin-bottom: var(--spacing-medium);
&:last-of-type {
margin-bottom: 0;
}
[data-mode='dark'] & {
border-color: var(--dm-color-03);
}
}
.card--claim-preview-wrap {
@ -57,14 +48,10 @@
min-width: 35rem;
}
// C A R D
// A C T I O N S
.card__actions {
display: flex;
align-items: center;
margin-top: var(--spacing-large);
font-size: var(--font-body);
&:only-child {
margin-top: 0;
@ -90,9 +77,6 @@
justify-content: center;
}
// C A R D
// L I S T
.card__list {
column-count: 2;
column-gap: var(--spacing-medium);
@ -104,68 +88,35 @@
}
}
// C A R D
// M E S S A G E
.card__message {
border-left: 0.5rem solid;
padding: var(--spacing-medium) var(--spacing-medium) var(--spacing-medium) var(--spacing-large);
&:not(&--error):not(&--failure):not(&--success) {
background-color: rgba($lbry-teal-1, 0.1);
border-color: $lbry-teal-3;
background-color: black; //black; //teal-1, 0.1);
border-color: black; //teal-3;
}
}
.card__message--error {
background-color: rgba($lbry-orange-1, 0.1);
border-color: $lbry-orange-3;
background-color: black; //black; //orange-1, 0.1);
border-color: black; //orange-3;
}
.card__message--failure {
background-color: rgba($lbry-red-1, 0.1);
border-color: $lbry-red-3;
background-color: black; //black; //red-1, 0.1);
border-color: black; //red-3;
}
.card__message--success {
background-color: rgba($lbry-green-1, 0.1);
border-color: $lbry-green-3;
background-color: black; //black; //green-1, 0.1);
border-color: black; //green-3;
}
// C A R D
// S U B T I T L E
.card__subtitle {
margin: var(--spacing-small) 0;
padding: var(--spacing-small);
border-radius: var(--card-radius);
font-size: var(--font-body);
background-color: rgba($lbry-blue-1, 0.1);
color: darken($lbry-gray-5, 15%);
[data-mode='dark'] & {
background-color: var(--dm-color-04);
color: inherit;
}
}
.card__subtitle--status {
@extend .card__subtitle;
background-color: $lbry-yellow-1;
[data-mode='dark'] & {
background-color: rgba($lbry-yellow-1, 0.1);
}
}
// C A R D
// T I T L E
.card__title {
display: flex;
align-items: center;
margin-bottom: var(--spacing-small);
font-size: var(--font-section-title);
font-size: var(--font-title);
font-weight: var(--font-weight-light);
& > *:not(:last-child) {
@ -173,13 +124,17 @@
}
}
.card__title.card__title--deprecated {
margin-bottom: var(--spacing-small);
}
.card__title--between {
@extend .card__title;
justify-content: space-between;
}
.card__media--nsfw {
background-color: $lbry-grape-3;
background-color: black; //grape-3;
}
.card__media--disabled {
@ -188,7 +143,11 @@
}
.card__header {
padding: var(--spacing-large);
margin: var(--spacing-medium) var(--spacing-large);
.section__subtitle {
margin-bottom: 0;
}
}
.card__body {
@ -198,14 +157,9 @@
.card__main-actions {
padding: var(--spacing-large);
background-color: var(--color-card-actions);
color: darken($lbry-gray-5, 15%);
font-size: var(--font-body);
[data-mode='dark'] & {
background-color: var(--color-card-actions--dark);
color: inherit;
}
padding-bottom: 0;
margin-bottom: var(--spacing-large);
border-top: 1px solid var(--color-border);
}
.card__body--with-icon,

View file

@ -2,13 +2,17 @@ $cover-z-index: 0;
$metadata-z-index: 1;
.channel-cover {
background-image: linear-gradient(to right, $lbry-indigo-4, $lbry-cyan-5 80%);
background-image: linear-gradient(to right, #637ad2, #318794 80%);
display: flex;
align-items: flex-end;
box-sizing: content-box;
color: $lbry-white;
color: #fff;
border-top-left-radius: var(--card-radius);
border-top-right-radius: var(--card-radius);
.button {
color: #fff;
}
}
.channel-cover__custom {
@ -37,8 +41,9 @@ $metadata-z-index: 1;
position: absolute;
height: var(--channel-thumbnail-width);
width: var(--channel-thumbnail-width);
box-shadow: 0px 8px 40px -3px $lbry-black;
box-shadow: 0px 8px 40px -3px #000;
left: var(--spacing-medium);
top: 4rem;
}
.channel-thumbnail__custom {
@ -60,16 +65,19 @@ $metadata-z-index: 1;
}
.channel-thumbnail__default--0 {
background-color: $lbry-indigo-3;
background-color: #748ffc;
}
.channel-thumbnail__default--1 {
background-color: $lbry-orange-2;
background-color: #ffa855;
}
.channel-thumbnail__default--2 {
background-color: $lbry-blue-3;
background-color: #339af0;
}
.channel-thumbnail__default--3 {
background-color: $lbry-red-1;
background-color: #ec8383;
}
.channel__primary-info {
@ -85,6 +93,7 @@ $metadata-z-index: 1;
}
.channel__title {
display: inline;
margin-right: var(--spacing-small);
overflow: hidden;
text-overflow: ellipsis;
@ -113,5 +122,6 @@ $metadata-z-index: 1;
position: absolute;
top: 0;
right: var(--spacing-medium);
margin-top: var(--spacing-medium);
z-index: $metadata-z-index;
}

View file

@ -1,9 +1,6 @@
$border-color: rgba($lbry-teal-5, 0.1);
$border-color--dark: var(--dm-color-04);
.claim-list {
.claim-preview {
border-top: 1px solid $border-color;
border-bottom: 1px solid var(--color-border);
}
}
@ -13,9 +10,10 @@ $border-color--dark: var(--dm-color-04);
min-height: 4.5rem;
padding: var(--spacing-medium);
font-size: var(--font-body);
border-bottom: 1px solid var(--color-border);
border-top-left-radius: var(--card-radius);
border-top-right-radius: var(--card-radius);
background-color: var(--color-card-actions);
& > *:not(:last-child) {
margin-right: 0.5rem;
@ -25,11 +23,6 @@ $border-color--dark: var(--dm-color-04);
margin-top: 0;
margin-bottom: 0;
}
[data-mode='dark'] & {
color: var(--dm-color-01);
background-color: var(--color-card-actions--dark);
}
}
.claim-list__header--small {
@ -41,10 +34,11 @@ $border-color--dark: var(--dm-color-04);
margin-bottom: 0;
padding: 0 var(--spacing-medium);
padding-right: var(--spacing-large);
}
[data-mode='dark'] & {
color: var(--dm-color-01);
}
.claim-list__conjuction {
color: var(--color-text-subtitle);
font-size: var(--font-small);
}
.claim-list__alt-controls {
@ -73,18 +67,12 @@ $border-color--dark: var(--dm-color-04);
flex-shrink: 0;
margin-right: var(--spacing-medium);
}
[data-mode='dark'] & {
color: $lbry-white;
border-color: $border-color--dark;
}
}
.claim-preview--large {
border: none;
padding: 0;
margin: var(--spacing-medium);
font-size: var(--font-multiplier-large);
&:hover {
background-color: transparent;
@ -98,14 +86,9 @@ $border-color--dark: var(--dm-color-04);
width: 7.5rem;
height: 7.5rem;
}
[data-mode='dark'] & {
border: none;
}
}
.claim-preview--small {
font-size: var(--font-multiplier-small);
padding: var(--spacing-small);
.media__thumb {
@ -118,14 +101,14 @@ $border-color--dark: var(--dm-color-04);
}
}
.claim-preview--channel:not(.claim-preview--inline) {
background-color: var(--color-card-background-highlighted);
}
.claim-preview--visited {
// Still keep the normal styles on hover regardless of if they have visited the claim
&:not(:hover) {
color: lighten($lbry-black, 35%);
[data-mode='dark'] & {
color: darken($lbry-white, 35%);
}
// color: lighten(black; //black, 35%);
}
}
@ -134,18 +117,14 @@ $border-color--dark: var(--dm-color-04);
opacity: 0.6;
&:hover {
background-color: $lbry-white;
[data-mode='dark'] & {
background-color: lighten($lbry-black, 5%);
}
background-color: black; //white;
}
}
.claim-preview--inline {
padding: 0;
padding-top: var(--spacing-large);
border-bottom: none;
margin-bottom: var(--spacing-medium);
.channel-thumbnail {
width: var(--channel-thumbnail-width--small);
@ -153,17 +132,10 @@ $border-color--dark: var(--dm-color-04);
}
}
.claim-preview--tooltip {
[data-mode='dark'] & {
background-color: $lbry-black;
}
}
.claim-preview-title {
font-weight: var(--font-weight-bold);
font-size: var(--font-body);
margin-right: auto;
padding-right: var(--spacing-medium);
font-size: larger;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
@ -196,7 +168,8 @@ $border-color--dark: var(--dm-color-04);
.claim-preview-properties {
align-items: flex-end;
flex: 1;
font-size: var(--font-subtext);
font-size: var(--font-small);
color: var(--color-text-subtitle);
}
.claim-upload {
@ -211,11 +184,6 @@ $border-color--dark: var(--dm-color-04);
flex-shrink: 0;
margin-right: var(--spacing-medium);
}
[data-mode='dark'] & {
color: $lbry-white;
border-color: $border-color--dark;
}
}
.claim-upload__progress--outer {
@ -223,11 +191,6 @@ $border-color--dark: var(--dm-color-04);
}
.claim-upload__progress--inner {
background: $lbry-teal-1;
background: black; //teal-1;
padding: var(--spacing-miniscule);
[data-mode='dark'] & {
background: $lbry-teal-4;
color: $lbry-white;
}
}

View file

@ -5,7 +5,7 @@
.comment {
display: flex;
flex-direction: column;
font-size: var(--font-multiplier-small);
font-size: var(--font-small);
padding: var(--spacing-small) 0 var(--spacing-small);
&:first-of-type {
@ -13,11 +13,7 @@
}
&:not(:last-of-type) {
border-bottom: 1px solid var(--lbry-gray-1);
[data-mode='dark'] & {
border-color: rgba($lbry-gray-5, 0.2);
}
border-bottom: 1px solid var(--color-border);
}
}
@ -50,5 +46,5 @@
.comment__char-count {
align-self: flex-end;
font-size: var(--font-label);
font-size: var(--font-small);
}

View file

@ -76,11 +76,6 @@
&:hover {
cursor: pointer;
.button--view,
.button--play {
background-color: $lbry-teal-2;
}
}
&:-webkit-full-screen {
@ -100,12 +95,7 @@
background-repeat: no-repeat;
background-size: 100%;
margin: auto;
background-color: $lbry-white;
[data-mode='dark'] & {
background-color: $lbry-black;
color: $lbry-white;
}
background-color: black; //white;
&:-webkit-full-screen {
width: 100%;
@ -124,5 +114,5 @@
}
.content__loading-text {
color: $lbry-white;
color: black; //white;
}

View file

@ -65,7 +65,7 @@
.cr {
&.function:hover,
&.boolean:hover {
background-color: $lbry-white;
background-color: black; //white;
}
}

View file

@ -1,12 +1,3 @@
.expandable {
margin-bottom: var(--spacing-medium);
padding-bottom: var(--spacing-medium);
[data-mode='dark'] & {
border-color: var(--dm-color-04);
}
}
.expandable--closed,
.expandable--open {
margin-bottom: var(--spacing-small);
@ -16,22 +7,6 @@
max-height: 10rem;
overflow: hidden;
position: relative;
&::after {
width: 100%;
height: 40%;
bottom: 0;
left: 0;
pointer-events: none;
background-image: linear-gradient(to bottom, transparent 0%, mix($lbry-white, $lbry-gray-1, 70%) 90%);
content: '';
position: absolute;
[data-mode='dark'] & {
background-image: linear-gradient(to bottom, transparent 0%, var(--dm-color-08) 90%);
}
}
}
.expandable--open {

View file

@ -2,14 +2,12 @@
display: flex;
position: relative;
align-items: center;
font-size: var(--font-label);
font-size: var(--font-small);
color: var(--color-text-help);
.icon {
stroke: rgba($lbry-black, 0.5);
[data-mode='dark'] & {
stroke: rgba($lbry-white, 0.7);
}
margin-bottom: -1px;
stroke: var(--color-subtitle);
}
& > *:not(:last-child) {

View file

@ -17,16 +17,16 @@
height: 100%;
object-fit: contain;
}
video {
cursor: pointer;
}
}
.file-render__viewer--document {
@extend .file-render__viewer;
overflow: auto;
background-color: $lbry-white;
[data-mode='dark'] & {
background-color: transparent;
}
background-color: var(--color-file-viewer-background);
.markdown-preview {
height: 100%;
@ -73,8 +73,8 @@
}
.CodeMirror-gutters {
background-color: $lbry-gray-1;
border-right: 1px solid $lbry-gray-2;
background-color: black; //gray-1;
border-right: 1px solid black; //gray-2;
padding-right: var(--spacing-medium);
}
@ -83,7 +83,7 @@
}
.CodeMirror-linenumber {
color: $lbry-gray-5;
color: black; //gray-5;
}
}

View file

@ -1,23 +1,3 @@
@import '~@lbry/components/sass/form/_index.scss';
// Reset lbry components style that turns buttons inside of forms black
form {
.button--primary,
[type='submit'] {
&:not(:hover),
&:hover {
@extend .button--primary;
}
}
.button--inverse {
&:not(:hover),
&:hover {
@extend .button--inverse;
}
}
}
// lbry/components overrides and minor styles
// Some items have very specific styling
// This is because many styles inside `lbry/components/sass/form/` are very specific
@ -31,124 +11,10 @@ input[type='number'] {
width: 8em;
}
input,
input[type='text'],
input[type='number'],
input[type='email'],
select,
textarea {
height: var(--input-height);
padding-bottom: 0.1em;
&::placeholder {
color: $lbry-gray-5;
opacity: 0.4;
}
[data-mode='dark'] & {
&::placeholder {
color: $lbry-white;
}
}
}
// @lbry/components specificityfixme
checkbox-element input[type='checkbox']:checked + label,
checkbox-element input[type='checkbox'] + label {
color: lighten($lbry-black, 20%);
[data-mode='dark'] & {
color: $lbry-gray-1;
}
}
fieldset-section {
margin: 0;
input,
select,
textarea {
border-color: lighten($lbry-black, 20%);
border-radius: var(--input-border-radius);
background-color: $lbry-white;
border-width: 1px;
[data-mode='dark'] & {
background-color: var(--dm-color-03);
border-color: $lbry-black;
}
}
label {
width: auto;
text-transform: none;
color: lighten($lbry-black, 20%);
[data-mode='dark'] & {
color: $lbry-gray-3;
}
}
&:not(:first-of-type) {
checkbox-element,
radio-element {
margin-top: var(--spacing-small);
}
}
+ fieldset-section {
margin-top: var(--spacing-medium);
}
}
checkbox-element {
&[disabled='true'] {
opacity: 0.3;
}
}
checkbox-element,
radio-element,
fieldset:last-child,
fieldset-section:last-child {
margin-bottom: 0;
}
checkbox-element,
radio-element {
&:hover {
cursor: pointer !important;
}
label {
margin-bottom: 0;
margin-left: var(--spacing-miniscule);
font-size: var(--font-body);
[data-mode='dark'] & {
color: $lbry-gray-1;
&:hover {
color: $lbry-teal-4;
}
}
}
}
checkbox-toggle {
border-width: 1px;
border-radius: var(--input-border-radius);
&:before {
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
transition: all 0.2s;
}
}
fieldset-group {
margin-top: var(--spacing-small);
+ fieldset-group {
margin-top: var(--spacing-small);
}
&.fieldset-group--smushed {
justify-content: flex-start;
@ -203,21 +69,17 @@ fieldset-group {
fieldset-section:first-child {
.form-field__prefix {
white-space: nowrap;
padding: var(--spacing-miniscule);
height: var(--input-height);
padding-right: 0;
padding: 0.5rem;
padding-left: 0.5rem;
height: var(--height-input);
padding-right: 1rem;
border: 1px solid;
border-top-left-radius: var(--input-border-radius);
border-bottom-left-radius: var(--input-border-radius);
border-top-left-radius: var(--border-radius);
border-bottom-left-radius: var(--border-radius);
border-right: 0;
border-color: $lbry-black;
color: $lbry-gray-4;
background-color: $lbry-white;
[data-mode='dark'] & {
background-color: var(--dm-color-03);
border-color: var(--dm-color-02);
}
border-color: var(--color-input-border);
color: var(--color-input-placeholder);
background-color: var(--color-input-bg);
}
}
@ -229,119 +91,23 @@ fieldset-group {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
padding-left: var(--spacing-xs);
&:focus {
border-image-slice: 1;
border-image-source: linear-gradient(to right, $lbry-black, $lbry-teal-5 5%);
}
[data-mode='dark'] & {
&:focus {
border-image-source: linear-gradient(to right, var(--dm-color-02), $lbry-teal-5 5%);
}
}
border-color: var(--color-input-border);
}
}
}
}
// form buttons are black by default
form {
[type='button'],
[type='submit'] {
&.button--inverse {
&:not(:hover) {
background-color: transparent;
border-color: $lbry-black;
color: $lbry-black;
}
&:hover {
background-color: $lbry-teal-4;
}
}
}
}
fieldset-section {
input-submit {
input {
&:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: none;
}
}
input[type='email'],
input[type='text'] {
[data-mode='dark'] & {
&:not(:focus) {
border-color: $lbry-gray-5;
}
}
}
.button,
// specificity needed because of @lbry/component rules
// @lbry/componentfixme
.button[type='submit']:not(:hover) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-color: $lbry-black;
opacity: 1;
[data-mode='dark'] & {
border-color: $lbry-gray-5;
color: $lbry-white;
}
}
}
select {
max-width: 13em;
background-position: 95% center;
background-size: 1.2rem;
[data-mode='dark'] & {
option {
background-color: $lbry-gray-5;
}
}
}
[data-mode='dark'] & {
input,
textarea,
select {
color: $lbry-white;
}
textarea,
select {
border-color: $lbry-gray-5;
}
}
}
.form-field--copyable {
background-color: rgba($lbry-gray-1, 0.5);
color: $lbry-gray-5;
padding: 0.2rem 0.75rem;
text-overflow: ellipsis;
user-select: text;
cursor: default;
[data-mode='dark'] & {
background-color: rgba($lbry-white, 0.3);
color: inherit;
}
}
.form-field__help {
@extend .help;
margin-top: var(--spacing-small);
margin-bottom: var(--spacing-large);
margin-top: var(--spacing-miniscule);
margin-bottom: var(--spacing-small);
}
.form-field--short {

View file

@ -3,20 +3,12 @@
position: fixed;
top: 0;
width: 100%;
background-color: $lbry-white;
border-bottom: 1px solid $lbry-gray-1;
box-shadow: var(--card-box-shadow) $lbry-gray-1;
background-color: var(--color-header-background);
box-shadow: var(--card-box-shadow) var(--color-box-shadow);
font-size: var(--font-body);
-webkit-user-select: none;
-webkit-app-region: drag;
[data-mode='dark'] & {
background-color: var(--dm-color-05);
color: var(--dm-color-01);
border-bottom: none;
box-shadow: var(--card-box-shadow) $lbry-black;
}
& > * {
user-select: none;
}
@ -32,6 +24,12 @@
padding-top: var(--mac-titlebar-height);
}
.header--noauth-web {
.header__navigation-item--icon {
margin: 0 10px;
}
}
.header__contents {
max-width: var(--page-max-width);
height: calc(var(--header-height) - 1px);
@ -43,6 +41,7 @@
.header__navigation {
flex: 1;
display: flex;
align-items: center;
&:last-of-type {
width: var(--side-nav-width);
@ -54,7 +53,6 @@
}
.header__menu {
width: var(--side-nav-width);
margin-left: auto;
display: flex;
justify-content: space-between;
@ -65,8 +63,11 @@
}
}
.header__menu--small {
width: auto;
.header__menu--with-balance {
button:first-child {
margin-left: var(--spacing-large);
margin-right: var(--spacing-medium);
}
}
.header__navigation-arrows {
@ -75,80 +76,29 @@
}
.header__navigation-item {
height: var(--header-height);
height: var(--height-button);
display: flex;
justify-content: center;
align-items: center;
border-radius: 0;
&:hover {
color: $lbry-teal-5;
svg {
stroke: $lbry-teal-5;
}
}
&.header__navigation-item--active {
&::after {
height: 0.2em;
bottom: 0;
width: 100%;
background-color: $lbry-teal-5;
content: '';
position: absolute;
[data-mode='dark'] & {
background-color: $lbry-teal-3;
}
}
}
[data-mode='dark'] & {
&:hover {
color: $lbry-teal-3;
svg {
stroke: $lbry-teal-3;
}
}
svg {
stroke: var(--dm-color-01);
}
}
}
.header__banner-background {
display: flex;
background-color: $lbry-teal-4;
[data-mode='dark'] & {
background-color: $lbry-teal-5;
color: $lbry-white;
}
}
.header__banner-contents {
display: flex;
max-width: var(--page-max-width);
width: 100%;
margin: auto;
padding: 0 var(--spacing-large);
justify-content: space-between;
background-color: $lbry-teal-4;
color: $lbry-white;
border-radius: var(--border-radius);
color: var(--color-text);
svg {
stroke: $lbry-white;
stroke: var(--color-text);
}
[data-mode='dark'] & {
background-color: $lbry-teal-5;
color: $lbry-white;
&:hover {
color: var(--color-link-active);
svg {
stroke: var(--color-link-active);
}
}
}
.header__navigation-item--back,
.header__navigation-item--forward {
.header__navigation-item--forward,
.header__navigation-item--icon {
width: 3rem;
}
@ -168,13 +118,6 @@
padding: 0 var(--spacing-small);
}
.header__navigation-item--upgrade {
color: $lbry-teal-5;
svg {
stroke: $lbry-teal-5;
}
}
@media (max-width: 600px) {
.header__navigation-item--back,
.header__navigation-item--forward,

View file

@ -1,5 +1,5 @@
.icon__wrapper {
background-color: var(--color-card-actions);
background-color: var(--color-primary-alt);
display: flex;
align-items: center;
justify-content: center;
@ -13,17 +13,13 @@
.icon {
position: absolute;
stroke: $lbry-gray-5;
}
[data-mode='dark'] & {
background-color: var(--color-card-actions--dark);
stroke: var(--color-primary);
}
}
.icon--help {
margin-left: var(--spacing-small);
bottom: -0.3rem;
top: 0.2rem;
opacity: 0.7;
height: 1rem;
width: 1rem;

View file

@ -1,12 +1,8 @@
.item-list {
background-color: $lbry-white;
background-color: black; //white;
margin-bottom: var(--spacing-large);
padding: var(--spacing-large);
[data-mode='dark'] & {
background-color: rgba($lbry-white, 0.1);
}
.card__actions {
margin-top: var(--spacing-medium);
margin-left: var(--spacing-small);
@ -35,9 +31,5 @@
.item-list__row:hover,
.item-list__row--selected {
background-color: rgba($lbry-black, 0.1);
[data-mode='dark'] & {
background-color: rgba($lbry-black, 0.5);
}
background-color: black; //black; //black, 0.1);
}

Some files were not shown because too many files have changed in this diff Show more