lbry-desktop/ui/effects/use-resolve-pins.js

52 lines
2.1 KiB
JavaScript
Raw Normal View History

// @flow
import React from 'react';
import useFetched from 'effects/use-fetched';
type Props = {
pins?: { urls?: Array<string>, claimIds?: Array<string>, onlyPinForOrder?: string },
claimsById: { [string]: Claim },
doResolveClaimIds: (Array<string>) => Promise<any>,
doResolveUris: (Array<string>, boolean) => Promise<any>,
};
export default function useResolvePins(props: Props) {
const { pins, claimsById, doResolveClaimIds, doResolveUris } = props;
const [resolvedPinUris, setResolvedPinUris] = React.useState(pins ? undefined : null);
const [resolvingPinUris, setResolvingPinUris] = React.useState(false);
const hasResolvedPinUris = useFetched(resolvingPinUris);
React.useEffect(() => {
if (resolvedPinUris === undefined && pins && !resolvingPinUris) {
if (pins.claimIds) {
// setResolvingPinUris is only needed for claim_search.
// doResolveUris uses selectResolvingUris internally to prevent double call.
setResolvingPinUris(true);
// We can't use .then() here to grab the `claim_search` uris directly,
// because we skip those that are already resolved. Instead, we mark a
// flag here, then populate the array in the other effect below in the
// next render cycle (redux would be updated by then). Pretty dumb.
// $FlowFixMe: already checked for null `pins`, but flow can't see it when there's code above it? Wow.
doResolveClaimIds(pins.claimIds).finally(() => setResolvingPinUris(false));
} else if (pins.urls) {
doResolveUris(pins.urls, true).finally(() => setResolvedPinUris(pins.urls));
} else {
setResolvedPinUris(null);
}
}
}, [resolvedPinUris, pins, doResolveUris, doResolveClaimIds, resolvingPinUris]);
React.useEffect(() => {
if (hasResolvedPinUris) {
if (pins && pins.claimIds) {
setResolvedPinUris(pins.claimIds.map<string>((id) => claimsById[id]?.canonical_url));
}
}
// Only do this over a false->true->false transition for hasResolvedPinUris.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasResolvedPinUris]);
return resolvedPinUris;
}