improve pending livestream dashboard #5810

Merged
jessopb merged 1 commit from fix-odyseePending into odysee 2021-04-01 22:38:38 +02:00

View file

@ -15,6 +15,7 @@ import CopyableText from 'component/copyableText';
import Card from 'component/common/card';
import ClaimList from 'component/claimList';
import usePersistedState from 'effects/use-persisted-state';
import usePrevious from 'effects/use-previous';
type Props = {
channels: Array<ChannelClaim>,
@ -50,8 +51,116 @@ export default function LivestreamSetupPage(props: Props) {
claim.value_type === 'stream' && !(claim.value && claim.value.source)
)
: [];
const [localPending, setLocalPending] = React.useState([]); //
const localPendingStr = JSON.stringify(localPending);
const pendingLivestreamClaimsStr = JSON.stringify(pendingLiveStreamClaims);
const prevPendingLiveStreamClaimStr = usePrevious(pendingLivestreamClaimsStr);
const liveStreamClaimsStr = JSON.stringify(livestreamClaims);
const prevLiveStreamClaimsStr = JSON.stringify(liveStreamClaimsStr);
const pendingLength = pendingLiveStreamClaims.length;
const totalLivestreamClaims = pendingLiveStreamClaims.concat(livestreamClaims);
// maintain a pendingClaims list by channelId that locally that things are removed from only when they show up in claim_search results.
React.useEffect(() => {
if (activeChannelClaimStr) {
const channelClaim = JSON.parse(activeChannelClaimStr);
// ensure we have a channel
if (channelClaim.claim_id) {
Lbry.channel_sign({
channel_id: channelClaim.claim_id,
hexdata: toHex(channelClaim.name),
})
.then((data) => {
setSigData(data);
})
.catch((error) => {
setSigData({ signature: null, signing_ts: null });
});
}
}
}, [activeChannelClaimStr, setSigData]);
// The following 2 effects handle the time between pending disappearing and claim_search being able to find it.
// We'll maintain our own pending list:
// add to it when there are new things in pending
// remove items only when our claim_search finds it
React.useEffect(() => {
// add to localPending when pending changes
const localPending = JSON.parse(localPendingStr);
const pendingLivestreamClaims = JSON.parse(pendingLivestreamClaimsStr);
if (
pendingLiveStreamClaims !== prevPendingLiveStreamClaimStr ||
(pendingLivestreamClaims.length && !localPending.length)
) {
const prevPendingLivestreamClaims = prevPendingLiveStreamClaimStr
? JSON.parse(prevPendingLiveStreamClaimStr)
: [];
const pendingClaimIds = pendingLivestreamClaims.map((claim) => claim.claim_id);
const prevPendingClaimIds = prevPendingLivestreamClaims.map((claim) => claim.claim_id);
const newLocalPending = [];
if (pendingClaimIds.length > prevPendingClaimIds.length) {
pendingLivestreamClaims.forEach((pendingClaim) => {
if (!localPending.some((lClaim) => lClaim.claim_id === pendingClaim.claim_id)) {
newLocalPending.push(pendingClaim);
}
});
setLocalPending(localPending.concat(newLocalPending));
}
}
}, [pendingLivestreamClaimsStr, prevPendingLiveStreamClaimStr, localPendingStr, setLocalPending]);
React.useEffect(() => {
// remove from localPending when livestreamClaims found
const localPending = JSON.parse(localPendingStr);
if (liveStreamClaimsStr !== prevLiveStreamClaimsStr && localPending.length) {
const livestreamClaims = JSON.parse(liveStreamClaimsStr);
setLocalPending(
localPending.filter((pending) => !livestreamClaims.some((claim) => claim.claim_id === pending.claim_id))
);
}
}, [liveStreamClaimsStr, prevLiveStreamClaimsStr, localPendingStr, setLocalPending]);
React.useEffect(() => {
let checkClaimsInterval;
if (!activeChannelClaimStr) return;
const channelClaim = JSON.parse(activeChannelClaimStr);
function checkLivestreamClaims() {
Lbry.claim_search({
channel_ids: [channelClaim.claim_id],
has_no_source: true,
claim_type: ['stream'],
})
.then((res) => {
if (res && res.items && res.items.length > 0) {
setLivestreamClaims(res.items.reverse());
} else {
setLivestreamClaims([]);
}
setSpin(false);
})
.catch(() => {
setLivestreamClaims([]);
setSpin(false);
});
}
if (!checkClaimsInterval) {
checkLivestreamClaims();
checkClaimsInterval = setInterval(checkLivestreamClaims, LIVESTREAM_CLAIM_POLL_IN_MS);
}
return () => {
if (checkClaimsInterval) {
clearInterval(checkClaimsInterval);
}
};
}, [activeChannelClaimStr, pendingLength, setSpin]);
const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id;
const localPendingForChannel = localPending.filter(
(claim) => claim.signing_channel && claim.signing_channel.claim_id === activeChannelId
);
const totalLivestreamClaims = localPendingForChannel.concat(livestreamClaims);
const helpText = (
<div className="section__subtitle">
<p>
@ -95,61 +204,6 @@ export default function LivestreamSetupPage(props: Props) {
</div>
);
React.useEffect(() => {
if (activeChannelClaimStr) {
const channelClaim = JSON.parse(activeChannelClaimStr);
// ensure we have a channel
if (channelClaim.claim_id) {
Lbry.channel_sign({
channel_id: channelClaim.claim_id,
hexdata: toHex(channelClaim.name),
})
.then((data) => {
setSigData(data);
})
.catch((error) => {
setSigData({ signature: null, signing_ts: null });
});
}
}
}, [activeChannelClaimStr, setSigData]);
React.useEffect(() => {
let checkClaimsInterval;
if (!activeChannelClaimStr) return;
const channelClaim = JSON.parse(activeChannelClaimStr);
function checkLivestreamClaims() {
Lbry.claim_search({
channel_ids: [channelClaim.claim_id],
has_no_source: true,
claim_type: ['stream'],
})
.then((res) => {
if (res && res.items && res.items.length > 0) {
setLivestreamClaims(res.items.reverse());
} else {
setLivestreamClaims([]);
}
setSpin(false);
})
.catch(() => {
setLivestreamClaims([]);
setSpin(false);
});
}
if (!checkClaimsInterval) {
checkLivestreamClaims();
checkClaimsInterval = setInterval(checkLivestreamClaims, LIVESTREAM_CLAIM_POLL_IN_MS);
}
return () => {
if (checkClaimsInterval) {
clearInterval(checkClaimsInterval);
}
};
}, [activeChannelClaimStr, pendingLength, setSpin]);
return (
<Page>
{(fetchingChannels || spin) && (
@ -219,11 +273,11 @@ export default function LivestreamSetupPage(props: Props) {
{totalLivestreamClaims.length > 0 ? (
<>
{Boolean(pendingLiveStreamClaims.length) && (
{Boolean(localPendingForChannel.length) && (
<div className="section">
<ClaimList
header={__('Your pending livestream uploads')}
uris={pendingLiveStreamClaims.map((claim) => claim.permanent_url)}
uris={localPendingForChannel.map((claim) => claim.permanent_url)}
/>
</div>
)}