cleanup
This commit is contained in:
parent
4c014e3147
commit
ecf5e52dd4
47 changed files with 462 additions and 453 deletions
|
@ -24,6 +24,7 @@ module.name_mapper='^app\(.*\)$' -> '<PROJECT_ROOT>/src/ui/app\1'
|
||||||
module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/ui/native\1'
|
module.name_mapper='^native\(.*\)$' -> '<PROJECT_ROOT>/src/ui/native\1'
|
||||||
module.name_mapper='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/ui/analytics\1'
|
module.name_mapper='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/ui/analytics\1'
|
||||||
module.name_mapper='^i18n\(.*\)$' -> '<PROJECT_ROOT>/src/ui/i18n\1'
|
module.name_mapper='^i18n\(.*\)$' -> '<PROJECT_ROOT>/src/ui/i18n\1'
|
||||||
|
module.name_mapper='^effects\(.*\)$' -> '<PROJECT_ROOT>/src/ui/effects\1'
|
||||||
module.name_mapper='^config\(.*\)$' -> '<PROJECT_ROOT>/config\1'
|
module.name_mapper='^config\(.*\)$' -> '<PROJECT_ROOT>/config\1'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@
|
||||||
"husky": "^0.14.3",
|
"husky": "^0.14.3",
|
||||||
"json-loader": "^0.5.4",
|
"json-loader": "^0.5.4",
|
||||||
"lbry-format": "https://github.com/lbryio/lbry-format.git",
|
"lbry-format": "https://github.com/lbryio/lbry-format.git",
|
||||||
"lbry-redux": "lbryio/lbry-redux#d44cd9ca56dee784dba42c0cc13061ae75cbd46c",
|
"lbry-redux": "lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605",
|
||||||
"lbryinc": "lbryio/lbryinc#368040d64658cf2a4b8a7a6725ec1787329ce65d",
|
"lbryinc": "lbryio/lbryinc#368040d64658cf2a4b8a7a6725ec1787329ce65d",
|
||||||
"lint-staged": "^7.0.2",
|
"lint-staged": "^7.0.2",
|
||||||
"localforage": "^1.7.1",
|
"localforage": "^1.7.1",
|
||||||
|
|
|
@ -11,8 +11,7 @@ import useKonamiListener from 'util/enhanced-layout';
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
import FileViewer from 'component/fileViewer';
|
import FileViewer from 'component/fileViewer';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
import usePrevious from 'util/use-previous';
|
import usePrevious from 'effects/use-previous';
|
||||||
import SyncBackgroundManager from 'component/syncBackgroundManager';
|
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
|
||||||
export const MAIN_WRAPPER_CLASS = 'main-wrapper';
|
export const MAIN_WRAPPER_CLASS = 'main-wrapper';
|
||||||
|
@ -121,7 +120,6 @@ function App(props: Props) {
|
||||||
<Router />
|
<Router />
|
||||||
<ModalRouter />
|
<ModalRouter />
|
||||||
<FileViewer pageUri={uri} />
|
<FileViewer pageUri={uri} />
|
||||||
<SyncBackgroundManager />
|
|
||||||
|
|
||||||
{/* @if TARGET='app' */}
|
{/* @if TARGET='app' */}
|
||||||
{showUpgradeButton && (
|
{showUpgradeButton && (
|
||||||
|
|
|
@ -3,7 +3,7 @@ import * as ICONS from 'constants/icons';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import useHover from 'util/use-hover';
|
import useHover from 'effects/use-hover';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
permanentUrl: ?string,
|
permanentUrl: ?string,
|
||||||
|
|
|
@ -64,7 +64,7 @@ function ChannelContent(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!channelIsMine && <HiddenNsfwClaims className="card__subtitle" uri={uri} />}
|
{!channelIsMine && <HiddenNsfwClaims uri={uri} />}
|
||||||
|
|
||||||
{hasContent && !channelIsBlocked && !channelIsBlackListed && (
|
{hasContent && !channelIsBlocked && !channelIsBlackListed && (
|
||||||
<ClaimList header={false} uris={claimsInChannel.map(claim => claim && claim.canonical_url)} />
|
<ClaimList header={false} uris={claimsInChannel.map(claim => claim && claim.canonical_url)} />
|
||||||
|
|
|
@ -182,7 +182,7 @@ function ChannelForm(props: Props) {
|
||||||
onChange={text => setParams({ ...params, description: text })}
|
onChange={text => setParams({ ...params, description: text })}
|
||||||
/>
|
/>
|
||||||
<TagSelect
|
<TagSelect
|
||||||
title={false}
|
title={__('Add Tags')}
|
||||||
suggestMature
|
suggestMature
|
||||||
help={__('The better your tags are, the easier it will be for people to discover your channel.')}
|
help={__('The better your tags are, the easier it will be for people to discover your channel.')}
|
||||||
empty={__('No tags added')}
|
empty={__('No tags added')}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import classnames from 'classnames';
|
||||||
import ClaimPreview from 'component/claimPreview';
|
import ClaimPreview from 'component/claimPreview';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
|
||||||
const SORT_NEW = 'new';
|
const SORT_NEW = 'new';
|
||||||
const SORT_OLD = 'old';
|
const SORT_OLD = 'old';
|
||||||
|
|
|
@ -187,19 +187,19 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
<div className="claim-preview-title">
|
<div className="claim-preview-title">
|
||||||
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
|
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
|
||||||
</div>
|
</div>
|
||||||
{actions !== undefined
|
{!hideActions && actions !== undefined ? (
|
||||||
? actions
|
actions
|
||||||
: !hideActions && (
|
) : (
|
||||||
<div className="card__actions--inline">
|
<div className="card__actions--inline">
|
||||||
{isChannel && !channelIsBlocked && !claimIsMine && (
|
{isChannel && !channelIsBlocked && !claimIsMine && (
|
||||||
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||||
)}
|
|
||||||
{isChannel && !isSubscribed && !claimIsMine && (
|
|
||||||
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
|
||||||
)}
|
|
||||||
{!isChannel && claim && <FileProperties uri={uri} />}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
|
{isChannel && !isSubscribed && !claimIsMine && (
|
||||||
|
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||||
|
)}
|
||||||
|
{!isChannel && claim && <FileProperties uri={uri} />}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="claim-preview-properties">
|
<div className="claim-preview-properties">
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { FormField, Form } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import ChannelSection from 'component/selectChannel';
|
import ChannelSection from 'component/selectChannel';
|
||||||
import UnsupportedOnWeb from 'component/common/unsupported-on-web';
|
import UnsupportedOnWeb from 'component/common/unsupported-on-web';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import classnames from 'classnames';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: string | Node,
|
title?: string | Node,
|
||||||
subtitle?: string | Node,
|
subtitle?: string | Node,
|
||||||
body?: string | Node,
|
body?: string | Node,
|
||||||
actions?: string | Node,
|
actions?: string | Node,
|
||||||
|
@ -16,15 +16,17 @@ export default function Card(props: Props) {
|
||||||
const { title, subtitle, body, actions, icon } = props;
|
const { title, subtitle, body, actions, icon } = props;
|
||||||
return (
|
return (
|
||||||
<section className={classnames('card')}>
|
<section className={classnames('card')}>
|
||||||
<div className="card__header">
|
{title && (
|
||||||
<div className="section__flex">
|
<div className="card__header">
|
||||||
{icon && <Icon sectionIcon icon={icon} />}
|
<div className="section__flex">
|
||||||
<div>
|
{icon && <Icon sectionIcon icon={icon} />}
|
||||||
<h2 className="section__title">{title}</h2>
|
<div>
|
||||||
<p className="section__subtitle">{subtitle}</p>
|
<h2 className="section__title">{title}</h2>
|
||||||
|
<p className="section__subtitle">{subtitle}</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
|
|
||||||
{body && <div className={classnames('card__body', { 'card__body--with-icon': icon })}>{body}</div>}
|
{body && <div className={classnames('card__body', { 'card__body--with-icon': icon })}>{body}</div>}
|
||||||
{actions && (
|
{actions && (
|
||||||
|
|
|
@ -6,8 +6,8 @@ import classnames from 'classnames';
|
||||||
import LoadingScreen from 'component/common/loading-screen';
|
import LoadingScreen from 'component/common/loading-screen';
|
||||||
import FileRender from 'component/fileRender';
|
import FileRender from 'component/fileRender';
|
||||||
import UriIndicator from 'component/uriIndicator';
|
import UriIndicator from 'component/uriIndicator';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import usePrevious from 'util/use-previous';
|
import usePrevious from 'effects/use-previous';
|
||||||
import { FILE_WRAPPER_CLASS } from 'page/file/view';
|
import { FILE_WRAPPER_CLASS } from 'page/file/view';
|
||||||
import Draggable from 'react-draggable';
|
import Draggable from 'react-draggable';
|
||||||
import Tooltip from 'component/common/tooltip';
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
@ -86,7 +86,7 @@ export default function FileViewer(props: Props) {
|
||||||
function handleResize() {
|
function handleResize() {
|
||||||
const element = document.querySelector(`.${FILE_WRAPPER_CLASS}`);
|
const element = document.querySelector(`.${FILE_WRAPPER_CLASS}`);
|
||||||
if (!element) {
|
if (!element) {
|
||||||
console.error("Can't find file viewer wrapper to attach to the inline viewer to");
|
console.error("Can't find file viewer wrapper to attach to the inline viewer to"); // eslint-disable-line
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
numberOfNsfwClaims: number,
|
numberOfNsfwClaims: number,
|
||||||
|
@ -10,12 +9,12 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (props: Props) => {
|
export default (props: Props) => {
|
||||||
const { numberOfNsfwClaims, obscureNsfw, className } = props;
|
const { numberOfNsfwClaims, obscureNsfw } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
obscureNsfw &&
|
obscureNsfw &&
|
||||||
Boolean(numberOfNsfwClaims) && (
|
Boolean(numberOfNsfwClaims) && (
|
||||||
<div className={classnames('card--section', className || 'help')}>
|
<div className="section--padded section__subtitle">
|
||||||
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
|
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
|
||||||
<Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />.
|
<Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />.
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import LicenseType from './license-type';
|
import LicenseType from './license-type';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
language: ?string,
|
language: ?string,
|
||||||
|
@ -25,67 +26,75 @@ function PublishAdvanced(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
<Card
|
||||||
{!hideSection && (
|
actions={
|
||||||
<div className={classnames({ 'card--disabled': !name })}>
|
<React.Fragment>
|
||||||
<FormField
|
{!hideSection && (
|
||||||
label={__('Language')}
|
<div className={classnames({ 'card--disabled': !name })}>
|
||||||
type="select"
|
<FormField
|
||||||
name="content_language"
|
label={__('Language')}
|
||||||
value={language}
|
type="select"
|
||||||
onChange={event => updatePublishForm({ language: event.target.value })}
|
name="content_language"
|
||||||
>
|
value={language}
|
||||||
<option value="en">{__('English')}</option>
|
onChange={event => updatePublishForm({ language: event.target.value })}
|
||||||
<option value="zh">{__('Chinese')}</option>
|
>
|
||||||
<option value="fr">{__('French')}</option>
|
<option value="en">{__('English')}</option>
|
||||||
<option value="de">{__('German')}</option>
|
<option value="zh">{__('Chinese')}</option>
|
||||||
<option value="jp">{__('Japanese')}</option>
|
<option value="fr">{__('French')}</option>
|
||||||
<option value="ru">{__('Russian')}</option>
|
<option value="de">{__('German')}</option>
|
||||||
<option value="es">{__('Spanish')}</option>
|
<option value="jp">{__('Japanese')}</option>
|
||||||
<option value="id">{__('Indonesian')}</option>
|
<option value="ru">{__('Russian')}</option>
|
||||||
<option value="it">{__('Italian')}</option>
|
<option value="es">{__('Spanish')}</option>
|
||||||
<option value="nl">{__('Dutch')}</option>
|
<option value="id">{__('Indonesian')}</option>
|
||||||
<option value="tr">{__('Turkish')}</option>
|
<option value="it">{__('Italian')}</option>
|
||||||
<option value="pl">{__('Polish')}</option>
|
<option value="nl">{__('Dutch')}</option>
|
||||||
<option value="ms">{__('Malay')}</option>
|
<option value="tr">{__('Turkish')}</option>
|
||||||
<option value="pt">{__('Portuguese')}</option>
|
<option value="pl">{__('Polish')}</option>
|
||||||
<option value="vi">{__('Vietnamese')}</option>
|
<option value="ms">{__('Malay')}</option>
|
||||||
<option value="th">{__('Thai')}</option>
|
<option value="pt">{__('Portuguese')}</option>
|
||||||
<option value="ar">{__('Arabic')}</option>
|
<option value="vi">{__('Vietnamese')}</option>
|
||||||
<option value="cs">{__('Czech')}</option>
|
<option value="th">{__('Thai')}</option>
|
||||||
<option value="hr">{__('Croatian')}</option>
|
<option value="ar">{__('Arabic')}</option>
|
||||||
<option value="km">{__('Cambodian')}</option>
|
<option value="cs">{__('Czech')}</option>
|
||||||
<option value="ko">{__('Korean')}</option>
|
<option value="hr">{__('Croatian')}</option>
|
||||||
<option value="no">{__('Norwegian')}</option>
|
<option value="km">{__('Cambodian')}</option>
|
||||||
<option value="ro">{__('Romanian')}</option>
|
<option value="ko">{__('Korean')}</option>
|
||||||
<option value="hi">{__('Hindi')}</option>
|
<option value="no">{__('Norwegian')}</option>
|
||||||
<option value="el">{__('Greek')}</option>
|
<option value="ro">{__('Romanian')}</option>
|
||||||
</FormField>
|
<option value="hi">{__('Hindi')}</option>
|
||||||
|
<option value="el">{__('Greek')}</option>
|
||||||
|
</FormField>
|
||||||
|
|
||||||
<LicenseType
|
<LicenseType
|
||||||
licenseType={licenseType}
|
licenseType={licenseType}
|
||||||
otherLicenseDescription={otherLicenseDescription}
|
otherLicenseDescription={otherLicenseDescription}
|
||||||
licenseUrl={licenseUrl}
|
licenseUrl={licenseUrl}
|
||||||
handleLicenseChange={(newLicenseType, newLicenseUrl) =>
|
handleLicenseChange={(newLicenseType, newLicenseUrl) =>
|
||||||
updatePublishForm({
|
updatePublishForm({
|
||||||
licenseType: newLicenseType,
|
licenseType: newLicenseType,
|
||||||
licenseUrl: newLicenseUrl,
|
licenseUrl: newLicenseUrl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
handleLicenseDescriptionChange={event =>
|
handleLicenseDescriptionChange={event =>
|
||||||
updatePublishForm({
|
updatePublishForm({
|
||||||
otherLicenseDescription: event.target.value,
|
otherLicenseDescription: event.target.value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })}
|
handleLicenseUrlChange={event => updatePublishForm({ licenseUrl: event.target.value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Button label={hideSection ? __('Additional Options') : __('Hide')} button="link" onClick={toggleHideSection} />
|
<Button
|
||||||
</div>
|
label={hideSection ? __('Additional Options') : __('Hide')}
|
||||||
</section>
|
button="link"
|
||||||
|
onClick={toggleHideSection}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { regexInvalidURI } from 'lbry-redux';
|
import { regexInvalidURI } from 'lbry-redux';
|
||||||
import classnames from 'classnames';
|
|
||||||
import FileSelector from 'component/common/file-selector';
|
import FileSelector from 'component/common/file-selector';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
name: ?string,
|
name: ?string,
|
||||||
|
@ -11,10 +12,11 @@ type Props = {
|
||||||
isStillEditing: boolean,
|
isStillEditing: boolean,
|
||||||
balance: number,
|
balance: number,
|
||||||
updatePublishForm: ({}) => void,
|
updatePublishForm: ({}) => void,
|
||||||
|
disabled: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function PublishFile(props: Props) {
|
function PublishFile(props: Props) {
|
||||||
const { name, balance, filePath, isStillEditing, updatePublishForm } = props;
|
const { name, balance, filePath, isStillEditing, updatePublishForm, disabled } = props;
|
||||||
|
|
||||||
function handleFileChange(filePath: string, fileName: string) {
|
function handleFileChange(filePath: string, fileName: string) {
|
||||||
const publishFormParams: { filePath: string, name?: string } = { filePath };
|
const publishFormParams: { filePath: string, name?: string } = { filePath };
|
||||||
|
@ -28,29 +30,29 @@ function PublishFile(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section
|
<Card
|
||||||
className={classnames('card card--section', {
|
className={disabled ? 'card--disabled' : undefined}
|
||||||
'card--disabled': balance === 0,
|
icon={ICONS.PUBLISH}
|
||||||
})}
|
disabled={balance === 0}
|
||||||
>
|
title={isStillEditing ? __('Edit') : __('Publish')}
|
||||||
<h2 className="card__title">{isStillEditing ? __('Edit') : __('Publish')}</h2>
|
subtitle={__('You are currently editing a claim.')}
|
||||||
{isStillEditing && <p className="card__subtitle">{__('You are currently editing a claim.')}</p>}
|
actions={
|
||||||
|
<React.Fragment>
|
||||||
<div className="card__content">
|
<FileSelector currentPath={filePath} onFileChosen={handleFileChange} />
|
||||||
<FileSelector currentPath={filePath} onFileChosen={handleFileChange} />
|
{!isStillEditing && (
|
||||||
{!isStillEditing && (
|
<p className="help">
|
||||||
<p className="help">
|
{__('For video content, use MP4s in H264/AAC format for best compatibility.')}{' '}
|
||||||
{__('For video content, use MP4s in H264/AAC format for best compatibility.')}{' '}
|
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/how-to-publish" />.
|
||||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/how-to-publish" />.
|
</p>
|
||||||
</p>
|
)}
|
||||||
)}
|
{!!isStillEditing && name && (
|
||||||
{!!isStillEditing && name && (
|
<p className="help">
|
||||||
<p className="help">
|
{__("If you don't choose a file, the file from your existing claim %name% will be used", { name: name })}
|
||||||
{__("If you don't choose a file, the file from your existing claim %name% will be used", { name: name })}
|
</p>
|
||||||
</p>
|
)}
|
||||||
)}
|
</React.Fragment>
|
||||||
</div>
|
}
|
||||||
</section>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import PublishName from 'component/publishName';
|
||||||
import PublishAdditionalOptions from 'component/publishAdditionalOptions';
|
import PublishAdditionalOptions from 'component/publishAdditionalOptions';
|
||||||
import PublishFormErrors from 'component/publishFormErrors';
|
import PublishFormErrors from 'component/publishFormErrors';
|
||||||
import SelectThumbnail from 'component/selectThumbnail';
|
import SelectThumbnail from 'component/selectThumbnail';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
tags: Array<Tag>,
|
tags: Array<Tag>,
|
||||||
|
@ -127,35 +128,36 @@ function PublishForm(props: Props) {
|
||||||
<PublishFile />
|
<PublishFile />
|
||||||
<div className={classnames({ 'card--disabled': formDisabled })}>
|
<div className={classnames({ 'card--disabled': formDisabled })}>
|
||||||
<PublishText disabled={formDisabled} />
|
<PublishText disabled={formDisabled} />
|
||||||
<div className="card card--section">
|
<Card actions={<SelectThumbnail />} />
|
||||||
{/* This should probably be PublishThumbnail */}
|
|
||||||
<SelectThumbnail />
|
<TagSelect
|
||||||
</div>
|
title={__('Add Tags')}
|
||||||
<div className="card card--section">
|
suggestMature
|
||||||
<TagSelect
|
help={__('The better your tags are, the easier it will be for people to discover your content.')}
|
||||||
title={false}
|
empty={__('No tags added')}
|
||||||
suggestMature
|
onSelect={newTag => {
|
||||||
help={__('The better your tags are, the easier it will be for people to discover your content.')}
|
if (!tags.map(savedTag => savedTag.name).includes(newTag.name)) {
|
||||||
empty={__('No tags added')}
|
updatePublishForm({ tags: [...tags, newTag] });
|
||||||
onSelect={newTag => {
|
}
|
||||||
if (!tags.map(savedTag => savedTag.name).includes(newTag.name)) {
|
}}
|
||||||
updatePublishForm({ tags: [...tags, newTag] });
|
onRemove={clickedTag => {
|
||||||
}
|
const newTags = tags.slice().filter(tag => tag.name !== clickedTag.name);
|
||||||
}}
|
updatePublishForm({ tags: newTags });
|
||||||
onRemove={clickedTag => {
|
}}
|
||||||
const newTags = tags.slice().filter(tag => tag.name !== clickedTag.name);
|
tagsChosen={tags}
|
||||||
updatePublishForm({ tags: newTags });
|
/>
|
||||||
}}
|
|
||||||
tagsChosen={tags}
|
<Card
|
||||||
/>
|
actions={
|
||||||
</div>
|
<React.Fragment>
|
||||||
<section className="card card--section">
|
<ChannelSection channel={channel} onChannelChange={channel => updatePublishForm({ channel })} />
|
||||||
<ChannelSection channel={channel} onChannelChange={channel => updatePublishForm({ channel })} />
|
<p className="help">
|
||||||
<p className="help">
|
{__('This is a username or handle that your content can be found under.')}{' '}
|
||||||
{__('This is a username or handle that your content can be found under.')}{' '}
|
{__('Ex. @Marvel, @TheBeatles, @BooksByJoe')}
|
||||||
{__('Ex. @Marvel, @TheBeatles, @BooksByJoe')}
|
</p>
|
||||||
</p>
|
</React.Fragment>
|
||||||
</section>
|
}
|
||||||
|
/>
|
||||||
|
|
||||||
<PublishName disabled={formDisabled} />
|
<PublishName disabled={formDisabled} />
|
||||||
<PublishPrice disabled={formDisabled} />
|
<PublishPrice disabled={formDisabled} />
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { isNameValid } from 'lbry-redux';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import NameHelpText from './name-help-text';
|
import NameHelpText from './name-help-text';
|
||||||
import BidHelpText from './bid-help-text';
|
import BidHelpText from './bid-help-text';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
name: string,
|
name: string,
|
||||||
|
@ -73,48 +74,56 @@ function PublishName(props: Props) {
|
||||||
}, [bid, previousBidAmount, balance]);
|
}, [bid, previousBidAmount, balance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
<Card
|
||||||
<fieldset-group class="fieldset-group--smushed fieldset-group--disabled-prefix">
|
actions={
|
||||||
<fieldset-section>
|
<React.Fragment>
|
||||||
<label>{__('Name')}</label>
|
<fieldset-group class="fieldset-group--smushed fieldset-group--disabled-prefix">
|
||||||
<div className="form-field__prefix">{`lbry://${
|
<fieldset-section>
|
||||||
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : `${channel}/`
|
<label>{__('Name')}</label>
|
||||||
}`}</div>
|
<div className="form-field__prefix">{`lbry://${
|
||||||
</fieldset-section>
|
!channel || channel === CHANNEL_ANONYMOUS || channel === CHANNEL_NEW ? '' : `${channel}/`
|
||||||
<FormField
|
}`}</div>
|
||||||
type="text"
|
</fieldset-section>
|
||||||
name="content_name"
|
<FormField
|
||||||
value={name}
|
type="text"
|
||||||
error={nameError}
|
name="content_name"
|
||||||
onChange={event => updatePublishForm({ name: event.target.value })}
|
value={name}
|
||||||
/>
|
error={nameError}
|
||||||
</fieldset-group>
|
onChange={event => updatePublishForm({ name: event.target.value })}
|
||||||
<div className="form-field__help">
|
/>
|
||||||
<NameHelpText
|
</fieldset-group>
|
||||||
uri={uri}
|
<div className="form-field__help">
|
||||||
isStillEditing={isStillEditing}
|
<NameHelpText
|
||||||
myClaimForUri={myClaimForUri}
|
uri={uri}
|
||||||
onEditMyClaim={editExistingClaim}
|
isStillEditing={isStillEditing}
|
||||||
/>
|
myClaimForUri={myClaimForUri}
|
||||||
</div>
|
onEditMyClaim={editExistingClaim}
|
||||||
<FormField
|
/>
|
||||||
type="number"
|
</div>
|
||||||
name="content_bid"
|
<FormField
|
||||||
min="0"
|
type="number"
|
||||||
step="any"
|
name="content_bid"
|
||||||
placeholder="0.123"
|
min="0"
|
||||||
className="form-field--price-amount"
|
step="any"
|
||||||
label={__('Deposit (LBC)')}
|
placeholder="0.123"
|
||||||
postfix="LBC"
|
className="form-field--price-amount"
|
||||||
value={bid}
|
label={__('Deposit (LBC)')}
|
||||||
error={bidError}
|
postfix="LBC"
|
||||||
disabled={!name}
|
value={bid}
|
||||||
onChange={event => updatePublishForm({ bid: parseFloat(event.target.value) })}
|
error={bidError}
|
||||||
helper={
|
disabled={!name}
|
||||||
<BidHelpText uri={uri} amountNeededForTakeover={amountNeededForTakeover} isResolvingUri={isResolvingUri} />
|
onChange={event => updatePublishForm({ bid: parseFloat(event.target.value) })}
|
||||||
}
|
helper={
|
||||||
/>
|
<BidHelpText
|
||||||
</section>
|
uri={uri}
|
||||||
|
amountNeededForTakeover={amountNeededForTakeover}
|
||||||
|
isResolvingUri={isResolvingUri}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormField, FormFieldPrice } from 'component/common/form';
|
import { FormField, FormFieldPrice } from 'component/common/form';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
contentIsFree: boolean,
|
contentIsFree: boolean,
|
||||||
|
@ -13,40 +14,44 @@ function PublishPrice(props: Props) {
|
||||||
const { contentIsFree, fee, updatePublishForm, disabled } = props;
|
const { contentIsFree, fee, updatePublishForm, disabled } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
<Card
|
||||||
<FormField
|
actions={
|
||||||
type="radio"
|
<React.Fragment>
|
||||||
name="content_free"
|
<FormField
|
||||||
label={__('Free')}
|
type="radio"
|
||||||
checked={contentIsFree}
|
name="content_free"
|
||||||
disabled={disabled}
|
label={__('Free')}
|
||||||
onChange={() => updatePublishForm({ contentIsFree: true })}
|
checked={contentIsFree}
|
||||||
/>
|
disabled={disabled}
|
||||||
|
onChange={() => updatePublishForm({ contentIsFree: true })}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="radio"
|
type="radio"
|
||||||
name="content_cost"
|
name="content_cost"
|
||||||
label={__('Add a price to this file')}
|
label={__('Add a price to this file')}
|
||||||
checked={!contentIsFree}
|
checked={!contentIsFree}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={() => updatePublishForm({ contentIsFree: false })}
|
onChange={() => updatePublishForm({ contentIsFree: false })}
|
||||||
/>
|
/>
|
||||||
{!contentIsFree && (
|
{!contentIsFree && (
|
||||||
<FormFieldPrice
|
<FormFieldPrice
|
||||||
name="content_cost_amount"
|
name="content_cost_amount"
|
||||||
min="0"
|
min="0"
|
||||||
price={fee}
|
price={fee}
|
||||||
onChange={newFee => updatePublishForm({ fee: newFee })}
|
onChange={newFee => updatePublishForm({ fee: newFee })}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
{fee && fee.currency !== 'LBC' && (
|
|
||||||
<p className="form-field__help">
|
|
||||||
{__(
|
|
||||||
'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
|
|
||||||
)}
|
)}
|
||||||
</p>
|
{fee && fee.currency !== 'LBC' && (
|
||||||
)}
|
<p className="form-field__help">
|
||||||
</section>
|
{__(
|
||||||
|
'All content fees are charged in LBC. For non-LBC payment methods, the number of credits charged will be adjusted based on the value of LBRY credits at the time of purchase.'
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormField } from 'component/common/form';
|
import { FormField } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: ?string,
|
title: ?string,
|
||||||
|
@ -19,30 +20,38 @@ function PublishText(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="card card--section">
|
<Card
|
||||||
<FormField
|
actions={
|
||||||
type="text"
|
<React.Fragment>
|
||||||
name="content_title"
|
<FormField
|
||||||
label={__('Title')}
|
type="text"
|
||||||
placeholder={__('Titular Title')}
|
name="content_title"
|
||||||
disabled={disabled}
|
label={__('Title')}
|
||||||
value={title}
|
placeholder={__('Titular Title')}
|
||||||
onChange={e => updatePublishForm({ title: e.target.value })}
|
disabled={disabled}
|
||||||
/>
|
value={title}
|
||||||
|
onChange={e => updatePublishForm({ title: e.target.value })}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type={advancedEditor ? 'markdown' : 'textarea'}
|
type={advancedEditor ? 'markdown' : 'textarea'}
|
||||||
name="content_description"
|
name="content_description"
|
||||||
label={__('Description')}
|
label={__('Description')}
|
||||||
placeholder={__('My description for this and that')}
|
placeholder={__('My description for this and that')}
|
||||||
value={description}
|
value={description}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={value => updatePublishForm({ description: advancedEditor ? value : value.target.value })}
|
onChange={value => updatePublishForm({ description: advancedEditor ? value : value.target.value })}
|
||||||
/>
|
/>
|
||||||
<div className="card__actions">
|
<div className="card__actions">
|
||||||
<Button button="link" onClick={toggleMarkdown} label={advancedEditor ? 'Simple Editor' : 'Advanced Editor'} />
|
<Button
|
||||||
</div>
|
button="link"
|
||||||
</section>
|
onClick={toggleMarkdown}
|
||||||
|
label={advancedEditor ? 'Simple Editor' : 'Advanced Editor'}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import TotalBackground from './total-background.png';
|
import TotalBackground from './total-background.png';
|
||||||
import useTween from 'util/use-tween';
|
import useTween from 'effects/use-tween';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
rewards: Array<Reward>,
|
rewards: Array<Reward>,
|
||||||
|
|
|
@ -69,25 +69,27 @@ function SideBar(props: Props) {
|
||||||
className="navigation-link"
|
className="navigation-link"
|
||||||
activeClass="navigation-link--active"
|
activeClass="navigation-link--active"
|
||||||
/>
|
/>
|
||||||
<ul className="navigation-links tags--vertical">
|
<section className="navigation-links__inline">
|
||||||
{followedTags.map(({ name }, key) => (
|
<ul className="navigation-links--small tags--vertical">
|
||||||
<li className="navigation-link__wrapper" key={name}>
|
{followedTags.map(({ name }, key) => (
|
||||||
<Tag navigate={`/$/tags?t${name}`} name={name} />
|
<li className="navigation-link__wrapper" key={name}>
|
||||||
</li>
|
<Tag navigate={`/$/tags?t${name}`} name={name} />
|
||||||
))}
|
</li>
|
||||||
</ul>
|
))}
|
||||||
<ul className="navigation-links--small">
|
</ul>
|
||||||
{subscriptions.map(({ uri, channelName }, index) => (
|
<ul className="navigation-links--small">
|
||||||
<li key={uri} className="navigation-link__wrapper">
|
{subscriptions.map(({ uri, channelName }, index) => (
|
||||||
<Button
|
<li key={uri} className="navigation-link__wrapper">
|
||||||
navigate={uri}
|
<Button
|
||||||
label={channelName}
|
navigate={uri}
|
||||||
className="navigation-link"
|
label={channelName}
|
||||||
activeClass="navigation-link--active"
|
className="navigation-link"
|
||||||
/>
|
activeClass="navigation-link--active"
|
||||||
</li>
|
/>
|
||||||
))}
|
</li>
|
||||||
</ul>
|
))}
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
</nav>
|
</nav>
|
||||||
</StickyBox>
|
</StickyBox>
|
||||||
);
|
);
|
||||||
|
|
|
@ -124,11 +124,6 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Try to unlock by default here
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
|
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
|
||||||
if (launchedModal === false && !modal) {
|
if (launchedModal === false && !modal) {
|
||||||
this.setState({ launchedModal: true }, () => notifyUnlockWallet());
|
this.setState({ launchedModal: true }, () => notifyUnlockWallet());
|
||||||
|
@ -153,10 +148,10 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (wallet && wallet.blocks_behind > 0) {
|
} else if (wallet && wallet.blocks_behind > 0) {
|
||||||
const format = wallet.blocks_behind === 1 ? '%s block behind' : '%s blocks behind';
|
const amountBehind = wallet.blocks_behind === 1 ? '%amountBehind% block behind' : '%amountBehind% blocks behind';
|
||||||
this.setState({
|
this.setState({
|
||||||
message: __('Blockchain Sync'),
|
message: __('Blockchain Sync'),
|
||||||
details: `${__('Catching up...')} (${__(format, wallet.blocks_behind)})`,
|
details: `${__('Catching up...')} (${__(amountBehind, { amountBehind: wallet.blocks_behind })})`,
|
||||||
});
|
});
|
||||||
} else if (
|
} else if (
|
||||||
wallet &&
|
wallet &&
|
||||||
|
|
|
@ -4,7 +4,7 @@ import * as ICONS from 'constants/icons';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import useHover from 'util/use-hover';
|
import useHover from 'effects/use-hover';
|
||||||
|
|
||||||
type SubscriptionArgs = {
|
type SubscriptionArgs = {
|
||||||
channelName: string,
|
channelName: string,
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
import * as SETTINGS from 'constants/settings';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { selectBalance } from 'lbry-redux';
|
|
||||||
import { doGetSync, selectSyncHash, selectUserVerifiedEmail } from 'lbryinc';
|
|
||||||
import { doSetClientSetting } from 'redux/actions/settings';
|
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
|
||||||
import WalletSecurityAndSync from './view';
|
|
||||||
|
|
||||||
const select = state => ({
|
|
||||||
balance: selectBalance(state),
|
|
||||||
verifiedEmail: selectUserVerifiedEmail(state),
|
|
||||||
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
|
||||||
hasSyncHash: selectSyncHash(state),
|
|
||||||
});
|
|
||||||
|
|
||||||
const perform = dispatch => ({
|
|
||||||
getSync: password => dispatch(doGetSync(password)),
|
|
||||||
setSync: value => dispatch(doSetClientSetting(SETTINGS.ENABLE_SYNC, value)),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(
|
|
||||||
select,
|
|
||||||
perform
|
|
||||||
)(WalletSecurityAndSync);
|
|
|
@ -1,22 +0,0 @@
|
||||||
// @flow
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
syncEnabled: boolean,
|
|
||||||
verifiedEmail?: string,
|
|
||||||
getSync: () => void,
|
|
||||||
};
|
|
||||||
|
|
||||||
function SyncBackgroundManager(props: Props) {
|
|
||||||
const { syncEnabled, getSync, verifiedEmail } = props;
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (syncEnabled && verifiedEmail) {
|
|
||||||
getSync();
|
|
||||||
}
|
|
||||||
}, [syncEnabled, verifiedEmail, getSync]);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default SyncBackgroundManager;
|
|
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import Tag from 'component/tag';
|
import Tag from 'component/tag';
|
||||||
import TagsSearch from 'component/tagsSearch';
|
import TagsSearch from 'component/tagsSearch';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
|
|
||||||
|
@ -73,7 +73,15 @@ export default function TagSelect(props: Props) {
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
body={
|
subtitle={
|
||||||
|
help !== false && (
|
||||||
|
<span>
|
||||||
|
{help || __("The tags you follow will change what's trending for you.")}{' '}
|
||||||
|
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/trending" />.
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
actions={
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<TagsSearch
|
<TagsSearch
|
||||||
onRemove={handleTagClick}
|
onRemove={handleTagClick}
|
||||||
|
@ -81,12 +89,6 @@ export default function TagSelect(props: Props) {
|
||||||
suggestMature={suggestMature && !hasMatureTag}
|
suggestMature={suggestMature && !hasMatureTag}
|
||||||
tagsPasssedIn={tagsToDisplay}
|
tagsPasssedIn={tagsToDisplay}
|
||||||
/>
|
/>
|
||||||
{help !== false && (
|
|
||||||
<p className="help">
|
|
||||||
{help || __("The tags you follow will change what's trending for you.")}{' '}
|
|
||||||
<Button button="link" label={__('Learn more')} href="https://lbry.com/faq/trending" />.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -40,9 +40,7 @@ function UserEmail(props: Props) {
|
||||||
'This information is disclosed only to LBRY, Inc. and not to the LBRY network. It is only required to save account information and earn rewards.'
|
'This information is disclosed only to LBRY, Inc. and not to the LBRY network. It is only required to save account information and earn rewards.'
|
||||||
)}
|
)}
|
||||||
actions={
|
actions={
|
||||||
!isVerified ? (
|
isVerified ? (
|
||||||
<Button button="primary" label={__('Add Email')} navigate={`/$/${PAGES.AUTH}`} />
|
|
||||||
) : (
|
|
||||||
<FormField
|
<FormField
|
||||||
type="text"
|
type="text"
|
||||||
className="form-field--copyable"
|
className="form-field--copyable"
|
||||||
|
@ -60,6 +58,8 @@ function UserEmail(props: Props) {
|
||||||
inputButton={<UserSignOutButton button="inverse" />}
|
inputButton={<UserSignOutButton button="inverse" />}
|
||||||
value={email || ''}
|
value={email || ''}
|
||||||
/>
|
/>
|
||||||
|
) : (
|
||||||
|
<Button button="primary" label={__('Add Email')} navigate={`/$/${PAGES.AUTH}`} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -30,6 +30,7 @@ function UserEmailNew(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
// Sync currently doesn't work for wallets with balances
|
||||||
if (syncEnabled && balance) {
|
if (syncEnabled && balance) {
|
||||||
setSync(false);
|
setSync(false);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,9 @@ function UserEmailNew(props: Props) {
|
||||||
name="sync_checkbox"
|
name="sync_checkbox"
|
||||||
label={__('Sync your balance between devices')}
|
label={__('Sync your balance between devices')}
|
||||||
helper={
|
helper={
|
||||||
balance > 0 ? __('This is only available for empty wallets') : __('Maybe some more text about something')
|
balance > 0
|
||||||
|
? __("This is only available if you don't have a balance")
|
||||||
|
: __('Maybe some more text about something')
|
||||||
}
|
}
|
||||||
checked={syncEnabled}
|
checked={syncEnabled}
|
||||||
onChange={() => setSync(!syncEnabled)}
|
onChange={() => setSync(!syncEnabled)}
|
||||||
|
|
|
@ -33,9 +33,9 @@ const select = state => ({
|
||||||
youtubeChannels: selectYoutubeChannels(state),
|
youtubeChannels: selectYoutubeChannels(state),
|
||||||
userFetchPending: selectUserIsPending(state),
|
userFetchPending: selectUserIsPending(state),
|
||||||
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
||||||
syncIsPending: selectGetSyncIsPending(state),
|
syncingWallet: selectGetSyncIsPending(state),
|
||||||
getSyncError: selectGetSyncErrorMessage(state),
|
getSyncError: selectGetSyncErrorMessage(state),
|
||||||
syncHash: selectSyncHash(state),
|
hasSynced: Boolean(selectSyncHash(state)),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = dispatch => ({
|
const perform = dispatch => ({
|
||||||
|
|
|
@ -6,19 +6,11 @@ import UserEmailVerify from 'component/userEmailVerify';
|
||||||
import UserFirstChannel from 'component/userFirstChannel';
|
import UserFirstChannel from 'component/userFirstChannel';
|
||||||
import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
|
import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
|
||||||
import { rewards as REWARDS } from 'lbryinc';
|
import { rewards as REWARDS } from 'lbryinc';
|
||||||
import usePrevious from 'util/use-previous';
|
|
||||||
import UserVerify from 'component/userVerify';
|
import UserVerify from 'component/userVerify';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import YoutubeTransferWelcome from 'component/youtubeTransferWelcome';
|
import YoutubeTransferWelcome from 'component/youtubeTransferWelcome';
|
||||||
import SyncPassword from 'component/syncPassword';
|
import SyncPassword from 'component/syncPassword';
|
||||||
|
import useFetched from 'effects/use-fetched';
|
||||||
/*
|
|
||||||
- Brand new user
|
|
||||||
- Brand new user, not auto approved
|
|
||||||
- Second device (first time user), first device has a password + rewards not approved
|
|
||||||
- Second device (first time user), first device has a password + rewards approved
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
user: ?User,
|
user: ?User,
|
||||||
|
@ -33,24 +25,12 @@ type Props = {
|
||||||
history: { replace: string => void },
|
history: { replace: string => void },
|
||||||
location: { search: string },
|
location: { search: string },
|
||||||
youtubeChannels: Array<any>,
|
youtubeChannels: Array<any>,
|
||||||
syncIsPending: boolean,
|
syncEnabled: boolean,
|
||||||
|
hasSynced: boolean,
|
||||||
|
syncingWallet: boolean,
|
||||||
getSyncError: ?string,
|
getSyncError: ?string,
|
||||||
hasSyncedSuccessfully: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function useFetched(fetching) {
|
|
||||||
const wasFetching = usePrevious(fetching);
|
|
||||||
const [fetched, setFetched] = React.useState(false);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (wasFetching && !fetching) {
|
|
||||||
setFetched(true);
|
|
||||||
}
|
|
||||||
}, [wasFetching, fetching, setFetched]);
|
|
||||||
|
|
||||||
return fetched;
|
|
||||||
}
|
|
||||||
|
|
||||||
function UserSignIn(props: Props) {
|
function UserSignIn(props: Props) {
|
||||||
const {
|
const {
|
||||||
emailToVerify,
|
emailToVerify,
|
||||||
|
@ -65,9 +45,9 @@ function UserSignIn(props: Props) {
|
||||||
fetchUser,
|
fetchUser,
|
||||||
youtubeChannels,
|
youtubeChannels,
|
||||||
syncEnabled,
|
syncEnabled,
|
||||||
syncIsPending,
|
syncingWallet,
|
||||||
getSyncError,
|
getSyncError,
|
||||||
syncHash,
|
hasSynced,
|
||||||
fetchingChannels,
|
fetchingChannels,
|
||||||
} = props;
|
} = props;
|
||||||
const { search } = location;
|
const { search } = location;
|
||||||
|
@ -76,56 +56,64 @@ function UserSignIn(props: Props) {
|
||||||
const hasVerifiedEmail = user && user.has_verified_email;
|
const hasVerifiedEmail = user && user.has_verified_email;
|
||||||
const rewardsApproved = user && user.is_reward_approved;
|
const rewardsApproved = user && user.is_reward_approved;
|
||||||
const hasFetchedReward = useFetched(claimingReward);
|
const hasFetchedReward = useFetched(claimingReward);
|
||||||
// const hasFetchedSync = useFetched(syncIsPending);
|
|
||||||
// const hasTriedSyncForReal = syncEnabled && hasFetchedSync;
|
|
||||||
const channelCount = channels ? channels.length : 0;
|
const channelCount = channels ? channels.length : 0;
|
||||||
const hasClaimedEmailAward = claimedRewards.some(reward => reward.reward_type === REWARDS.TYPE_CONFIRM_EMAIL);
|
const hasClaimedEmailAward = claimedRewards.some(reward => reward.reward_type === REWARDS.TYPE_CONFIRM_EMAIL);
|
||||||
const hasYoutubeChannels = youtubeChannels && youtubeChannels.length;
|
const hasYoutubeChannels = youtubeChannels && Boolean(youtubeChannels.length);
|
||||||
const hasTransferrableYoutubeChannels = hasYoutubeChannels && youtubeChannels.some(channel => channel.transferable);
|
const hasTransferrableYoutubeChannels = hasYoutubeChannels && youtubeChannels.some(channel => channel.transferable);
|
||||||
const hasPendingYoutubeTransfer =
|
const hasPendingYoutubeTransfer =
|
||||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === 'pending_transfer');
|
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === 'pending_transfer');
|
||||||
|
|
||||||
React.useEffect(() => {
|
// Complexity warning
|
||||||
if (
|
// We can't just check if we are currently fetching something
|
||||||
hasVerifiedEmail &&
|
// We may want to keep a component rendered while something is being fetched, instead of replacing it with the large spinner
|
||||||
balance !== undefined &&
|
// The verbose variable names are an attempt to alleviate _some_ of the confusion from handling all edge cases that come from
|
||||||
!hasClaimedEmailAward &&
|
// reward claiming (plus the balance updating after), channel creation, account syncing, and youtube transfer
|
||||||
!hasFetchedReward &&
|
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && balance === 0 && !getSyncError;
|
||||||
(!syncEnabled || (syncEnabled && syncHash))
|
const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet;
|
||||||
) {
|
const isWaitingForSomethingToFinish =
|
||||||
claimReward();
|
// If the user has claimed the email award, we need to wait until the balance updates sometime in the future
|
||||||
}
|
!hasFetchedReward || (hasFetchedReward && hasClaimedEmailAward) || (syncEnabled && !hasSynced);
|
||||||
}, [hasVerifiedEmail, claimReward, balance, hasClaimedEmailAward, hasFetchedReward, syncEnabled, syncHash]);
|
|
||||||
|
// The possible screens for the sign in flow
|
||||||
|
const showEmail = !emailToVerify && !hasVerifiedEmail;
|
||||||
|
const showEmailVerification = emailToVerify && !hasVerifiedEmail;
|
||||||
|
const showUserVerification = hasVerifiedEmail && !rewardsApproved;
|
||||||
|
const showSyncPassword = syncEnabled && getSyncError && !hasSynced;
|
||||||
|
const showChannelCreation =
|
||||||
|
hasVerifiedEmail && balance && balance > DEFAULT_BID_FOR_FIRST_CHANNEL && channelCount === 0 && !hasYoutubeChannels;
|
||||||
|
const showYoutubeTransfer =
|
||||||
|
hasVerifiedEmail && hasYoutubeChannels && (hasTransferrableYoutubeChannels || hasPendingYoutubeTransfer);
|
||||||
|
const showLoadingSpinner =
|
||||||
|
canHijackSignInFlowWithSpinner && (isCurrentlyFetchingSomething || isWaitingForSomethingToFinish);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
fetchUser();
|
fetchUser();
|
||||||
}, [fetchUser]);
|
}, [fetchUser]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
// Don't claim the reward if sync is enabled until after a sync has been completed successfully
|
||||||
|
// If we do it before, we could end up trying to sync a wallet with a non-zero balance which will fail to sync
|
||||||
|
const delayForSync = syncEnabled && !hasSynced;
|
||||||
|
|
||||||
|
if (hasVerifiedEmail && !hasClaimedEmailAward && !hasFetchedReward && !delayForSync) {
|
||||||
|
claimReward();
|
||||||
|
}
|
||||||
|
}, [hasVerifiedEmail, claimReward, hasClaimedEmailAward, hasFetchedReward, syncEnabled, hasSynced]);
|
||||||
|
|
||||||
|
// Loop through this list from the end, until it finds a matching component
|
||||||
|
// If it never finds one, assume the user has completed every step and redirect them
|
||||||
const SIGN_IN_FLOW = [
|
const SIGN_IN_FLOW = [
|
||||||
!emailToVerify && !hasVerifiedEmail && <UserEmailNew />,
|
showEmail && <UserEmailNew />,
|
||||||
emailToVerify && !hasVerifiedEmail && <UserEmailVerify />,
|
showEmailVerification && <UserEmailVerify />,
|
||||||
hasVerifiedEmail && !rewardsApproved && <UserVerify />,
|
showUserVerification && <UserVerify />,
|
||||||
getSyncError && !syncHash && <SyncPassword />,
|
showSyncPassword && <SyncPassword />,
|
||||||
hasVerifiedEmail && balance > DEFAULT_BID_FOR_FIRST_CHANNEL && channelCount === 0 && !hasYoutubeChannels && (
|
showChannelCreation && <UserFirstChannel />,
|
||||||
<UserFirstChannel />
|
showYoutubeTransfer && <YoutubeTransferWelcome />,
|
||||||
|
showLoadingSpinner && (
|
||||||
|
<div className="main--empty">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
),
|
),
|
||||||
hasVerifiedEmail && hasYoutubeChannels && (hasTransferrableYoutubeChannels || hasPendingYoutubeTransfer) && (
|
|
||||||
<YoutubeTransferWelcome />
|
|
||||||
),
|
|
||||||
hasVerifiedEmail &&
|
|
||||||
balance === 0 &&
|
|
||||||
!getSyncError &&
|
|
||||||
(fetchingChannels ||
|
|
||||||
!hasFetchedReward ||
|
|
||||||
claimingReward ||
|
|
||||||
syncIsPending ||
|
|
||||||
(syncEnabled && !syncHash) ||
|
|
||||||
// Just claimed the email award, wait until the balance updates to move forward
|
|
||||||
(balance === 0 && hasFetchedReward && hasClaimedEmailAward)) && (
|
|
||||||
<div className="main--empty">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
let componentToRender;
|
let componentToRender;
|
||||||
|
|
|
@ -13,25 +13,33 @@ type Props = {
|
||||||
videosImported: ?Array<number>, // [currentAmountImported, totalAmountToImport]
|
videosImported: ?Array<number>, // [currentAmountImported, totalAmountToImport]
|
||||||
};
|
};
|
||||||
|
|
||||||
const LBRY_YT_URL = 'https://lbry.com/youtube/status/';
|
const NOT_TRANSFERRED = 'not_transferred';
|
||||||
const NOT_TRANSFERED = 'not_transferred';
|
|
||||||
const PENDING_TRANSFER = 'pending_transfer';
|
const PENDING_TRANSFER = 'pending_transfer';
|
||||||
const COMPLETED_TRANSFER = 'completed_transfer';
|
const COMPLETED_TRANSFER = 'completed_transfer';
|
||||||
|
|
||||||
export default function YoutubeTransferStatus(props: Props) {
|
export default function YoutubeTransferStatus(props: Props) {
|
||||||
const { youtubeChannels, ytImportPending, claimChannels, videosImported, checkYoutubeTransfer, updateUser } = props;
|
const { youtubeChannels, ytImportPending, claimChannels, videosImported, checkYoutubeTransfer, updateUser } = props;
|
||||||
|
|
||||||
const hasChannels = youtubeChannels && youtubeChannels.length;
|
const hasChannels = youtubeChannels && youtubeChannels.length;
|
||||||
const transferEnabled = youtubeChannels && youtubeChannels.some(el => el.transferable === true);
|
|
||||||
const transferComplete =
|
|
||||||
youtubeChannels &&
|
|
||||||
youtubeChannels.some(({ transfer_state: transferState }) => transferState === COMPLETED_TRANSFER);
|
|
||||||
|
|
||||||
let youtubeUrls =
|
let transferEnabled = false;
|
||||||
youtubeChannels &&
|
let transferStarted = false;
|
||||||
youtubeChannels.map(
|
let transferComplete = false;
|
||||||
({ lbry_channel_name: channelName, channel_claim_id: claimId }) => `lbry://${channelName}#${claimId}`
|
if (hasChannels) {
|
||||||
);
|
for (var i = 0; i < youtubeChannels.length; i++) {
|
||||||
|
const { transfer_state: transferState, transferable } = youtubeChannels[i];
|
||||||
|
if (transferable) {
|
||||||
|
transferEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transferState === COMPLETED_TRANSFER) {
|
||||||
|
transferComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transferState === PENDING_TRANSFER) {
|
||||||
|
transferStarted = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let total;
|
let total;
|
||||||
let complete;
|
let complete;
|
||||||
|
@ -44,7 +52,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
||||||
const { transferable, transfer_state: transferState, sync_status: syncStatus } = channel;
|
const { transferable, transfer_state: transferState, sync_status: syncStatus } = channel;
|
||||||
if (!transferable) {
|
if (!transferable) {
|
||||||
switch (transferState) {
|
switch (transferState) {
|
||||||
case NOT_TRANSFERED:
|
case NOT_TRANSFERRED:
|
||||||
return syncStatus[0].toUpperCase() + syncStatus.slice(1);
|
return syncStatus[0].toUpperCase() + syncStatus.slice(1);
|
||||||
case PENDING_TRANSFER:
|
case PENDING_TRANSFER:
|
||||||
return __('Transfer in progress');
|
return __('Transfer in progress');
|
||||||
|
@ -58,7 +66,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// If a channel is transferrable, theres nothing to check
|
// If a channel is transferrable, theres nothing to check
|
||||||
if (!transferComplete) {
|
if (transferStarted && !transferComplete) {
|
||||||
checkYoutubeTransfer();
|
checkYoutubeTransfer();
|
||||||
|
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
|
@ -70,30 +78,29 @@ export default function YoutubeTransferStatus(props: Props) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [transferComplete, checkYoutubeTransfer, updateUser]);
|
}, [transferComplete, transferStarted, checkYoutubeTransfer, updateUser]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
hasChannels &&
|
hasChannels &&
|
||||||
!transferComplete && (
|
!transferComplete && (
|
||||||
<div>
|
<div>
|
||||||
<Card
|
<Card
|
||||||
title={youtubeUrls.length > 1 ? __('Your YouTube Channels') : __('Your YouTube Channel')}
|
title={youtubeChannels.length > 1 ? __('Your YouTube Channels') : __('Your YouTube Channel')}
|
||||||
subtitle={
|
subtitle={
|
||||||
<span>
|
<span>
|
||||||
{__('Your videos are currently being transferred. There is nothing else for you to do.')}{' '}
|
{transferStarted
|
||||||
<Button button="link" href={LBRY_YT_URL} label={__('Learn more')} />.
|
? __('Your videos are currently being transferred. There is nothing else for you to do.')
|
||||||
|
: __('Your videos are ready to be transferred.')}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
body={
|
body={
|
||||||
<section>
|
<section>
|
||||||
{youtubeUrls.map((url, index) => {
|
{youtubeChannels.map((channel, index) => {
|
||||||
const channel = youtubeChannels[index];
|
const { lbry_channel_name: channelName, channel_claim_id: claimId } = channel;
|
||||||
|
const url = `lbry://${channelName}#${claimId}`;
|
||||||
const transferState = getMessage(channel);
|
const transferState = getMessage(channel);
|
||||||
return (
|
return (
|
||||||
<div
|
<div key={url} className="card--inline">
|
||||||
key={url}
|
|
||||||
style={{ border: '1px solid #ccc', borderRadius: 'var(--card-radius)', marginBottom: '1rem' }}
|
|
||||||
>
|
|
||||||
<ClaimPreview uri={url} actions={<span className="help">{transferState}</span>} properties={''} />
|
<ClaimPreview uri={url} actions={<span className="help">{transferState}</span>} properties={''} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
17
src/ui/effects/use-fetched.js
Normal file
17
src/ui/effects/use-fetched.js
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import usePrevious from 'effects/use-previous';
|
||||||
|
|
||||||
|
// Returns true once a loading value has changed from false => true => false
|
||||||
|
export default function useFetched(fetching: boolean) {
|
||||||
|
const wasFetching = usePrevious(fetching);
|
||||||
|
const [fetched, setFetched] = React.useState(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (wasFetching && !fetching) {
|
||||||
|
setFetched(true);
|
||||||
|
}
|
||||||
|
}, [wasFetching, fetching, setFetched]);
|
||||||
|
|
||||||
|
return fetched;
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
||||||
import { Modal } from 'modal/modal';
|
import { Modal } from 'modal/modal';
|
||||||
import { Form, FormField } from 'component/common/form';
|
import { Form, FormField } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import usePersistedState from 'util/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
|
|
@ -16,7 +16,7 @@ function DiscoverPage(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
{email && <TagsSelect showClose title={__('Customize Your Homepage')} />}
|
{(email || !IS_WEB) && <TagsSelect showClose title={__('Customize Your Homepage')} />}
|
||||||
<ClaimListDiscover
|
<ClaimListDiscover
|
||||||
hideCustomization={IS_WEB && !email}
|
hideCustomization={IS_WEB && !email}
|
||||||
personalView
|
personalView
|
||||||
|
|
|
@ -38,9 +38,7 @@ function FollowingPage(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<div className="card card--section">
|
<TagsSelect showClose={false} title={__('Follow New Tags')} />
|
||||||
<TagsSelect showClose={false} title={__('Customize Your Tags')} />
|
|
||||||
</div>
|
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<ClaimList
|
<ClaimList
|
||||||
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
|
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React, { useRef } from 'react';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import ClaimListDiscover from 'component/claimListDiscover';
|
import ClaimListDiscover from 'component/claimListDiscover';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import useHover from 'util/use-hover';
|
import useHover from 'effects/use-hover';
|
||||||
import analytics from 'analytics';
|
import analytics from 'analytics';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
makeSelectClaimIsMine,
|
makeSelectClaimIsMine,
|
||||||
doPopulateSharedUserState,
|
doPopulateSharedUserState,
|
||||||
doFetchChannelListMine,
|
doFetchChannelListMine,
|
||||||
|
getSync,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import Native from 'native';
|
import Native from 'native';
|
||||||
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||||
|
@ -454,6 +455,8 @@ export function doSignIn() {
|
||||||
dispatch(doBalanceSubscribe());
|
dispatch(doBalanceSubscribe());
|
||||||
dispatch(doCheckSubscriptionsInit());
|
dispatch(doCheckSubscriptionsInit());
|
||||||
dispatch(doFetchChannelListMine());
|
dispatch(doFetchChannelListMine());
|
||||||
|
dispatch(getSync());
|
||||||
|
|
||||||
// @endif
|
// @endif
|
||||||
|
|
||||||
Lbryio.call('user_settings', 'get').then(settings => {
|
Lbryio.call('user_settings', 'get').then(settings => {
|
||||||
|
|
|
@ -55,15 +55,20 @@
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// "cards" inside cards
|
||||||
.card--inline {
|
.card--inline {
|
||||||
box-shadow: none;
|
border: 1px solid $lbry-gray-1;
|
||||||
border-radius: none;
|
border-radius: var(--card-radius);
|
||||||
margin-bottom: 0;
|
|
||||||
|
[data-mode='dark'] & {
|
||||||
|
border-color: var(--dm-color-03);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card--claim-preview-wrap {
|
.card--claim-preview-wrap {
|
||||||
@extend .card;
|
@extend .card;
|
||||||
margin: var(--spacing-xlarge) 0;
|
margin: var(--spacing-xlarge) 0;
|
||||||
|
min-width: 35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card--claim-preview-selected {
|
.card--claim-preview-selected {
|
||||||
|
@ -241,7 +246,7 @@
|
||||||
|
|
||||||
.card__main-actions {
|
.card__main-actions {
|
||||||
padding: var(--spacing-large);
|
padding: var(--spacing-large);
|
||||||
background-color: rgba($lbry-blue-1, 0.1);
|
background-color: var(--color-card-actions);
|
||||||
color: darken($lbry-gray-5, 15%);
|
color: darken($lbry-gray-5, 15%);
|
||||||
font-size: var(--font-body);
|
font-size: var(--font-body);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
$border-color: rgba($lbry-teal-5, 0.1);
|
$border-color: rgba($lbry-teal-5, 0.1);
|
||||||
$border-color--dark: var(--dm-color-04);
|
$border-color--dark: var(--dm-color-04);
|
||||||
|
|
||||||
|
.claim-list {
|
||||||
|
.claim-preview {
|
||||||
|
border-top: 1px solid $border-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.claim-list__header {
|
.claim-list__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -85,6 +91,7 @@ $border-color--dark: var(--dm-color-04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.claim-preview {
|
.claim-preview {
|
||||||
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
@ -99,14 +106,6 @@ $border-color--dark: var(--dm-color-04);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-right: var(--spacing-medium);
|
margin-right: var(--spacing-medium);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.claim-preview {
|
|
||||||
border-top: 1px solid $border-color;
|
|
||||||
|
|
||||||
&:only-of-type {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
[data-mode='dark'] & {
|
[data-mode='dark'] & {
|
||||||
color: $lbry-white;
|
color: $lbry-white;
|
||||||
|
@ -114,14 +113,6 @@ $border-color--dark: var(--dm-color-04);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.claim-preview--injected + .claim-preview {
|
|
||||||
border-top: 1px solid $border-color;
|
|
||||||
|
|
||||||
[data-mode='dark'] & {
|
|
||||||
border-color: $border-color--dark;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.claim-preview--large {
|
.claim-preview--large {
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
.icon__wrapper {
|
.icon__wrapper {
|
||||||
@extend .card__subtitle;
|
background-color: var(--color-card-actions);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
|
@ -66,10 +66,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.main--contained {
|
.main--contained {
|
||||||
max-width: 40rem;
|
|
||||||
min-width: 25rem;
|
|
||||||
margin: auto;
|
margin: auto;
|
||||||
margin-top: 5rem;
|
margin-top: 5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
max-width: 40rem;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main--full-width {
|
.main--full-width {
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
font-size: var(--font-multiplier-small);
|
font-size: var(--font-multiplier-small);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navigation-links__inline {
|
||||||
|
margin-left: 1.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
.navigation-link__wrapper {
|
.navigation-link__wrapper {
|
||||||
margin: var(--spacing-miniscule) 0;
|
margin: var(--spacing-miniscule) 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ $large-breakpoint: 1921px;
|
||||||
// Color
|
// Color
|
||||||
--color-background: #f7f7f7;
|
--color-background: #f7f7f7;
|
||||||
--color-background--splash: #270f34;
|
--color-background--splash: #270f34;
|
||||||
|
--color-card-actions: #f7fbfe;
|
||||||
|
|
||||||
// Dark Mode
|
// Dark Mode
|
||||||
--dm-color-01: #ddd;
|
--dm-color-01: #ddd;
|
||||||
|
|
|
@ -6850,9 +6850,9 @@ lazy-val@^1.0.3, lazy-val@^1.0.4:
|
||||||
yargs "^13.2.2"
|
yargs "^13.2.2"
|
||||||
zstd-codec "^0.1.1"
|
zstd-codec "^0.1.1"
|
||||||
|
|
||||||
lbry-redux@lbryio/lbry-redux#d44cd9ca56dee784dba42c0cc13061ae75cbd46c:
|
lbry-redux@lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/d44cd9ca56dee784dba42c0cc13061ae75cbd46c"
|
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/42bf926138872d14523be7191694309be4f37605"
|
||||||
dependencies:
|
dependencies:
|
||||||
proxy-polyfill "0.1.6"
|
proxy-polyfill "0.1.6"
|
||||||
reselect "^3.0.0"
|
reselect "^3.0.0"
|
||||||
|
|
Loading…
Reference in a new issue