From 3edb00b99dd0a3215484ccd522631c9c28179721 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Tue, 1 Mar 2022 14:40:35 +0800 Subject: [PATCH] Manage Subs: change from claim_search to batch-resolve The idea of using claim_search to indirectly batch-resolve didn't work out well. There's something wrong with the claim_search pagination where some results are duplicated in multiple pages, while some are missing. It's also returning less results that than the given number of claim ids, so sometimes the infinite scroll breaks. --- ui/page/channelsFollowingManage/index.js | 7 ++- ui/page/channelsFollowingManage/view.jsx | 76 ++++++++++++++++-------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/ui/page/channelsFollowingManage/index.js b/ui/page/channelsFollowingManage/index.js index e5f35453d..45dc4ab33 100644 --- a/ui/page/channelsFollowingManage/index.js +++ b/ui/page/channelsFollowingManage/index.js @@ -1,4 +1,5 @@ import { connect } from 'react-redux'; +import { doResolveUris } from 'redux/actions/claims'; import { selectSubscriptionUris } from 'redux/selectors/subscriptions'; import ChannelsFollowingManage from './view'; @@ -6,4 +7,8 @@ const select = (state) => ({ subscribedChannelUris: selectSubscriptionUris(state), }); -export default connect(select)(ChannelsFollowingManage); +const perform = { + doResolveUris, +}; + +export default connect(select, perform)(ChannelsFollowingManage); diff --git a/ui/page/channelsFollowingManage/view.jsx b/ui/page/channelsFollowingManage/view.jsx index a9547fe92..68600a223 100644 --- a/ui/page/channelsFollowingManage/view.jsx +++ b/ui/page/channelsFollowingManage/view.jsx @@ -1,14 +1,11 @@ // @flow import React from 'react'; import ClaimList from 'component/claimList'; -import ClaimListDiscover from 'component/claimListDiscover'; import DebouncedInput from 'component/common/debounced-input'; import Empty from 'component/common/empty'; import Page from 'component/page'; import Spinner from 'component/spinner'; -import * as CS from 'constants/claim_search'; import * as ICONS from 'constants/icons'; -import { parseURI } from 'util/lbryURI'; function getFilteredUris(uris, filterQuery) { if (filterQuery) { @@ -18,60 +15,87 @@ function getFilteredUris(uris, filterQuery) { return null; } -function parseIdFromUri(uri) { - try { - const { channelClaimId } = parseURI(uri); - return channelClaimId; - } catch { - return ''; - } -} - // **************************************************************************** // ChannelsFollowingManage // **************************************************************************** +const FOLLOW_PAGE_SIZE = 30; + type Props = { subscribedChannelUris: Array, + doResolveUris: (uris: Array, returnCachedClaims: boolean, resolveReposts: boolean) => void, }; export default function ChannelsFollowingManage(props: Props) { - const { subscribedChannelUris } = props; + const { subscribedChannelUris, doResolveUris } = props; + + // The locked-on-mount full set of subscribed uris. const [uris, setUris] = React.useState([]); + + // Filtered query and their uris. const [filterQuery, setFilterQuery] = React.useState(''); - const filteredUris = getFilteredUris(uris, filterQuery); - const [channelIds, setChannelIds] = React.useState(null); + const [filteredUris, setFilteredUris] = React.useState(null); + + // Infinite-scroll handling. 'page' is 0-indexed. + const [page, setPage] = React.useState(-1); + const lastPage = Math.max(0, Math.ceil(uris.length / FOLLOW_PAGE_SIZE) - 1); + + async function resolveUris(uris) { + return doResolveUris(uris, true, false); + } + + async function resolveNextPage(uris, currPage, pageSize = FOLLOW_PAGE_SIZE) { + const nextPage = currPage + 1; + const nextUriBatch = uris.slice(nextPage * pageSize, (nextPage + 1) * pageSize); + return resolveUris(nextUriBatch); + } + + function bumpPage() { + if (page < lastPage) { + resolveNextPage(uris, page).finally(() => setPage(page + 1)); + } + } React.useEffect(() => { setUris(subscribedChannelUris); - setChannelIds(subscribedChannelUris.map((uri) => parseIdFromUri(uri))); + resolveNextPage(subscribedChannelUris, -1).finally(() => setPage(0)); // eslint-disable-next-line react-hooks/exhaustive-deps, (lock list on mount so it doesn't shift when unfollow) }, []); + React.useEffect(() => { + const filteredUris = getFilteredUris(uris, filterQuery); + if (filteredUris) { + resolveUris(filteredUris).finally(() => setFilteredUris(filteredUris)); + } else { + setFilteredUris(filteredUris); + } + // eslint-disable-next-line react-hooks/exhaustive-deps, (only need to respond to 'filterQuery') + }, [filterQuery]); + return (
{__('Followed Channels')}
- {channelIds === null ? ( + {page < 0 ? (
- +
) : uris && uris.length === 0 ? ( ) : ( <> + {filteredUris && } - {!filteredUris && channelIds.length && ( - 0 && ( + )}