remove dependency on full claim list

paginate claim list
improve handling of pending publishes
add abandon to publishes list previews

use bodyCard

fix publish edit notification
This commit is contained in:
jessop 2020-04-24 09:51:00 -04:00
parent f83ab01c2d
commit 7730ee1e3f
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"