Merge pull request #4059 from lbryio/feat-claimListPaginate

paginate claim list
This commit is contained in:
jessopb 2020-05-01 14:26:20 -04:00 committed by GitHub
commit 104aa943ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 188 additions and 95 deletions

View file

@ -131,7 +131,7 @@
"imagesloaded": "^4.1.4", "imagesloaded": "^4.1.4",
"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#f8c26fbe34f49a9898d48b8a41c956b9ad4ff582", "lbry-redux": "lbryio/lbry-redux#58ff4d8086cf2d038e0f606f50e04d67efec596a",
"lbryinc": "lbryio/lbryinc#cc62a4eec10845cc0b31da7d0f27287cfa7c4866", "lbryinc": "lbryio/lbryinc#cc62a4eec10845cc0b31da7d0f27287cfa7c4866",
"lint-staged": "^7.0.2", "lint-staged": "^7.0.2",
"localforage": "^1.7.1", "localforage": "^1.7.1",

View file

@ -0,0 +1,13 @@
import { connect } from 'react-redux';
import { doOpenModal } from 'redux/actions/app';
import ClaimAbandonButton from './view';
import { makeSelectClaimForUri } from 'lbry-redux';
const select = (state, props) => ({
claim: props.uri && makeSelectClaimForUri(props.uri)(state),
});
export default connect(select, {
doOpenModal,
})(ClaimAbandonButton);

View file

@ -0,0 +1,21 @@
// @flow
import * as MODALS from 'constants/modal_types';
import * as ICONS from 'constants/icons';
import React from 'react';
import Button from 'component/button';
type Props = {
doOpenModal: (string, {}) => void,
claim: StreamClaim,
abandonActionCallback: any => void,
};
export default function ClaimAbandonButton(props: Props) {
const { doOpenModal, claim, abandonActionCallback } = props;
function abandonClaim() {
doOpenModal(MODALS.CONFIRM_CLAIM_REVOKE, { claim: claim, cb: abandonActionCallback });
}
return <Button button="secondary" icon={ICONS.DELETE} onClick={abandonClaim} />;
}

View file

@ -30,6 +30,8 @@ type Props = {
showUnresolvedClaims?: boolean, showUnresolvedClaims?: boolean,
renderProperties: ?(Claim) => Node, renderProperties: ?(Claim) => Node,
includeSupportAction?: boolean, includeSupportAction?: boolean,
includeOwnerActions?: boolean,
abandonActionCallback?: any => void,
hideBlock: boolean, hideBlock: boolean,
injectedItem: ?Node, injectedItem: ?Node,
timedOutMessage?: Node, timedOutMessage?: Node,
@ -55,6 +57,8 @@ export default function ClaimList(props: Props) {
showUnresolvedClaims, showUnresolvedClaims,
renderProperties, renderProperties,
includeSupportAction, includeSupportAction,
includeOwnerActions,
abandonActionCallback,
hideBlock, hideBlock,
injectedItem, injectedItem,
timedOutMessage, timedOutMessage,
@ -148,6 +152,8 @@ export default function ClaimList(props: Props) {
uri={uri} uri={uri}
type={type} type={type}
includeSupportAction={includeSupportAction} includeSupportAction={includeSupportAction}
includeOwnerActions={includeOwnerActions}
abandonActionCallback={abandonActionCallback}
showUnresolvedClaim={showUnresolvedClaims} showUnresolvedClaim={showUnresolvedClaims}
properties={renderProperties || (type !== 'small' ? undefined : false)} properties={renderProperties || (type !== 'small' ? undefined : false)}
showUserBlocked={showHiddenByUser} showUserBlocked={showHiddenByUser}

View file

@ -15,6 +15,7 @@ import SubscribeButton from 'component/subscribeButton';
import ChannelThumbnail from 'component/channelThumbnail'; import ChannelThumbnail from 'component/channelThumbnail';
import BlockButton from 'component/blockButton'; import BlockButton from 'component/blockButton';
import ClaimSupportButton from 'component/claimSupportButton'; import ClaimSupportButton from 'component/claimSupportButton';
import ClaimAbandonButton from 'component/claimAbandonButton';
import useGetThumbnail from 'effects/use-get-thumbnail'; import useGetThumbnail from 'effects/use-get-thumbnail';
import ClaimPreviewTitle from 'component/claimPreviewTitle'; import ClaimPreviewTitle from 'component/claimPreviewTitle';
import ClaimPreviewSubtitle from 'component/claimPreviewSubtitle'; import ClaimPreviewSubtitle from 'component/claimPreviewSubtitle';
@ -58,6 +59,8 @@ type Props = {
customShouldHide?: Claim => boolean, customShouldHide?: Claim => boolean,
showUnresolvedClaim?: boolean, showUnresolvedClaim?: boolean,
includeSupportAction?: boolean, includeSupportAction?: boolean,
includeOwnerActions?: boolean,
abandonActionCallback?: any => void,
}; };
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => { const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -90,6 +93,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
customShouldHide, customShouldHide,
showUnresolvedClaim, showUnresolvedClaim,
includeSupportAction, includeSupportAction,
includeOwnerActions,
abandonActionCallback,
} = props; } = props;
const shouldFetch = const shouldFetch =
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending); claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
@ -283,6 +288,9 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
<BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} /> <BlockButton uri={uri.startsWith('lbry://') ? uri : `lbry://${uri}`} />
)} )}
{includeSupportAction && <ClaimSupportButton uri={uri} />} {includeSupportAction && <ClaimSupportButton uri={uri} />}
{includeOwnerActions && (
<ClaimAbandonButton uri={uri} abandonActionCallback={abandonActionCallback} />
)}
</div> </div>
)} )}
</React.Fragment> </React.Fragment>

View file

@ -10,6 +10,7 @@ import {
doClearPublish, doClearPublish,
doUpdatePublishForm, doUpdatePublishForm,
doPrepareEdit, doPrepareEdit,
doCheckPublishNameAvailability,
} from 'lbry-redux'; } from 'lbry-redux';
import { doPublishDesktop } from 'redux/actions/publish'; import { doPublishDesktop } from 'redux/actions/publish';
import { selectUnclaimedRewardValue } from 'lbryinc'; import { selectUnclaimedRewardValue } from 'lbryinc';
@ -35,9 +36,7 @@ const perform = dispatch => ({
publish: filePath => dispatch(doPublishDesktop(filePath)), publish: filePath => dispatch(doPublishDesktop(filePath)),
prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)), prepareEdit: (claim, uri) => dispatch(doPrepareEdit(claim, uri)),
resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()), resetThumbnailStatus: () => dispatch(doResetThumbnailStatus()),
checkAvailability: name => dispatch(doCheckPublishNameAvailability(name)),
}); });
export default connect( export default connect(select, perform)(PublishPage);
select,
perform
)(PublishPage);

View file

@ -64,6 +64,7 @@ type Props = {
amountNeededForTakeover: ?number, amountNeededForTakeover: ?number,
// Add back type // Add back type
updatePublishForm: any => void, updatePublishForm: any => void,
checkAvailability: string => void,
}; };
function PublishForm(props: Props) { function PublishForm(props: Props) {
@ -86,6 +87,7 @@ function PublishForm(props: Props) {
tags, tags,
publish, publish,
disabled = false, disabled = false,
checkAvailability,
} = props; } = props;
const TAGS_LIMIT = 5; const TAGS_LIMIT = 5;
const formDisabled = (!filePath && !editingURI) || publishing; const formDisabled = (!filePath && !editingURI) || publishing;
@ -134,11 +136,12 @@ function PublishForm(props: Props) {
} }
const isValid = isURIValid(uri); const isValid = isURIValid(uri);
if (uri && isValid) { if (uri && isValid && checkAvailability && name) {
resolveUri(uri); resolveUri(uri);
checkAvailability(name);
updatePublishForm({ uri }); updatePublishForm({ uri });
} }
}, [name, channel, resolveUri, updatePublishForm]); }, [name, channel, resolveUri, updatePublishForm, checkAvailability]);
return ( return (
<div className="card-stack"> <div className="card-stack">

View file

@ -68,10 +68,10 @@ class SelectThumbnail extends React.PureComponent<Props, State> {
const actualFilePath = filePath || downloadPath; const actualFilePath = filePath || downloadPath;
let isSupportedVideo = false; let isSupportedVideo = false;
if (typeof filePath === 'string') { if (typeof actualFilePath === 'string') {
isSupportedVideo = Lbry.getMediaType(null, actualFilePath) === 'video'; isSupportedVideo = Lbry.getMediaType(null, actualFilePath) === 'video';
} else if (filePath && filePath.type) { } else if (actualFilePath && actualFilePath.type) {
isSupportedVideo = filePath.type.split('/')[0] === 'video'; isSupportedVideo = actualFilePath.type.split('/')[0] === 'video';
} }
let thumbnailSrc; let thumbnailSrc;

View file

@ -8,7 +8,6 @@ import {
makeSelectMetadataForUri, makeSelectMetadataForUri,
makeSelectClaimForUri, makeSelectClaimForUri,
doSupportAbandonForClaim, doSupportAbandonForClaim,
doFetchClaimListMine,
selectAbandonClaimSupportError, selectAbandonClaimSupportError,
} from 'lbry-redux'; } from 'lbry-redux';
import SupportsLiquidate from './view'; import SupportsLiquidate from './view';
@ -27,7 +26,6 @@ const select = (state, props) => ({
const perform = dispatch => ({ const perform = dispatch => ({
abandonSupportForClaim: (claimId, type, keep, preview) => abandonSupportForClaim: (claimId, type, keep, preview) =>
dispatch(doSupportAbandonForClaim(claimId, type, keep, preview)), dispatch(doSupportAbandonForClaim(claimId, type, keep, preview)),
fetchClaimListMine: () => dispatch(doFetchClaimListMine()),
}); });
export default connect(select, perform)(SupportsLiquidate); export default connect(select, perform)(SupportsLiquidate);

View file

@ -7,7 +7,7 @@ import DateTime from 'component/dateTime';
import Button from 'component/button'; import Button from 'component/button';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import { toCapitalCase } from 'util/string'; import { toCapitalCase } from 'util/string';
import { buildURI, parseURI, TXO_LIST as TXO, TXO_ABANDON_STATES as TXO_STATES } from 'lbry-redux'; import { buildURI, parseURI, TXO_LIST as TXO, ABANDON_STATES } from 'lbry-redux';
type Props = { type Props = {
txo: Txo, txo: Txo,
@ -25,20 +25,20 @@ type State = {
class TxoListItem extends React.PureComponent<Props, State> { class TxoListItem extends React.PureComponent<Props, State> {
constructor() { constructor() {
super(); super();
this.state = { abandonState: TXO_STATES.READY }; this.state = { abandonState: ABANDON_STATES.READY };
(this: any).abandonClaim = this.abandonClaim.bind(this); (this: any).abandonClaim = this.abandonClaim.bind(this);
(this: any).getLink = this.getLink.bind(this); (this: any).getLink = this.getLink.bind(this);
} }
getLink(type: string) { getLink(type: string) {
const { abandonState } = this.state; const { abandonState } = this.state;
if (this.state.abandonState === TXO_STATES.PENDING) { if (this.state.abandonState === ABANDON_STATES.PENDING) {
return <Spinner type={'small'} />; return <Spinner type={'small'} />;
} }
if (type === TXO.SUPPORT) { if (type === TXO.SUPPORT) {
return ( return (
<Button <Button
disabled={abandonState === TXO_STATES.DONE || abandonState === TXO_STATES.ERROR} disabled={abandonState === ABANDON_STATES.DONE || abandonState === ABANDON_STATES.ERROR}
button="secondary" button="secondary"
icon={ICONS.UNLOCK} icon={ICONS.UNLOCK}
onClick={this.abandonClaim} onClick={this.abandonClaim}
@ -49,7 +49,7 @@ class TxoListItem extends React.PureComponent<Props, State> {
const abandonTitle = type === TXO.SUPPORT ? 'Abandon Support' : 'Abandon Claim'; const abandonTitle = type === TXO.SUPPORT ? 'Abandon Support' : 'Abandon Claim';
return ( return (
<Button <Button
disabled={abandonState === TXO_STATES.DONE || abandonState === TXO_STATES.ERROR} disabled={abandonState === ABANDON_STATES.DONE || abandonState === ABANDON_STATES.ERROR}
button="secondary" button="secondary"
icon={ICONS.DELETE} icon={ICONS.DELETE}
onClick={this.abandonClaim} onClick={this.abandonClaim}

View file

@ -3,6 +3,9 @@ export const MINIMUM_PUBLISH_BID = 0.00001;
export const CHANNEL_ANONYMOUS = 'anonymous'; export const CHANNEL_ANONYMOUS = 'anonymous';
export const CHANNEL_NEW = 'new'; export const CHANNEL_NEW = 'new';
export const PAGE_SIZE = 20; export const PAGE_SIZE = 20;
export const PUBLISHES_PAGE_SIZE = 10;
export const PAGE_PARAM = 'page';
export const PAGE_SIZE_PARAM = 'page_size';
export const INVALID_NAME_ERROR = export const INVALID_NAME_ERROR =
__('LBRY names cannot contain spaces or reserved symbols') + ' ' + '($#@;/"<>%{}|^~[]`)'; __('LBRY names cannot contain spaces or reserved symbols') + ' ' + '($#@;/"<>%{}|^~[]`)';

View file

@ -11,7 +11,7 @@ import {
doClearRepostError, doClearRepostError,
doToast, doToast,
selectMyClaimsWithoutChannels, selectMyClaimsWithoutChannels,
doFetchClaimListMine, doCheckPublishNameAvailability,
} from 'lbry-redux'; } from 'lbry-redux';
import ModalRepost from './view'; import ModalRepost from './view';
@ -25,13 +25,10 @@ const select = (state, props) => ({
myClaims: selectMyClaimsWithoutChannels(state), myClaims: selectMyClaimsWithoutChannels(state),
}); });
export default connect( export default connect(select, {
select, doHideModal,
{ doRepost,
doHideModal, doClearRepostError,
doRepost, doToast,
doClearRepostError, doCheckPublishNameAvailability,
doToast, })(ModalRepost);
doFetchClaimListMine,
}
)(ModalRepost);

View file

@ -22,8 +22,7 @@ type Props = {
claim: ?StreamClaim, claim: ?StreamClaim,
balance: number, balance: number,
channels: ?Array<ChannelClaim>, channels: ?Array<ChannelClaim>,
myClaims: ?Array<StreamClaim>, doCheckPublishNameAvailability: string => Promise<*>,
doFetchClaimListMine: () => void,
error: ?string, error: ?string,
reposting: boolean, reposting: boolean,
}; };
@ -40,8 +39,7 @@ function ModalRepost(props: Props) {
channels, channels,
error, error,
reposting, reposting,
myClaims, doCheckPublishNameAvailability,
doFetchClaimListMine,
} = props; } = props;
const defaultName = claim && claim.name; const defaultName = claim && claim.name;
const contentClaimId = claim && claim.claim_id; const contentClaimId = claim && claim.claim_id;
@ -49,6 +47,7 @@ function ModalRepost(props: Props) {
const [repostBid, setRepostBid] = React.useState(0.01); const [repostBid, setRepostBid] = React.useState(0.01);
const [showAdvanced, setShowAdvanced] = React.useState(); const [showAdvanced, setShowAdvanced] = React.useState();
const [repostName, setRepostName] = React.useState(defaultName); const [repostName, setRepostName] = React.useState(defaultName);
const [available, setAvailable] = React.useState(true);
let repostBidError; let repostBidError;
if (repostBid === 0) { if (repostBid === 0) {
@ -66,12 +65,7 @@ function ModalRepost(props: Props) {
repostNameError = __('A name is required'); repostNameError = __('A name is required');
} else if (!isNameValid(repostName, false)) { } else if (!isNameValid(repostName, false)) {
repostNameError = INVALID_NAME_ERROR; repostNameError = INVALID_NAME_ERROR;
} else if ( } else if (!available) {
channels &&
channels.find(claim => claim.name === repostChannel) &&
myClaims &&
myClaims.find(claim => claim.name === repostName)
) {
repostNameError = __('You already have a claim with this name.'); repostNameError = __('You already have a claim with this name.');
} }
@ -91,12 +85,11 @@ function ModalRepost(props: Props) {
} }
}, [channelStrings]); }, [channelStrings]);
const myClaimsString = myClaims && myClaims.map(channel => channel.permanent_url).join(',');
React.useEffect(() => { React.useEffect(() => {
if (myClaimsString === '') { if (repostName && isNameValid(repostName, false)) {
doFetchClaimListMine(); doCheckPublishNameAvailability(repostName).then(r => setAvailable(r));
} }
}, [myClaimsString, doFetchClaimListMine]); }, [repostName, doCheckPublishNameAvailability]);
function handleSubmit() { function handleSubmit() {
const channelToRepostTo = channels && channels.find(channel => channel.name === repostChannel); const channelToRepostTo = channels && channels.find(channel => channel.name === repostChannel);

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doHideModal } from 'redux/actions/app'; import { doHideModal } from 'redux/actions/app';
import { doAbandonTxo, selectTransactionItems } from 'lbry-redux'; import { doAbandonTxo, doAbandonClaim, selectTransactionItems } from 'lbry-redux';
import ModalRevokeClaim from './view'; import ModalRevokeClaim from './view';
const select = state => ({ const select = state => ({
@ -10,6 +10,7 @@ const select = state => ({
const perform = dispatch => ({ const perform = dispatch => ({
closeModal: () => dispatch(doHideModal()), closeModal: () => dispatch(doHideModal()),
abandonTxo: (txo, cb) => dispatch(doAbandonTxo(txo, cb)), abandonTxo: (txo, cb) => dispatch(doAbandonTxo(txo, cb)),
abandonClaim: (txid, nout, cb) => dispatch(doAbandonClaim(txid, nout, cb)),
}); });
export default connect(select, perform)(ModalRevokeClaim); export default connect(select, perform)(ModalRevokeClaim);

View file

@ -7,13 +7,15 @@ import * as txnTypes from 'constants/transaction_types';
type Props = { type Props = {
closeModal: () => void, closeModal: () => void,
abandonTxo: (Txo, () => void) => void, abandonTxo: (Txo, () => void) => void,
abandonClaim: (string, number, ?() => void) => void,
tx: Txo, tx: Txo,
claim: GenericClaim,
cb: () => void, cb: () => void,
}; };
export default function ModalRevokeClaim(props: Props) { export default function ModalRevokeClaim(props: Props) {
const { tx, closeModal, abandonTxo, cb } = props; const { tx, claim, closeModal, abandonTxo, abandonClaim, cb } = props;
const { value_type: valueType, type, normalized_name: name } = tx; const { value_type: valueType, type, normalized_name: name } = tx || claim;
const [channelName, setChannelName] = useState(''); const [channelName, setChannelName] = useState('');
function getButtonLabel(type: string) { function getButtonLabel(type: string) {
@ -80,7 +82,7 @@ export default function ModalRevokeClaim(props: Props) {
} }
function revokeClaim() { function revokeClaim() {
abandonTxo(tx, cb); tx ? abandonTxo(tx, cb) : abandonClaim(claim.txid, claim.nout, cb);
closeModal(); closeModal();
} }

View file

@ -1,36 +1,39 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
selectIsFetchingClaimListMine, selectIsFetchingClaimListMine,
makeSelectMyStreamUrlsForPage, selectMyClaimsPage,
selectMyStreamUrlsCount, selectMyClaimsPageItemCount,
selectFetchingMyClaimsPageError,
doClearPublish, doClearPublish,
doFetchClaimListMine, doFetchClaimListMine,
} from 'lbry-redux'; } from 'lbry-redux';
import { selectUploadCount } from 'lbryinc';
import { doCheckPendingPublishesApp } from 'redux/actions/publish'; import { doCheckPendingPublishesApp } from 'redux/actions/publish';
import FileListPublished from './view'; import FileListPublished from './view';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { PUBLISHES_PAGE_SIZE, PAGE_PARAM, PAGE_SIZE_PARAM } from 'constants/claim';
const select = (state, props) => { const select = (state, props) => {
const { search } = props.location; const { search } = props.location;
const urlParams = new URLSearchParams(search); const urlParams = new URLSearchParams(search);
const page = Number(urlParams.get('page')) || 1; const page = Number(urlParams.get(PAGE_PARAM)) || '1';
const pageSize = urlParams.get(PAGE_SIZE_PARAM) || String(PUBLISHES_PAGE_SIZE);
return { return {
page, page,
urls: makeSelectMyStreamUrlsForPage(page)(state), pageSize,
urlTotal: selectMyStreamUrlsCount(state),
fetching: selectIsFetchingClaimListMine(state), fetching: selectIsFetchingClaimListMine(state),
urls: selectMyClaimsPage(state),
urlTotal: selectMyClaimsPageItemCount(state),
error: selectFetchingMyClaimsPageError(state),
uploadCount: selectUploadCount(state),
}; };
}; };
const perform = dispatch => ({ const perform = dispatch => ({
checkPendingPublishes: () => dispatch(doCheckPendingPublishesApp()), checkPendingPublishes: () => dispatch(doCheckPendingPublishesApp()),
fetchClaimListMine: () => dispatch(doFetchClaimListMine()), fetchClaimListMine: (page, pageSize) => dispatch(doFetchClaimListMine(page, pageSize)),
clearPublish: () => dispatch(doClearPublish()), clearPublish: () => dispatch(doClearPublish()),
}); });
export default withRouter( export default withRouter(connect(select, perform)(FileListPublished));
connect(
select,
perform
)(FileListPublished)
);

View file

@ -4,45 +4,86 @@ import Button from 'component/button';
import ClaimList from 'component/claimList'; import ClaimList from 'component/claimList';
import Page from 'component/page'; import Page from 'component/page';
import Paginate from 'component/common/paginate'; import Paginate from 'component/common/paginate';
import { PAGE_SIZE } from 'constants/claim'; import { PAGE_PARAM, PAGE_SIZE_PARAM } from 'constants/claim';
import WebUploadList from 'component/webUploadList'; import WebUploadList from 'component/webUploadList';
import Spinner from 'component/spinner'; import Spinner from 'component/spinner';
import Card from 'component/common/card';
type Props = { type Props = {
uploadCount: number,
checkPendingPublishes: () => void, checkPendingPublishes: () => void,
clearPublish: () => void, clearPublish: () => void,
fetchClaimListMine: () => void, fetchClaimListMine: (number, number) => void,
fetching: boolean, fetching: boolean,
urls: Array<string>, urls: Array<string>,
urlTotal: ?number, urlTotal: number,
history: { replace: string => void }, history: { replace: string => void, push: string => void },
page: number, page: number,
pageSize: number,
}; };
function FileListPublished(props: Props) { function FileListPublished(props: Props) {
const { checkPendingPublishes, clearPublish, fetchClaimListMine, fetching, urls, urlTotal } = props; const {
uploadCount,
checkPendingPublishes,
clearPublish,
fetchClaimListMine,
fetching,
urls,
urlTotal,
page,
pageSize,
} = props;
const params = {};
params[PAGE_PARAM] = Number(page);
params[PAGE_SIZE_PARAM] = Number(pageSize);
const paramsString = JSON.stringify(params);
useEffect(() => { useEffect(() => {
checkPendingPublishes(); checkPendingPublishes();
fetchClaimListMine(); }, [checkPendingPublishes]);
}, [checkPendingPublishes, fetchClaimListMine]);
useEffect(() => {
if (paramsString && fetchClaimListMine) {
const params = JSON.parse(paramsString);
fetchClaimListMine(params.page, params.page_size);
}
}, [uploadCount, paramsString, fetchClaimListMine]);
return ( return (
<Page> <Page>
<WebUploadList /> <WebUploadList />
{urls && Boolean(urls.length) && ( <Card
<React.Fragment> title={__('Publishes')}
<ClaimList titleActions={
header={__('Your Publishes')} <div className="card__actions--inline">
loading={fetching} <Button button="alt" label={__('New Publish')} navigate="/$/publish" onClick={() => clearPublish()} />
persistedStorageKey="claim-list-published"
uris={urls} <Button
headerAltControls={ button="secondary"
<Button button="link" label={__('New Publish')} navigate="/$/publish" onClick={() => clearPublish()} /> label={__('Refresh')}
} onClick={() => fetchClaimListMine(params.page, params.page_size)}
/> />
<Paginate totalPages={Math.ceil(Number(urlTotal) / Number(PAGE_SIZE))} loading={fetching} /> </div>
</React.Fragment> }
)} isBodyList
body={
<div>
<ClaimList
isCardBody
loading={fetching}
persistedStorageKey="claim-list-published"
uris={urls}
includeOwnerActions
abandonActionCallback={() => fetchClaimListMine(params.page, params.page_size)}
/>
<Paginate totalPages={urlTotal > 0 ? Math.ceil(urlTotal / Number(pageSize)) : 1} />
</div>
}
/>
{!(urls && urls.length) && ( {!(urls && urls.length) && (
<React.Fragment> <React.Fragment>
{!fetching ? ( {!fetching ? (

View file

@ -9,7 +9,7 @@ import * as MODALS from 'constants/modal_types';
import { import {
Lbry, Lbry,
doBalanceSubscribe, doBalanceSubscribe,
doFetchFileInfosAndPublishedClaims, doFetchFileInfos,
doError, doError,
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectClaimIsMine, makeSelectClaimIsMine,
@ -352,7 +352,7 @@ export function doDaemonReady() {
dispatch(doFindFFmpeg()); dispatch(doFindFFmpeg());
dispatch(doGetDaemonStatus()); dispatch(doGetDaemonStatus());
dispatch(doFetchDaemonSettings()); dispatch(doFetchDaemonSettings());
dispatch(doFetchFileInfosAndPublishedClaims()); dispatch(doFetchFileInfos());
if (!selectIsUpgradeSkipped(state)) { if (!selectIsUpgradeSkipped(state)) {
dispatch(doCheckUpgradeAvailable()); dispatch(doCheckUpgradeAvailable());
} }

View file

@ -2,7 +2,14 @@
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
import { batchActions, doError, selectMyClaims, doPublish, doCheckPendingPublishes } from 'lbry-redux'; import {
batchActions,
doError,
selectMyClaims,
doPublish,
doCheckPendingPublishes,
ACTIONS as LBRY_REDUX_ACTIONS,
} from 'lbry-redux';
import { selectosNotificationsEnabled } from 'redux/selectors/settings'; import { selectosNotificationsEnabled } from 'redux/selectors/settings';
import { push } from 'connected-react-router'; import { push } from 'connected-react-router';
import analytics from 'analytics'; import analytics from 'analytics';
@ -31,23 +38,21 @@ export const doPublishDesktop = (filePath: string) => (dispatch: Dispatch, getSt
const isMatch = claim => claim.claim_id === pendingClaim.claim_id; const isMatch = claim => claim.claim_id === pendingClaim.claim_id;
const isEdit = myClaims.some(isMatch); const isEdit = myClaims.some(isMatch);
const myNewClaims = isEdit actions.push({
? myClaims.map(claim => (isMatch(claim) ? pendingClaim : claim)) type: LBRY_REDUX_ACTIONS.UPDATE_PENDING_CLAIMS,
: myClaims.concat(pendingClaim); data: {
actions.push( claims: [pendingClaim],
},
});
dispatch(batchActions(...actions));
dispatch(
doOpenModal(MODALS.PUBLISH, { doOpenModal(MODALS.PUBLISH, {
uri: url, uri: url,
isEdit, isEdit,
filePath, filePath,
}) })
); );
actions.push({
type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED,
data: {
claims: myNewClaims,
},
});
dispatch(batchActions(...actions));
}; };
const publishFail = error => { const publishFail = error => {

View file

@ -6178,9 +6178,9 @@ 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#f8c26fbe34f49a9898d48b8a41c956b9ad4ff582: lbry-redux@lbryio/lbry-redux#58ff4d8086cf2d038e0f606f50e04d67efec596a:
version "0.0.1" version "0.0.1"
resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/f8c26fbe34f49a9898d48b8a41c956b9ad4ff582" resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/58ff4d8086cf2d038e0f606f50e04d67efec596a"
dependencies: dependencies:
proxy-polyfill "0.1.6" proxy-polyfill "0.1.6"
reselect "^3.0.0" reselect "^3.0.0"