pr feedback
This commit is contained in:
parent
044076ca1d
commit
bbcff99fb3
17 changed files with 92 additions and 80 deletions
2
flow-typed/18nj.js
vendored
Normal file
2
flow-typed/18nj.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
// @flow
|
||||
declare function __(a: string, b?: {}): string;
|
|
@ -128,8 +128,8 @@
|
|||
"husky": "^0.14.3",
|
||||
"json-loader": "^0.5.4",
|
||||
"lbry-format": "https://github.com/lbryio/lbry-format.git",
|
||||
"lbry-redux": "lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605",
|
||||
"lbryinc": "lbryio/lbryinc#368040d64658cf2a4b8a7a6725ec1787329ce65d",
|
||||
"lbry-redux": "lbryio/lbry-redux#04ae0913a444abac200731c7ed53796d763a0bbb",
|
||||
"lbryinc": "lbryio/lbryinc#a44576194e1f5f60e37d328ddfdca40bd6165c2d",
|
||||
"lint-staged": "^7.0.2",
|
||||
"localforage": "^1.7.1",
|
||||
"lodash-es": "^4.17.14",
|
||||
|
|
|
@ -22,10 +22,8 @@ const perform = dispatch => ({
|
|||
fetchTransactions: () => dispatch(doFetchTransactions()),
|
||||
fetchAccessToken: () => dispatch(doFetchAccessToken()),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
onSignedIn: () => dispatch(doSignIn()),
|
||||
signIn: () => dispatch(doSignIn()),
|
||||
requestDownloadUpgrade: () => dispatch(doDownloadUpgradeRequested()),
|
||||
fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
|
||||
onSignedIn: () => dispatch(doSignIn()),
|
||||
});
|
||||
|
||||
export default hot(
|
||||
|
|
|
@ -28,7 +28,7 @@ type Props = {
|
|||
fetchTransactions: () => void,
|
||||
fetchAccessToken: () => void,
|
||||
fetchChannelListMine: () => void,
|
||||
onSignedIn: () => void,
|
||||
signIn: () => void,
|
||||
requestDownloadUpgrade: () => void,
|
||||
fetchChannelListMine: () => void,
|
||||
onSignedIn: () => void,
|
||||
|
@ -45,7 +45,7 @@ function App(props: Props) {
|
|||
user,
|
||||
fetchAccessToken,
|
||||
fetchChannelListMine,
|
||||
onSignedIn,
|
||||
signIn,
|
||||
autoUpdateDownloaded,
|
||||
isUpgradeAvailable,
|
||||
requestDownloadUpgrade,
|
||||
|
@ -96,7 +96,7 @@ function App(props: Props) {
|
|||
if (previousHasVerifiedEmail === false && hasVerifiedEmail) {
|
||||
analytics.emailVerifiedEvent();
|
||||
}
|
||||
}, [previousHasVerifiedEmail, hasVerifiedEmail, onSignedIn]);
|
||||
}, [previousHasVerifiedEmail, hasVerifiedEmail, signIn]);
|
||||
|
||||
useEffect(() => {
|
||||
if (previousRewardApproved === false && isRewardApproved) {
|
||||
|
@ -107,9 +107,9 @@ function App(props: Props) {
|
|||
// Keep this at the end to ensure initial setup effects are run first
|
||||
useEffect(() => {
|
||||
if (!previousHasVerifiedEmail && hasVerifiedEmail) {
|
||||
onSignedIn();
|
||||
signIn();
|
||||
}
|
||||
}, [previousHasVerifiedEmail, hasVerifiedEmail, onSignedIn]);
|
||||
}, [previousHasVerifiedEmail, hasVerifiedEmail, signIn]);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
|
|
|
@ -75,16 +75,14 @@ class ErrorBoundary extends React.Component<Props, State> {
|
|||
title={__('Aw shucks!')}
|
||||
subtitle={
|
||||
<Fragment>
|
||||
<p>
|
||||
{__("There was an error. It's been reported and will be fixed")}. {__('Try')}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
className="load-screen__button"
|
||||
label={__('refreshing the app')}
|
||||
onClick={this.refresh}
|
||||
/>{' '}
|
||||
{__("to fix it. If that doesn't work, press CMD/CTRL-R to reset to the homepage.")}.
|
||||
</p>
|
||||
{__("There was an error. It's been reported and will be fixed")}. {__('Try')}{' '}
|
||||
<Button
|
||||
button="link"
|
||||
className="load-screen__button"
|
||||
label={__('refreshing the app')}
|
||||
onClick={this.refresh}
|
||||
/>{' '}
|
||||
{__("to fix it. If that doesn't work, press CMD/CTRL-R to reset to the homepage.")}.
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -31,9 +31,8 @@ function PublishFile(props: Props) {
|
|||
|
||||
return (
|
||||
<Card
|
||||
className={disabled ? 'card--disabled' : undefined}
|
||||
icon={ICONS.PUBLISH}
|
||||
disabled={balance === 0}
|
||||
disabled={disabled || balance === 0}
|
||||
title={isStillEditing ? __('Edit') : __('Publish')}
|
||||
subtitle={__('You are currently editing a claim.')}
|
||||
actions={
|
||||
|
|
|
@ -125,7 +125,7 @@ function PublishForm(props: Props) {
|
|||
<Fragment>
|
||||
<UnsupportedOnWeb />
|
||||
|
||||
<PublishFile />
|
||||
<PublishFile disabled={formDisabled} />
|
||||
<div className={classnames({ 'card--disabled': formDisabled })}>
|
||||
<PublishText disabled={formDisabled} />
|
||||
<Card actions={<SelectThumbnail />} />
|
||||
|
|
|
@ -37,7 +37,7 @@ function PublishPrice(props: Props) {
|
|||
{!contentIsFree && (
|
||||
<FormFieldPrice
|
||||
name="content_cost_amount"
|
||||
min="0"
|
||||
min={0}
|
||||
price={fee}
|
||||
onChange={newFee => updatePublishForm({ fee: newFee })}
|
||||
/>
|
||||
|
|
|
@ -5,7 +5,7 @@ import UserEmailNew from 'component/userEmailNew';
|
|||
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 { rewards as REWARDS, YOUTUBE_STATUSES } from 'lbryinc';
|
||||
import UserVerify from 'component/userVerify';
|
||||
import Spinner from 'component/spinner';
|
||||
import YoutubeTransferWelcome from 'component/youtubeTransferWelcome';
|
||||
|
@ -61,14 +61,14 @@ function UserSignIn(props: Props) {
|
|||
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');
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER);
|
||||
|
||||
// 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 && !hasClaimedEmailAward && balance === 0 && !getSyncError;
|
||||
const canHijackSignInFlowWithSpinner = hasVerifiedEmail && !getSyncError && balance === 0;
|
||||
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
|
||||
|
@ -116,15 +116,17 @@ function UserSignIn(props: Props) {
|
|||
),
|
||||
];
|
||||
|
||||
let componentToRender;
|
||||
for (var i = SIGN_IN_FLOW.length - 1; i > -1; i--) {
|
||||
const Component = SIGN_IN_FLOW[i];
|
||||
if (Component) {
|
||||
componentToRender = Component;
|
||||
break;
|
||||
function getSignInStep() {
|
||||
for (var i = SIGN_IN_FLOW.length - 1; i > -1; i--) {
|
||||
const Component = SIGN_IN_FLOW[i];
|
||||
if (Component) {
|
||||
return Component;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const componentToRender = getSignInStep();
|
||||
|
||||
if (!componentToRender) {
|
||||
history.replace(redirect || '/');
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import CopyableText from 'component/copyableText';
|
|||
import AdmZip from 'adm-zip';
|
||||
import path from 'path';
|
||||
import Card from 'component/common/card';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
||||
type Props = {
|
||||
daemonSettings: {
|
||||
|
@ -96,7 +97,7 @@ class WalletBackup extends React.PureComponent<Props, State> {
|
|||
<ul>
|
||||
<li>
|
||||
{__(
|
||||
'Your LBRY credits are controllable by you and only you, via wallet file(s) stored locally on your computer.'
|
||||
'Your LBRY credits are controllable by you and only you, via a wallet file stored locally on your computer.'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
|
@ -106,7 +107,7 @@ class WalletBackup extends React.PureComponent<Props, State> {
|
|||
</li>
|
||||
<li>
|
||||
{__(
|
||||
'However, it is fairly easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
|
||||
'However, it is easy to back up manually. To backup your wallet, make a copy of the folder listed below:'
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -115,12 +116,20 @@ class WalletBackup extends React.PureComponent<Props, State> {
|
|||
<React.Fragment>
|
||||
<CopyableText copyable={lbryumWalletDir} snackMessage={__('Path copied.')} />
|
||||
<p className="help">
|
||||
{__(
|
||||
'Access to these files are equivalent to having access to your credits. Keep any copies you make of your wallet in a secure place.'
|
||||
)}{' '}
|
||||
{/* @i18fixme */}
|
||||
{__('For more details on backing up and best practices')},{' '}
|
||||
<Button button="link" href="https://lbry.com/faq/how-to-backup-wallet" label={__('see this article')} />.
|
||||
<I18nMessage
|
||||
tokens={{
|
||||
helpLink: (
|
||||
<Button
|
||||
button="link"
|
||||
href="https://lbry.com/faq/how-to-backup-wallet"
|
||||
label={__('see this article')}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
>
|
||||
Access to these files are equivalent to having access to your credits. Keep any copies you make of your
|
||||
wallet in a secure place. For more details on backing up and best practices %helpLink%.
|
||||
</I18nMessage>
|
||||
</p>
|
||||
<p className={'card__message card__message--error' + (this.state.errorMessage ? '' : ' hidden')}>
|
||||
{this.state.errorMessage}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
selectYoutubeChannels,
|
||||
selectYTImportPending,
|
||||
selectYouTubeImportPending,
|
||||
selectUserIsPending,
|
||||
doClaimYoutubeChannels,
|
||||
doUserFetch,
|
||||
selectYTImportVideosComplete,
|
||||
selectYouTubeImportVideosComplete,
|
||||
doCheckYoutubeTransfer,
|
||||
} from 'lbryinc';
|
||||
import YoutubeChannelList from './view';
|
||||
|
||||
const select = state => ({
|
||||
youtubeChannels: selectYoutubeChannels(state),
|
||||
ytImportPending: selectYTImportPending(state),
|
||||
youtubeImportPending: selectYouTubeImportPending(state),
|
||||
userFetchPending: selectUserIsPending(state),
|
||||
videosImported: selectYTImportVideosComplete(state),
|
||||
videosImported: selectYouTubeImportVideosComplete(state),
|
||||
});
|
||||
|
||||
const perform = dispatch => ({
|
||||
|
|
|
@ -3,28 +3,33 @@ import * as React from 'react';
|
|||
import Button from 'component/button';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import Card from 'component/common/card';
|
||||
import { YOUTUBE_STATUSES } from 'lbryinc';
|
||||
import { buildURI } from 'lbry-redux';
|
||||
|
||||
type Props = {
|
||||
youtubeChannels: Array<any>,
|
||||
ytImportPending: boolean,
|
||||
youtubeImportPending: boolean,
|
||||
claimChannels: () => void,
|
||||
updateUser: () => void,
|
||||
checkYoutubeTransfer: () => void,
|
||||
videosImported: ?Array<number>, // [currentAmountImported, totalAmountToImport]
|
||||
};
|
||||
|
||||
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 {
|
||||
youtubeChannels,
|
||||
youtubeImportPending,
|
||||
claimChannels,
|
||||
videosImported,
|
||||
checkYoutubeTransfer,
|
||||
updateUser,
|
||||
} = props;
|
||||
const hasChannels = youtubeChannels && youtubeChannels.length;
|
||||
|
||||
const transferEnabled = youtubeChannels.some(status => status.transferable);
|
||||
const hasPendingTransfers = youtubeChannels.some(status => status.transfer_state === PENDING_TRANSFER);
|
||||
const hasCompleteTransfers = youtubeChannels.some(status => status.transfer_state === COMPLETED_TRANSFER);
|
||||
console.log('?', hasChannels && (hasPendingTransfers || (!hasPendingTransfers && !hasCompleteTransfers)));
|
||||
const hasPendingTransfers = youtubeChannels.some(
|
||||
status => status.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER
|
||||
);
|
||||
|
||||
let total;
|
||||
let complete;
|
||||
|
@ -37,11 +42,11 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
const { transferable, transfer_state: transferState, sync_status: syncStatus } = channel;
|
||||
if (!transferable) {
|
||||
switch (transferState) {
|
||||
case NOT_TRANSFERRED:
|
||||
case YOUTUBE_STATUSES.NOT_TRANSFERRED:
|
||||
return syncStatus[0].toUpperCase() + syncStatus.slice(1);
|
||||
case PENDING_TRANSFER:
|
||||
case YOUTUBE_STATUSES.PENDING_TRANSFER:
|
||||
return __('Transfer in progress');
|
||||
case COMPLETED_TRANSFER:
|
||||
case YOUTUBE_STATUSES.COMPLETED_TRANSFER:
|
||||
return __('Completed transfer');
|
||||
}
|
||||
} else {
|
||||
|
@ -82,7 +87,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
<section>
|
||||
{youtubeChannels.map((channel, index) => {
|
||||
const { lbry_channel_name: channelName, channel_claim_id: claimId } = channel;
|
||||
const url = `lbry://${channelName}#${claimId}`;
|
||||
const url = buildURI({ channelName, channelClaimId: claimId });
|
||||
const transferState = getMessage(channel);
|
||||
return (
|
||||
<div key={url} className="card--inline">
|
||||
|
@ -91,9 +96,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
);
|
||||
})}
|
||||
{videosImported && (
|
||||
<div className="section help">
|
||||
{complete} / {total} {__('videos transferred')}
|
||||
</div>
|
||||
<div className="section help">{__('%complete% / %total% videos transferred', { complete, total })}</div>
|
||||
)}
|
||||
</section>
|
||||
}
|
||||
|
@ -102,7 +105,7 @@ export default function YoutubeTransferStatus(props: Props) {
|
|||
<div className="card__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
disabled={ytImportPending}
|
||||
disabled={youtubeImportPending}
|
||||
onClick={claimChannels}
|
||||
label={youtubeChannels.length > 1 ? __('Claim Channels') : __('Claim Channel')}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import {
|
||||
selectYoutubeChannels,
|
||||
selectYTImportPending,
|
||||
selectYouTubeImportPending,
|
||||
selectUserIsPending,
|
||||
doClaimYoutubeChannels,
|
||||
doUserFetch,
|
||||
|
@ -10,7 +10,7 @@ import YoutubeChannelList from './view';
|
|||
|
||||
const select = state => ({
|
||||
youtubeChannels: selectYoutubeChannels(state),
|
||||
youtubeImportPending: selectYTImportPending(state),
|
||||
youtubeImportPending: selectYouTubeImportPending(state),
|
||||
userFetchPending: selectUserIsPending(state),
|
||||
});
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import classnames from 'classnames';
|
|||
import ClaimPreview from 'component/claimPreview';
|
||||
import Button from 'component/button';
|
||||
import Confetti from 'react-confetti';
|
||||
import { YOUTUBE_STATUSES } from 'lbryinc';
|
||||
|
||||
type Props = {
|
||||
youtubeChannels: Array<{ lbry_channel_name: string, channel_claim_id: string, transfer_state: string }>,
|
||||
|
@ -15,7 +16,7 @@ export default function UserYoutubeTransfer(props: Props) {
|
|||
const { youtubeChannels, claimChannels } = props;
|
||||
const hasYoutubeChannels = youtubeChannels && youtubeChannels.length;
|
||||
const hasPendingYoutubeTransfer =
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === 'pending_transfer');
|
||||
hasYoutubeChannels && youtubeChannels.some(channel => channel.transfer_state === YOUTUBE_STATUSES.PENDING_TRANSFER);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -27,7 +28,7 @@ export default function UserYoutubeTransfer(props: Props) {
|
|||
</React.Fragment>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<h1 className="section__title--large">{__('Good to Go!')}</h1>
|
||||
<h1 className="section__title--large">{__('Good To Go!')}</h1>
|
||||
<p className="section__subtitle">
|
||||
{__('You now control your channel and your videos are being transferred to your account.')}
|
||||
</p>
|
||||
|
@ -59,7 +60,6 @@ export default function UserYoutubeTransfer(props: Props) {
|
|||
) : (
|
||||
<section className="section">
|
||||
<h1 className="section__title">{__('Begin Transfer')}</h1>
|
||||
<p className="section__subtitle">{__('Do it to it.')}</p>
|
||||
<div className="section__actions">
|
||||
<Button button="primary" label={__('Transfer')} onClick={claimChannels} />
|
||||
</div>
|
||||
|
|
|
@ -11,6 +11,7 @@ import Native from 'native';
|
|||
import Button from 'component/button';
|
||||
import Page from 'component/page';
|
||||
import Card from 'component/common/card';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
||||
type DeamonSettings = {
|
||||
data_dir: string | any,
|
||||
|
@ -142,10 +143,10 @@ class HelpPage extends React.PureComponent<Props, State> {
|
|||
<Card
|
||||
title={__('Find Assistance')}
|
||||
subtitle={
|
||||
<p>
|
||||
{__('Live help is available most hours in the')} <strong>#help</strong>{' '}
|
||||
{__('channel of our Discord chat room. Or you can always email us at help@lbry.com.')}
|
||||
</p>
|
||||
<I18nMessage tokens={{ channel: <strong>#help</strong> }}>
|
||||
Live help is available most hours in the %channel% channel of our Discord chat room. Or you can always
|
||||
email us at help@lbry.com.
|
||||
</I18nMessage>
|
||||
}
|
||||
actions={
|
||||
<div className="section__actions">
|
||||
|
|
|
@ -16,7 +16,6 @@ import {
|
|||
makeSelectClaimIsMine,
|
||||
doPopulateSharedUserState,
|
||||
doFetchChannelListMine,
|
||||
getSync,
|
||||
} from 'lbry-redux';
|
||||
import Native from 'native';
|
||||
import { doFetchDaemonSettings } from 'redux/actions/settings';
|
||||
|
@ -32,7 +31,7 @@ import {
|
|||
selectUpgradeTimer,
|
||||
selectModal,
|
||||
} from 'redux/selectors/app';
|
||||
import { Lbryio, doAuthenticate } from 'lbryinc';
|
||||
import { Lbryio, doAuthenticate, doGetSync } from 'lbryinc';
|
||||
import { lbrySettings as config, version as appVersion } from 'package.json';
|
||||
import { push } from 'connected-react-router';
|
||||
import analytics from 'analytics';
|
||||
|
@ -451,12 +450,13 @@ export function doSignIn() {
|
|||
// @if TARGET='web'
|
||||
const { auth_token: authToken } = cookie.parse(document.cookie);
|
||||
Lbry.setApiHeader('X-Lbry-Auth-Token', authToken);
|
||||
|
||||
dispatch(doBalanceSubscribe());
|
||||
dispatch(doCheckSubscriptionsInit());
|
||||
dispatch(doFetchChannelListMine());
|
||||
dispatch(getSync());
|
||||
dispatch(doCheckSubscriptionsInit());
|
||||
// @endif
|
||||
|
||||
// @if TARGET='app'
|
||||
dispatch(doGetSync());
|
||||
// @endif
|
||||
|
||||
Lbryio.call('user_settings', 'get').then(settings => {
|
||||
|
|
|
@ -6850,17 +6850,17 @@ lazy-val@^1.0.3, lazy-val@^1.0.4:
|
|||
yargs "^13.2.2"
|
||||
zstd-codec "^0.1.1"
|
||||
|
||||
lbry-redux@lbryio/lbry-redux#42bf926138872d14523be7191694309be4f37605:
|
||||
lbry-redux@lbryio/lbry-redux#04ae0913a444abac200731c7ed53796d763a0bbb:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/42bf926138872d14523be7191694309be4f37605"
|
||||
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/04ae0913a444abac200731c7ed53796d763a0bbb"
|
||||
dependencies:
|
||||
proxy-polyfill "0.1.6"
|
||||
reselect "^3.0.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
lbryinc@lbryio/lbryinc#368040d64658cf2a4b8a7a6725ec1787329ce65d:
|
||||
lbryinc@lbryio/lbryinc#a44576194e1f5f60e37d328ddfdca40bd6165c2d:
|
||||
version "0.0.1"
|
||||
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/368040d64658cf2a4b8a7a6725ec1787329ce65d"
|
||||
resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/a44576194e1f5f60e37d328ddfdca40bd6165c2d"
|
||||
dependencies:
|
||||
reselect "^3.0.0"
|
||||
|
||||
|
|
Loading…
Reference in a new issue