Batch-resolve Watch History

## Issue
Doing individual resolves, even on a small list, is taxing.

## Change
Add infinite scroll and batch-resolve each page.
This commit is contained in:
infinite-persistence 2022-05-16 14:44:01 +08:00 committed by Thomas Zarebczan
parent 51616956d4
commit a2099482b0
4 changed files with 47 additions and 23 deletions

View file

@ -2263,5 +2263,8 @@
"Unable to react. Please try again later.": "Unable to react. Please try again later.",
"Username (cannot be changed)": "Username (cannot be changed)",
"Display Name": "Display Name",
"Watch History": "Watch History",
"Currently, your watch history is only saved locally.": "Currently, your watch history is only saved locally.",
"Clear History": "Clear History",
"--end--": "--end--"
}

View file

@ -1,17 +1,17 @@
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import WatchHistoryPage from './view';
import { selectHistory } from 'redux/selectors/content';
import { selectWatchHistoryUris } from 'redux/selectors/content';
import { doClearContentHistoryAll } from 'redux/actions/content';
import { doResolveUris } from 'redux/actions/claims';
const select = (state) => {
return {
history: selectHistory(state),
};
};
const perform = (dispatch) => ({
doClearContentHistoryAll: () => dispatch(doClearContentHistoryAll()),
const select = (state) => ({
historyUris: selectWatchHistoryUris(state),
});
const perform = {
doClearContentHistoryAll,
doResolveUris,
};
export default withRouter(connect(select, perform)(WatchHistoryPage));

View file

@ -8,23 +8,24 @@ import Icon from 'component/common/icon';
import * as ICONS from 'constants/icons';
import { YRBL_SAD_IMG_URL } from 'config';
import Tooltip from 'component/common/tooltip';
import useClaimListInfiniteScroll from 'effects/use-claimList-infinite-scroll';
export const PAGE_VIEW_QUERY = 'view';
export const PAGE_SIZE = 30;
type Props = {
history: Array<any>,
historyUris: Array<string>,
doClearContentHistoryAll: () => void,
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean, resolveReposts: boolean) => void,
};
export default function WatchHistoryPage(props: Props) {
const { history, doClearContentHistoryAll } = props;
const [unavailableUris] = React.useState([]);
const watchHistory = [];
for (let entry of history) {
if (entry.uri.indexOf('@') !== -1) {
watchHistory.push(entry.uri);
}
}
const { historyUris, doClearContentHistoryAll, doResolveUris } = props;
const { uris, page, isLoadingPage, bumpPage } = useClaimListInfiniteScroll(
historyUris,
doResolveUris,
PAGE_SIZE,
true
);
function clearHistory() {
doClearContentHistoryAll();
@ -43,7 +44,7 @@ export default function WatchHistoryPage(props: Props) {
</h1>
<div className="claim-list__alt-controls--wrap">
{watchHistory.length > 0 && (
{uris.length > 0 && (
<Button
title={__('Clear History')}
button="primary"
@ -53,8 +54,18 @@ export default function WatchHistoryPage(props: Props) {
)}
</div>
</div>
{watchHistory.length > 0 && <ClaimList uris={watchHistory} unavailableUris={unavailableUris} inWatchHistory />}
{watchHistory.length === 0 && (
{uris.length > 0 && (
<ClaimList
uris={uris.slice(0, (page + 1) * PAGE_SIZE)}
onScrollBottom={bumpPage}
page={page + 1}
pageSize={PAGE_SIZE}
loading={isLoadingPage}
useLoadingSpinner
inWatchHistory
/>
)}
{uris.length === 0 && (
<div style={{ textAlign: 'center' }}>
<img src={YRBL_SAD_IMG_URL} />
<h2 className="main--empty empty" style={{ marginTop: '0' }}>

View file

@ -69,7 +69,7 @@ export const selectContentPositionForUri = (state: State, uri: string) => {
return null;
};
export const selectHistory = createSelector(selectState, (state) => state.history || []);
export const selectHistory = (state: State) => selectState(state).history || [];
export const selectHistoryPageCount = createSelector(selectHistory, (history) =>
Math.ceil(history.length / HISTORY_ITEMS_PER_PAGE)
@ -92,6 +92,16 @@ export const selectRecentHistory = createSelector(selectHistory, (history) => {
return history.slice(0, RECENT_HISTORY_AMOUNT);
});
export const selectWatchHistoryUris = createSelector(selectHistory, (history) => {
const uris = [];
for (let entry of history) {
if (entry.uri.indexOf('@') !== -1) {
uris.push(entry.uri);
}
}
return uris;
});
export const selectShouldObscurePreviewForUri = (state: State, uri: string) => {
const showMatureContent = selectShowMatureContent(state);
const isClaimMature = selectClaimIsNsfwForUri(state, uri);