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='^analytics\(.*\)$' -> '<PROJECT_ROOT>/src/ui/analytics\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'
|
||||
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
"husky": "^0.14.3",
|
||||
"json-loader": "^0.5.4",
|
||||
"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",
|
||||
"lint-staged": "^7.0.2",
|
||||
"localforage": "^1.7.1",
|
||||
|
|
|
@ -11,8 +11,7 @@ import useKonamiListener from 'util/enhanced-layout';
|
|||
import Yrbl from 'component/yrbl';
|
||||
import FileViewer from 'component/fileViewer';
|
||||
import { withRouter } from 'react-router';
|
||||
import usePrevious from 'util/use-previous';
|
||||
import SyncBackgroundManager from 'component/syncBackgroundManager';
|
||||
import usePrevious from 'effects/use-previous';
|
||||
import Button from 'component/button';
|
||||
|
||||
export const MAIN_WRAPPER_CLASS = 'main-wrapper';
|
||||
|
@ -121,7 +120,6 @@ function App(props: Props) {
|
|||
<Router />
|
||||
<ModalRouter />
|
||||
<FileViewer pageUri={uri} />
|
||||
<SyncBackgroundManager />
|
||||
|
||||
{/* @if TARGET='app' */}
|
||||
{showUpgradeButton && (
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as ICONS from 'constants/icons';
|
|||
import * as PAGES from 'constants/pages';
|
||||
import React, { useRef } from 'react';
|
||||
import Button from 'component/button';
|
||||
import useHover from 'util/use-hover';
|
||||
import useHover from 'effects/use-hover';
|
||||
|
||||
type Props = {
|
||||
permanentUrl: ?string,
|
||||
|
|
|
@ -64,7 +64,7 @@ function ChannelContent(props: Props) {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{!channelIsMine && <HiddenNsfwClaims className="card__subtitle" uri={uri} />}
|
||||
{!channelIsMine && <HiddenNsfwClaims uri={uri} />}
|
||||
|
||||
{hasContent && !channelIsBlocked && !channelIsBlackListed && (
|
||||
<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 })}
|
||||
/>
|
||||
<TagSelect
|
||||
title={false}
|
||||
title={__('Add Tags')}
|
||||
suggestMature
|
||||
help={__('The better your tags are, the easier it will be for people to discover your channel.')}
|
||||
empty={__('No tags added')}
|
||||
|
|
|
@ -6,7 +6,7 @@ import classnames from 'classnames';
|
|||
import ClaimPreview from 'component/claimPreview';
|
||||
import Spinner from 'component/spinner';
|
||||
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_OLD = 'old';
|
||||
|
|
|
@ -187,9 +187,9 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
|||
<div className="claim-preview-title">
|
||||
{claim ? <TruncatedText text={title || claim.name} lines={1} /> : <span>{__('Nothing here')}</span>}
|
||||
</div>
|
||||
{actions !== undefined
|
||||
? actions
|
||||
: !hideActions && (
|
||||
{!hideActions && actions !== undefined ? (
|
||||
actions
|
||||
) : (
|
||||
<div className="card__actions--inline">
|
||||
{isChannel && !channelIsBlocked && !claimIsMine && (
|
||||
<SubscribeButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
|
||||
|
|
|
@ -5,7 +5,7 @@ import { FormField, Form } from 'component/common/form';
|
|||
import Button from 'component/button';
|
||||
import ChannelSection from 'component/selectChannel';
|
||||
import UnsupportedOnWeb from 'component/common/unsupported-on-web';
|
||||
import usePersistedState from 'util/use-persisted-state';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
|
|
@ -5,7 +5,7 @@ import classnames from 'classnames';
|
|||
import Icon from 'component/common/icon';
|
||||
|
||||
type Props = {
|
||||
title: string | Node,
|
||||
title?: string | Node,
|
||||
subtitle?: string | Node,
|
||||
body?: string | Node,
|
||||
actions?: string | Node,
|
||||
|
@ -16,6 +16,7 @@ export default function Card(props: Props) {
|
|||
const { title, subtitle, body, actions, icon } = props;
|
||||
return (
|
||||
<section className={classnames('card')}>
|
||||
{title && (
|
||||
<div className="card__header">
|
||||
<div className="section__flex">
|
||||
{icon && <Icon sectionIcon icon={icon} />}
|
||||
|
@ -25,6 +26,7 @@ export default function Card(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{body && <div className={classnames('card__body', { 'card__body--with-icon': icon })}>{body}</div>}
|
||||
{actions && (
|
||||
|
|
|
@ -6,8 +6,8 @@ import classnames from 'classnames';
|
|||
import LoadingScreen from 'component/common/loading-screen';
|
||||
import FileRender from 'component/fileRender';
|
||||
import UriIndicator from 'component/uriIndicator';
|
||||
import usePersistedState from 'util/use-persisted-state';
|
||||
import usePrevious from 'util/use-previous';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
import usePrevious from 'effects/use-previous';
|
||||
import { FILE_WRAPPER_CLASS } from 'page/file/view';
|
||||
import Draggable from 'react-draggable';
|
||||
import Tooltip from 'component/common/tooltip';
|
||||
|
@ -86,7 +86,7 @@ export default function FileViewer(props: Props) {
|
|||
function handleResize() {
|
||||
const element = document.querySelector(`.${FILE_WRAPPER_CLASS}`);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import classnames from 'classnames';
|
||||
|
||||
type Props = {
|
||||
numberOfNsfwClaims: number,
|
||||
|
@ -10,12 +9,12 @@ type Props = {
|
|||
};
|
||||
|
||||
export default (props: Props) => {
|
||||
const { numberOfNsfwClaims, obscureNsfw, className } = props;
|
||||
const { numberOfNsfwClaims, obscureNsfw } = props;
|
||||
|
||||
return (
|
||||
obscureNsfw &&
|
||||
Boolean(numberOfNsfwClaims) && (
|
||||
<div className={classnames('card--section', className || 'help')}>
|
||||
<div className="section--padded section__subtitle">
|
||||
{numberOfNsfwClaims} {numberOfNsfwClaims > 1 ? __('files') : __('file')} {__('hidden due to your')}{' '}
|
||||
<Button button="link" navigate="/$/settings" label={__('content viewing preferences')} />.
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
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 Button from 'component/button';
|
||||
import LicenseType from './license-type';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
type Props = {
|
||||
language: ?string,
|
||||
|
@ -25,7 +26,9 @@ function PublishAdvanced(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<section className="card card--section">
|
||||
<Card
|
||||
actions={
|
||||
<React.Fragment>
|
||||
{!hideSection && (
|
||||
<div className={classnames({ 'card--disabled': !name })}>
|
||||
<FormField
|
||||
|
@ -83,9 +86,15 @@ function PublishAdvanced(props: Props) {
|
|||
)}
|
||||
|
||||
<div className="card__actions">
|
||||
<Button label={hideSection ? __('Additional Options') : __('Hide')} button="link" onClick={toggleHideSection} />
|
||||
<Button
|
||||
label={hideSection ? __('Additional Options') : __('Hide')}
|
||||
button="link"
|
||||
onClick={toggleHideSection}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
// @flow
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React from 'react';
|
||||
import { regexInvalidURI } from 'lbry-redux';
|
||||
import classnames from 'classnames';
|
||||
import FileSelector from 'component/common/file-selector';
|
||||
import Button from 'component/button';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
type Props = {
|
||||
name: ?string,
|
||||
|
@ -11,10 +12,11 @@ type Props = {
|
|||
isStillEditing: boolean,
|
||||
balance: number,
|
||||
updatePublishForm: ({}) => void,
|
||||
disabled: boolean,
|
||||
};
|
||||
|
||||
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) {
|
||||
const publishFormParams: { filePath: string, name?: string } = { filePath };
|
||||
|
@ -28,15 +30,14 @@ function PublishFile(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<section
|
||||
className={classnames('card card--section', {
|
||||
'card--disabled': balance === 0,
|
||||
})}
|
||||
>
|
||||
<h2 className="card__title">{isStillEditing ? __('Edit') : __('Publish')}</h2>
|
||||
{isStillEditing && <p className="card__subtitle">{__('You are currently editing a claim.')}</p>}
|
||||
|
||||
<div className="card__content">
|
||||
<Card
|
||||
className={disabled ? 'card--disabled' : undefined}
|
||||
icon={ICONS.PUBLISH}
|
||||
disabled={balance === 0}
|
||||
title={isStillEditing ? __('Edit') : __('Publish')}
|
||||
subtitle={__('You are currently editing a claim.')}
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<FileSelector currentPath={filePath} onFileChosen={handleFileChange} />
|
||||
{!isStillEditing && (
|
||||
<p className="help">
|
||||
|
@ -49,8 +50,9 @@ function PublishFile(props: Props) {
|
|||
{__("If you don't choose a file, the file from your existing claim %name% will be used", { name: name })}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import PublishName from 'component/publishName';
|
|||
import PublishAdditionalOptions from 'component/publishAdditionalOptions';
|
||||
import PublishFormErrors from 'component/publishFormErrors';
|
||||
import SelectThumbnail from 'component/selectThumbnail';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
type Props = {
|
||||
tags: Array<Tag>,
|
||||
|
@ -127,13 +128,10 @@ function PublishForm(props: Props) {
|
|||
<PublishFile />
|
||||
<div className={classnames({ 'card--disabled': formDisabled })}>
|
||||
<PublishText disabled={formDisabled} />
|
||||
<div className="card card--section">
|
||||
{/* This should probably be PublishThumbnail */}
|
||||
<SelectThumbnail />
|
||||
</div>
|
||||
<div className="card card--section">
|
||||
<Card actions={<SelectThumbnail />} />
|
||||
|
||||
<TagSelect
|
||||
title={false}
|
||||
title={__('Add Tags')}
|
||||
suggestMature
|
||||
help={__('The better your tags are, the easier it will be for people to discover your content.')}
|
||||
empty={__('No tags added')}
|
||||
|
@ -148,14 +146,18 @@ function PublishForm(props: Props) {
|
|||
}}
|
||||
tagsChosen={tags}
|
||||
/>
|
||||
</div>
|
||||
<section className="card card--section">
|
||||
|
||||
<Card
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<ChannelSection channel={channel} onChannelChange={channel => updatePublishForm({ channel })} />
|
||||
<p className="help">
|
||||
{__('This is a username or handle that your content can be found under.')}{' '}
|
||||
{__('Ex. @Marvel, @TheBeatles, @BooksByJoe')}
|
||||
</p>
|
||||
</section>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
|
||||
<PublishName disabled={formDisabled} />
|
||||
<PublishPrice disabled={formDisabled} />
|
||||
|
|
|
@ -5,6 +5,7 @@ import { isNameValid } from 'lbry-redux';
|
|||
import { FormField } from 'component/common/form';
|
||||
import NameHelpText from './name-help-text';
|
||||
import BidHelpText from './bid-help-text';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
type Props = {
|
||||
name: string,
|
||||
|
@ -73,7 +74,9 @@ function PublishName(props: Props) {
|
|||
}, [bid, previousBidAmount, balance]);
|
||||
|
||||
return (
|
||||
<section className="card card--section">
|
||||
<Card
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<fieldset-group class="fieldset-group--smushed fieldset-group--disabled-prefix">
|
||||
<fieldset-section>
|
||||
<label>{__('Name')}</label>
|
||||
|
@ -111,10 +114,16 @@ function PublishName(props: Props) {
|
|||
disabled={!name}
|
||||
onChange={event => updatePublishForm({ bid: parseFloat(event.target.value) })}
|
||||
helper={
|
||||
<BidHelpText uri={uri} amountNeededForTakeover={amountNeededForTakeover} isResolvingUri={isResolvingUri} />
|
||||
<BidHelpText
|
||||
uri={uri}
|
||||
amountNeededForTakeover={amountNeededForTakeover}
|
||||
isResolvingUri={isResolvingUri}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import { FormField, FormFieldPrice } from 'component/common/form';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
type Props = {
|
||||
contentIsFree: boolean,
|
||||
|
@ -13,7 +14,9 @@ function PublishPrice(props: Props) {
|
|||
const { contentIsFree, fee, updatePublishForm, disabled } = props;
|
||||
|
||||
return (
|
||||
<section className="card card--section">
|
||||
<Card
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<FormField
|
||||
type="radio"
|
||||
name="content_free"
|
||||
|
@ -46,7 +49,9 @@ function PublishPrice(props: Props) {
|
|||
)}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
import React from 'react';
|
||||
import { FormField } from 'component/common/form';
|
||||
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 = {
|
||||
title: ?string,
|
||||
|
@ -19,7 +20,9 @@ function PublishText(props: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<section className="card card--section">
|
||||
<Card
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<FormField
|
||||
type="text"
|
||||
name="content_title"
|
||||
|
@ -40,9 +43,15 @@ function PublishText(props: Props) {
|
|||
onChange={value => updatePublishForm({ description: advancedEditor ? value : value.target.value })}
|
||||
/>
|
||||
<div className="card__actions">
|
||||
<Button button="link" onClick={toggleMarkdown} label={advancedEditor ? 'Simple Editor' : 'Advanced Editor'} />
|
||||
<Button
|
||||
button="link"
|
||||
onClick={toggleMarkdown}
|
||||
label={advancedEditor ? 'Simple Editor' : 'Advanced Editor'}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import TotalBackground from './total-background.png';
|
||||
import useTween from 'util/use-tween';
|
||||
import useTween from 'effects/use-tween';
|
||||
|
||||
type Props = {
|
||||
rewards: Array<Reward>,
|
||||
|
|
|
@ -69,7 +69,8 @@ function SideBar(props: Props) {
|
|||
className="navigation-link"
|
||||
activeClass="navigation-link--active"
|
||||
/>
|
||||
<ul className="navigation-links tags--vertical">
|
||||
<section className="navigation-links__inline">
|
||||
<ul className="navigation-links--small tags--vertical">
|
||||
{followedTags.map(({ name }, key) => (
|
||||
<li className="navigation-link__wrapper" key={name}>
|
||||
<Tag navigate={`/$/tags?t${name}`} name={name} />
|
||||
|
@ -88,6 +89,7 @@ function SideBar(props: Props) {
|
|||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</nav>
|
||||
</StickyBox>
|
||||
);
|
||||
|
|
|
@ -124,11 +124,6 @@ export default class SplashScreen extends React.PureComponent<Props, State> {
|
|||
clearTimeout(this.timeout);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Try to unlock by default here
|
||||
//
|
||||
//
|
||||
// Make sure there isn't another active modal (like INCOMPATIBLE_DAEMON)
|
||||
if (launchedModal === false && !modal) {
|
||||
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) {
|
||||
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({
|
||||
message: __('Blockchain Sync'),
|
||||
details: `${__('Catching up...')} (${__(format, wallet.blocks_behind)})`,
|
||||
details: `${__('Catching up...')} (${__(amountBehind, { amountBehind: wallet.blocks_behind })})`,
|
||||
});
|
||||
} else if (
|
||||
wallet &&
|
||||
|
|
|
@ -4,7 +4,7 @@ import * as ICONS from 'constants/icons';
|
|||
import React, { useRef } from 'react';
|
||||
import { parseURI } from 'lbry-redux';
|
||||
import Button from 'component/button';
|
||||
import useHover from 'util/use-hover';
|
||||
import useHover from 'effects/use-hover';
|
||||
|
||||
type SubscriptionArgs = {
|
||||
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 Tag from 'component/tag';
|
||||
import TagsSearch from 'component/tagsSearch';
|
||||
import usePersistedState from 'util/use-persisted-state';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
import analytics from 'analytics';
|
||||
import Card from 'component/common/card';
|
||||
|
||||
|
@ -73,7 +73,15 @@ export default function TagSelect(props: Props) {
|
|||
)}
|
||||
</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>
|
||||
<TagsSearch
|
||||
onRemove={handleTagClick}
|
||||
|
@ -81,12 +89,6 @@ export default function TagSelect(props: Props) {
|
|||
suggestMature={suggestMature && !hasMatureTag}
|
||||
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>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -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.'
|
||||
)}
|
||||
actions={
|
||||
!isVerified ? (
|
||||
<Button button="primary" label={__('Add Email')} navigate={`/$/${PAGES.AUTH}`} />
|
||||
) : (
|
||||
isVerified ? (
|
||||
<FormField
|
||||
type="text"
|
||||
className="form-field--copyable"
|
||||
|
@ -60,6 +58,8 @@ function UserEmail(props: Props) {
|
|||
inputButton={<UserSignOutButton button="inverse" />}
|
||||
value={email || ''}
|
||||
/>
|
||||
) : (
|
||||
<Button button="primary" label={__('Add Email')} navigate={`/$/${PAGES.AUTH}`} />
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -30,6 +30,7 @@ function UserEmailNew(props: Props) {
|
|||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
// Sync currently doesn't work for wallets with balances
|
||||
if (syncEnabled && balance) {
|
||||
setSync(false);
|
||||
}
|
||||
|
@ -56,7 +57,9 @@ function UserEmailNew(props: Props) {
|
|||
name="sync_checkbox"
|
||||
label={__('Sync your balance between devices')}
|
||||
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}
|
||||
onChange={() => setSync(!syncEnabled)}
|
||||
|
|
|
@ -33,9 +33,9 @@ const select = state => ({
|
|||
youtubeChannels: selectYoutubeChannels(state),
|
||||
userFetchPending: selectUserIsPending(state),
|
||||
syncEnabled: makeSelectClientSetting(SETTINGS.ENABLE_SYNC)(state),
|
||||
syncIsPending: selectGetSyncIsPending(state),
|
||||
syncingWallet: selectGetSyncIsPending(state),
|
||||
getSyncError: selectGetSyncErrorMessage(state),
|
||||
syncHash: selectSyncHash(state),
|
||||
hasSynced: Boolean(selectSyncHash(state)),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
|
|
|
@ -6,19 +6,11 @@ import UserEmailVerify from 'component/userEmailVerify';
|
|||
import UserFirstChannel from 'component/userFirstChannel';
|
||||
import { DEFAULT_BID_FOR_FIRST_CHANNEL } from 'component/userFirstChannel/view';
|
||||
import { rewards as REWARDS } from 'lbryinc';
|
||||
import usePrevious from 'util/use-previous';
|
||||
import UserVerify from 'component/userVerify';
|
||||
import Spinner from 'component/spinner';
|
||||
import YoutubeTransferWelcome from 'component/youtubeTransferWelcome';
|
||||
import SyncPassword from 'component/syncPassword';
|
||||
|
||||
/*
|
||||
- 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
|
||||
|
||||
*/
|
||||
import useFetched from 'effects/use-fetched';
|
||||
|
||||
type Props = {
|
||||
user: ?User,
|
||||
|
@ -33,24 +25,12 @@ type Props = {
|
|||
history: { replace: string => void },
|
||||
location: { search: string },
|
||||
youtubeChannels: Array<any>,
|
||||
syncIsPending: boolean,
|
||||
syncEnabled: boolean,
|
||||
hasSynced: boolean,
|
||||
syncingWallet: boolean,
|
||||
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) {
|
||||
const {
|
||||
emailToVerify,
|
||||
|
@ -65,9 +45,9 @@ function UserSignIn(props: Props) {
|
|||
fetchUser,
|
||||
youtubeChannels,
|
||||
syncEnabled,
|
||||
syncIsPending,
|
||||
syncingWallet,
|
||||
getSyncError,
|
||||
syncHash,
|
||||
hasSynced,
|
||||
fetchingChannels,
|
||||
} = props;
|
||||
const { search } = location;
|
||||
|
@ -76,52 +56,60 @@ function UserSignIn(props: Props) {
|
|||
const hasVerifiedEmail = user && user.has_verified_email;
|
||||
const rewardsApproved = user && user.is_reward_approved;
|
||||
const hasFetchedReward = useFetched(claimingReward);
|
||||
// const hasFetchedSync = useFetched(syncIsPending);
|
||||
// const hasTriedSyncForReal = syncEnabled && hasFetchedSync;
|
||||
const channelCount = channels ? channels.length : 0;
|
||||
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 hasPendingYoutubeTransfer =
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === 'pending_transfer');
|
||||
|
||||
React.useEffect(() => {
|
||||
if (
|
||||
hasVerifiedEmail &&
|
||||
balance !== undefined &&
|
||||
!hasClaimedEmailAward &&
|
||||
!hasFetchedReward &&
|
||||
(!syncEnabled || (syncEnabled && syncHash))
|
||||
) {
|
||||
claimReward();
|
||||
}
|
||||
}, [hasVerifiedEmail, claimReward, balance, hasClaimedEmailAward, hasFetchedReward, syncEnabled, syncHash]);
|
||||
// Complexity warning
|
||||
// We can't just check if we are currently fetching something
|
||||
// We may want to keep a component rendered while something is being fetched, instead of replacing it with the large spinner
|
||||
// The verbose variable names are an attempt to alleviate _some_ of the confusion from handling all edge cases that come from
|
||||
// reward claiming (plus the balance updating after), channel creation, account syncing, and youtube transfer
|
||||
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && balance === 0 && !getSyncError;
|
||||
const isCurrentlyFetchingSomething = fetchingChannels || claimingReward || syncingWallet;
|
||||
const isWaitingForSomethingToFinish =
|
||||
// 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);
|
||||
|
||||
// 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(() => {
|
||||
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 = [
|
||||
!emailToVerify && !hasVerifiedEmail && <UserEmailNew />,
|
||||
emailToVerify && !hasVerifiedEmail && <UserEmailVerify />,
|
||||
hasVerifiedEmail && !rewardsApproved && <UserVerify />,
|
||||
getSyncError && !syncHash && <SyncPassword />,
|
||||
hasVerifiedEmail && balance > DEFAULT_BID_FOR_FIRST_CHANNEL && channelCount === 0 && !hasYoutubeChannels && (
|
||||
<UserFirstChannel />
|
||||
),
|
||||
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)) && (
|
||||
showEmail && <UserEmailNew />,
|
||||
showEmailVerification && <UserEmailVerify />,
|
||||
showUserVerification && <UserVerify />,
|
||||
showSyncPassword && <SyncPassword />,
|
||||
showChannelCreation && <UserFirstChannel />,
|
||||
showYoutubeTransfer && <YoutubeTransferWelcome />,
|
||||
showLoadingSpinner && (
|
||||
<div className="main--empty">
|
||||
<Spinner />
|
||||
</div>
|
||||
|
|
|
@ -13,25 +13,33 @@ type Props = {
|
|||
videosImported: ?Array<number>, // [currentAmountImported, totalAmountToImport]
|
||||
};
|
||||
|
||||
const LBRY_YT_URL = 'https://lbry.com/youtube/status/';
|
||||
const NOT_TRANSFERED = 'not_transferred';
|
||||
const NOT_TRANSFERRED = 'not_transferred';
|
||||
const PENDING_TRANSFER = 'pending_transfer';
|
||||
const COMPLETED_TRANSFER = 'completed_transfer';
|
||||
|
||||
export default function YoutubeTransferStatus(props: Props) {
|
||||
const { youtubeChannels, ytImportPending, claimChannels, videosImported, checkYoutubeTransfer, updateUser } = props;
|
||||
|
||||
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 =
|
||||
youtubeChannels &&
|
||||
youtubeChannels.map(
|
||||
({ lbry_channel_name: channelName, channel_claim_id: claimId }) => `lbry://${channelName}#${claimId}`
|
||||
);
|
||||
let transferEnabled = false;
|
||||
let transferStarted = false;
|
||||
let transferComplete = false;
|
||||
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 complete;
|
||||
|
@ -44,7 +52,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
const { transferable, transfer_state: transferState, sync_status: syncStatus } = channel;
|
||||
if (!transferable) {
|
||||
switch (transferState) {
|
||||
case NOT_TRANSFERED:
|
||||
case NOT_TRANSFERRED:
|
||||
return syncStatus[0].toUpperCase() + syncStatus.slice(1);
|
||||
case PENDING_TRANSFER:
|
||||
return __('Transfer in progress');
|
||||
|
@ -58,7 +66,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
|
||||
React.useEffect(() => {
|
||||
// If a channel is transferrable, theres nothing to check
|
||||
if (!transferComplete) {
|
||||
if (transferStarted && !transferComplete) {
|
||||
checkYoutubeTransfer();
|
||||
|
||||
let interval = setInterval(() => {
|
||||
|
@ -70,30 +78,29 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
clearInterval(interval);
|
||||
};
|
||||
}
|
||||
}, [transferComplete, checkYoutubeTransfer, updateUser]);
|
||||
}, [transferComplete, transferStarted, checkYoutubeTransfer, updateUser]);
|
||||
|
||||
return (
|
||||
hasChannels &&
|
||||
!transferComplete && (
|
||||
<div>
|
||||
<Card
|
||||
title={youtubeUrls.length > 1 ? __('Your YouTube Channels') : __('Your YouTube Channel')}
|
||||
title={youtubeChannels.length > 1 ? __('Your YouTube Channels') : __('Your YouTube Channel')}
|
||||
subtitle={
|
||||
<span>
|
||||
{__('Your videos are currently being transferred. There is nothing else for you to do.')}{' '}
|
||||
<Button button="link" href={LBRY_YT_URL} label={__('Learn more')} />.
|
||||
{transferStarted
|
||||
? __('Your videos are currently being transferred. There is nothing else for you to do.')
|
||||
: __('Your videos are ready to be transferred.')}
|
||||
</span>
|
||||
}
|
||||
body={
|
||||
<section>
|
||||
{youtubeUrls.map((url, index) => {
|
||||
const channel = youtubeChannels[index];
|
||||
{youtubeChannels.map((channel, index) => {
|
||||
const { lbry_channel_name: channelName, channel_claim_id: claimId } = channel;
|
||||
const url = `lbry://${channelName}#${claimId}`;
|
||||
const transferState = getMessage(channel);
|
||||
return (
|
||||
<div
|
||||
key={url}
|
||||
style={{ border: '1px solid #ccc', borderRadius: 'var(--card-radius)', marginBottom: '1rem' }}
|
||||
>
|
||||
<div key={url} className="card--inline">
|
||||
<ClaimPreview uri={url} actions={<span className="help">{transferState}</span>} properties={''} />
|
||||
</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 { Form, FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import usePersistedState from 'util/use-persisted-state';
|
||||
import usePersistedState from 'effects/use-persisted-state';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
|
|
|
@ -16,7 +16,7 @@ function DiscoverPage(props: Props) {
|
|||
|
||||
return (
|
||||
<Page>
|
||||
{email && <TagsSelect showClose title={__('Customize Your Homepage')} />}
|
||||
{(email || !IS_WEB) && <TagsSelect showClose title={__('Customize Your Homepage')} />}
|
||||
<ClaimListDiscover
|
||||
hideCustomization={IS_WEB && !email}
|
||||
personalView
|
||||
|
|
|
@ -38,9 +38,7 @@ function FollowingPage(props: Props) {
|
|||
|
||||
return (
|
||||
<Page>
|
||||
<div className="card card--section">
|
||||
<TagsSelect showClose={false} title={__('Customize Your Tags')} />
|
||||
</div>
|
||||
<TagsSelect showClose={false} title={__('Follow New Tags')} />
|
||||
<div className="card">
|
||||
<ClaimList
|
||||
header={viewingSuggestedSubs ? __('Discover New Channels') : __('Channels You Follow')}
|
||||
|
|
|
@ -3,7 +3,7 @@ import React, { useRef } from 'react';
|
|||
import Page from 'component/page';
|
||||
import ClaimListDiscover from 'component/claimListDiscover';
|
||||
import Button from 'component/button';
|
||||
import useHover from 'util/use-hover';
|
||||
import useHover from 'effects/use-hover';
|
||||
import analytics from 'analytics';
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
makeSelectClaimIsMine,
|
||||
doPopulateSharedUserState,
|
||||
doFetchChannelListMine,
|
||||
getSync,
|
||||
} from 'lbry-redux';
|
||||
import Native from 'native';
|
||||
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||
|
@ -454,6 +455,8 @@ export function doSignIn() {
|
|||
dispatch(doBalanceSubscribe());
|
||||
dispatch(doCheckSubscriptionsInit());
|
||||
dispatch(doFetchChannelListMine());
|
||||
dispatch(getSync());
|
||||
|
||||
// @endif
|
||||
|
||||
Lbryio.call('user_settings', 'get').then(settings => {
|
||||
|
|
|
@ -55,15 +55,20 @@
|
|||
margin-right: auto;
|
||||
}
|
||||
|
||||
// "cards" inside cards
|
||||
.card--inline {
|
||||
box-shadow: none;
|
||||
border-radius: none;
|
||||
margin-bottom: 0;
|
||||
border: 1px solid $lbry-gray-1;
|
||||
border-radius: var(--card-radius);
|
||||
|
||||
[data-mode='dark'] & {
|
||||
border-color: var(--dm-color-03);
|
||||
}
|
||||
}
|
||||
|
||||
.card--claim-preview-wrap {
|
||||
@extend .card;
|
||||
margin: var(--spacing-xlarge) 0;
|
||||
min-width: 35rem;
|
||||
}
|
||||
|
||||
.card--claim-preview-selected {
|
||||
|
@ -241,7 +246,7 @@
|
|||
|
||||
.card__main-actions {
|
||||
padding: var(--spacing-large);
|
||||
background-color: rgba($lbry-blue-1, 0.1);
|
||||
background-color: var(--color-card-actions);
|
||||
color: darken($lbry-gray-5, 15%);
|
||||
font-size: var(--font-body);
|
||||
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
.claim-list__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
@ -85,6 +91,7 @@ $border-color--dark: var(--dm-color-04);
|
|||
}
|
||||
|
||||
.claim-preview {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
|
@ -99,14 +106,6 @@ $border-color--dark: var(--dm-color-04);
|
|||
flex-shrink: 0;
|
||||
margin-right: var(--spacing-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.claim-preview {
|
||||
border-top: 1px solid $border-color;
|
||||
|
||||
&:only-of-type {
|
||||
border: none;
|
||||
}
|
||||
|
||||
[data-mode='dark'] & {
|
||||
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 {
|
||||
border: none;
|
||||
padding: 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.icon__wrapper {
|
||||
@extend .card__subtitle;
|
||||
background-color: var(--color-card-actions);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
|
|
@ -66,10 +66,13 @@
|
|||
}
|
||||
|
||||
.main--contained {
|
||||
max-width: 40rem;
|
||||
min-width: 25rem;
|
||||
margin: auto;
|
||||
margin-top: 5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
max-width: 40rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.main--full-width {
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
font-size: var(--font-multiplier-small);
|
||||
}
|
||||
|
||||
.navigation-links__inline {
|
||||
margin-left: 1.7rem;
|
||||
}
|
||||
|
||||
.navigation-link__wrapper {
|
||||
margin: var(--spacing-miniscule) 0;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ $large-breakpoint: 1921px;
|
|||
// Color
|
||||
--color-background: #f7f7f7;
|
||||
--color-background--splash: #270f34;
|
||||
--color-card-actions: #f7fbfe;
|
||||
|
||||
// Dark Mode
|
||||
--dm-color-01: #ddd;
|
||||
|
|
|
@ -6850,9 +6850,9 @@ lazy-val@^1.0.3, lazy-val@^1.0.4:
|
|||
yargs "^13.2.2"
|
||||
zstd-codec "^0.1.1"
|
||||
|
||||
lbry-redux@lbryio/lbry-redux#d44cd9ca56dee784dba42c0cc13061ae75cbd46c:
|
||||
lbry-redux@lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605:
|
||||
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:
|
||||
proxy-polyfill "0.1.6"
|
||||
reselect "^3.0.0"
|
||||
|
|
Loading…
Reference in a new issue