Merge pull request #1593 from lbryio/downloads-pending
handle fetching state on downloads and publishes pages
This commit is contained in:
commit
1c55774165
10 changed files with 101 additions and 661 deletions
|
@ -89,9 +89,6 @@
|
|||
"babel-preset-env": "^1.6.1",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.18.0",
|
||||
"danger": "^3.6.0",
|
||||
"danger-plugin-eslint": "^0.1.0",
|
||||
"danger-plugin-yarn": "^1.3.0",
|
||||
"decompress": "^4.2.0",
|
||||
"del": "^3.0.0",
|
||||
"devtron": "^1.4.0",
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Spinner from 'component/spinner';
|
||||
import { isShowingChildren } from 'util/dom';
|
||||
|
||||
// time in ms to wait to show loading spinner
|
||||
const LOADER_TIMEOUT = 1500;
|
||||
const LOADER_TIMEOUT = 1000;
|
||||
|
||||
type Props = {
|
||||
children: React.Node | Array<React.Node>,
|
||||
|
@ -21,23 +20,6 @@ type State = {
|
|||
};
|
||||
|
||||
class Page extends React.PureComponent<Props, State> {
|
||||
static getDerivedStateFromProps(nextProps: Props, prevState: State) {
|
||||
const { children } = nextProps;
|
||||
const { showLoader } = prevState;
|
||||
|
||||
// If we aren't showing the loader, don't bother updating
|
||||
if (!showLoader) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isShowingChildren(children)) {
|
||||
return {
|
||||
showLoader: false,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
@ -49,16 +31,29 @@ class Page extends React.PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { children } = this.props;
|
||||
const { loading } = this.props;
|
||||
if (loading) {
|
||||
this.beginLoadingTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isShowingChildren(children))
|
||||
this.loaderTimeout = setTimeout(() => {
|
||||
this.setState({ showLoader: true });
|
||||
}, LOADER_TIMEOUT);
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
const { loading } = this.props;
|
||||
if (!this.loaderTimeout && !prevProps.loading && loading) {
|
||||
this.beginLoadingTimeout();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.loaderTimeout = null;
|
||||
if (this.loaderTimeout) {
|
||||
clearTimeout(this.loaderTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
beginLoadingTimeout() {
|
||||
this.loaderTimeout = setTimeout(() => {
|
||||
this.setState({ showLoader: true });
|
||||
}, LOADER_TIMEOUT);
|
||||
}
|
||||
|
||||
loaderTimeout: ?TimeoutID;
|
||||
|
@ -67,10 +62,6 @@ class Page extends React.PureComponent<Props, State> {
|
|||
const { pageTitle, children, noPadding, extraPadding, notContained, loading } = this.props;
|
||||
const { showLoader } = this.state;
|
||||
|
||||
// We don't want to show the loading spinner right away if it will only flash on the
|
||||
// screen for a short time, wait until we know it will be loading for a bit before showing it
|
||||
const shouldShowLoader = !isShowingChildren(children) && showLoader;
|
||||
|
||||
return (
|
||||
<main
|
||||
className={classnames('main', {
|
||||
|
@ -85,7 +76,7 @@ class Page extends React.PureComponent<Props, State> {
|
|||
</div>
|
||||
)}
|
||||
{!loading && children}
|
||||
{shouldShowLoader && (
|
||||
{showLoader && (
|
||||
<div className="page__empty">
|
||||
<Spinner />
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectFileInfosDownloaded, selectMyClaimsWithoutChannels } from 'lbry-redux';
|
||||
import {
|
||||
selectFileInfosDownloaded,
|
||||
selectMyClaimsWithoutChannels,
|
||||
selectIsFetchingFileList,
|
||||
} from 'lbry-redux';
|
||||
import { doNavigate } from 'redux/actions/navigation';
|
||||
import FileListDownloaded from './view';
|
||||
|
||||
const select = state => ({
|
||||
fileInfos: selectFileInfosDownloaded(state),
|
||||
fetching: selectIsFetchingFileList(state),
|
||||
claims: selectMyClaimsWithoutChannels(state),
|
||||
});
|
||||
|
||||
|
@ -12,4 +17,7 @@ const perform = dispatch => ({
|
|||
navigate: path => dispatch(doNavigate(path)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(FileListDownloaded);
|
||||
export default connect(
|
||||
select,
|
||||
perform
|
||||
)(FileListDownloaded);
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import Button from 'component/button';
|
||||
import FileList from 'component/fileList';
|
||||
import Page from 'component/page';
|
||||
|
||||
class FileListDownloaded extends React.PureComponent {
|
||||
type Props = {
|
||||
fetching: boolean,
|
||||
fileInfos: {},
|
||||
navigate: (string, ?{}) => void,
|
||||
};
|
||||
|
||||
class FileListDownloaded extends React.PureComponent<Props> {
|
||||
render() {
|
||||
const { fileInfos, navigate } = this.props;
|
||||
const hasDownloads = fileInfos && fileInfos.length > 0;
|
||||
const { fetching, fileInfos, navigate } = this.props;
|
||||
const hasDownloads = fileInfos && Object.values(fileInfos).length > 0;
|
||||
|
||||
return (
|
||||
<Page notContained>
|
||||
<Page notContained loading={fetching}>
|
||||
{hasDownloads ? (
|
||||
<FileList fileInfos={fileInfos} />
|
||||
) : (
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectPendingPublishes, selectClaimsWithPendingPublishes } from 'redux/selectors/publish';
|
||||
import { selectIsFetchingClaimListMine } from 'lbry-redux';
|
||||
import { doNavigate } from 'redux/actions/navigation';
|
||||
import { doCheckPendingPublishes } from 'redux/actions/publish';
|
||||
import FileListPublished from './view';
|
||||
|
||||
const select = state => ({
|
||||
claims: selectClaimsWithPendingPublishes(state),
|
||||
fetching: selectIsFetchingClaimListMine(state),
|
||||
pendingPublishes: selectPendingPublishes(state),
|
||||
});
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ type Props = {
|
|||
claims: Array<{}>,
|
||||
checkIfPublishesConfirmed: (Array<{}>) => void,
|
||||
navigate: (string, ?{}) => void,
|
||||
fetching: boolean,
|
||||
};
|
||||
|
||||
class FileListPublished extends React.PureComponent<Props> {
|
||||
|
@ -20,11 +21,11 @@ class FileListPublished extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { claims, navigate } = this.props;
|
||||
const { fetching, claims, navigate } = this.props;
|
||||
|
||||
return (
|
||||
<Page notContained>
|
||||
{claims.length ? (
|
||||
<Page notContained loading={fetching}>
|
||||
{claims && claims.length ? (
|
||||
<FileList checkPending fileInfos={claims} sortByHeight />
|
||||
) : (
|
||||
<div className="page__empty">
|
||||
|
|
|
@ -11,15 +11,20 @@ import { setSubscriptionNotifications, doFetchMySubscriptions } from 'redux/acti
|
|||
import SubscriptionsPage from './view';
|
||||
|
||||
const select = state => ({
|
||||
isFetchingSubscriptions: selectIsFetchingSubscriptions(state),
|
||||
loading:
|
||||
selectIsFetchingSubscriptions(state) ||
|
||||
Object.keys(selectSubscriptionsBeingFetched(state)).length,
|
||||
subscriptionsBeingFetched: selectSubscriptionsBeingFetched(state),
|
||||
subscriptions: selectSubscriptions(state),
|
||||
subscriptionClaims: selectSubscriptionClaims(state),
|
||||
notifications: selectNotifications(state),
|
||||
});
|
||||
|
||||
export default connect(select, {
|
||||
export default connect(
|
||||
select,
|
||||
{
|
||||
doFetchClaimsByChannel,
|
||||
setSubscriptionNotifications,
|
||||
doFetchMySubscriptions,
|
||||
})(SubscriptionsPage);
|
||||
}
|
||||
)(SubscriptionsPage);
|
||||
|
|
|
@ -14,10 +14,10 @@ type Props = {
|
|||
doFetchMySubscriptions: () => void,
|
||||
setSubscriptionNotifications: ({}) => void,
|
||||
subscriptions: Array<Subscription>,
|
||||
isFetchingSubscriptions: boolean,
|
||||
subscriptionClaims: Array<{ uri: string, claims: Array<Claim> }>,
|
||||
subscriptionsBeingFetched: {},
|
||||
notifications: {},
|
||||
loading: boolean,
|
||||
};
|
||||
|
||||
export default class extends React.PureComponent<Props> {
|
||||
|
@ -52,10 +52,13 @@ export default class extends React.PureComponent<Props> {
|
|||
if (claim.claims.length) {
|
||||
subscriptionClaimMap[claim.uri] = 1;
|
||||
} else if (isDev) {
|
||||
console
|
||||
.error
|
||||
// `claim for ${claim.uri} was added to byId in redux but there are no loaded fetched claims`
|
||||
();
|
||||
// eslint-disable no-console
|
||||
console.error(
|
||||
`Claim for ${
|
||||
claim.uri
|
||||
} was added to byId in redux but there are no loaded fetched claims. This shouldn't happen because a subscription should have claims attached to it.`
|
||||
);
|
||||
// eslint-enable no-console
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -67,7 +70,7 @@ export default class extends React.PureComponent<Props> {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { subscriptions, subscriptionClaims, isFetchingSubscriptions } = this.props;
|
||||
const { subscriptions, subscriptionClaims, loading } = this.props;
|
||||
|
||||
let claimList = [];
|
||||
subscriptionClaims.forEach(claimData => {
|
||||
|
@ -77,7 +80,7 @@ export default class extends React.PureComponent<Props> {
|
|||
const subscriptionUris = claimList.map(claim => `lbry://${claim.name}#${claim.claim_id}`);
|
||||
|
||||
return (
|
||||
<Page notContained loading={isFetchingSubscriptions}>
|
||||
<Page notContained loading={loading}>
|
||||
<HiddenNsfwClaims uris={subscriptionUris} />
|
||||
{!subscriptions.length && (
|
||||
<div className="page__empty">
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// @flow
|
||||
import * as React from 'react';
|
||||
|
||||
// is a child component being rendered?
|
||||
export const isShowingChildren = (children: React.Node): boolean => {
|
||||
if (Array.isArray(children)) {
|
||||
const firstChildIndex = children.findIndex(child => child);
|
||||
return firstChildIndex > -1;
|
||||
}
|
||||
|
||||
return !!children;
|
||||
};
|
Loading…
Reference in a new issue