Merge pull request #4059 from lbryio/feat-claimListPaginate
paginate claim list
This commit is contained in:
commit
104aa943ed
20 changed files with 188 additions and 95 deletions
|
@ -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",
|
||||||
|
|
13
ui/component/claimAbandonButton/index.js
Normal file
13
ui/component/claimAbandonButton/index.js
Normal 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);
|
21
ui/component/claimAbandonButton/view.jsx
Normal file
21
ui/component/claimAbandonButton/view.jsx
Normal 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} />;
|
||||||
|
}
|
|
@ -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}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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') + ' ' + '($#@;/"<>%{}|^~[]`)';
|
||||||
|
|
|
@ -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);
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
||||||
);
|
|
||||||
|
|
|
@ -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 ? (
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in a new issue