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.", "Unable to react. Please try again later.": "Unable to react. Please try again later.",
"Username (cannot be changed)": "Username (cannot be changed)", "Username (cannot be changed)": "Username (cannot be changed)",
"Display Name": "Display Name", "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--" "--end--": "--end--"
} }

View file

@ -1,17 +1,17 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom'; import { withRouter } from 'react-router-dom';
import WatchHistoryPage from './view'; import WatchHistoryPage from './view';
import { selectHistory } from 'redux/selectors/content'; import { selectWatchHistoryUris } from 'redux/selectors/content';
import { doClearContentHistoryAll } from 'redux/actions/content'; import { doClearContentHistoryAll } from 'redux/actions/content';
import { doResolveUris } from 'redux/actions/claims';
const select = (state) => { const select = (state) => ({
return { historyUris: selectWatchHistoryUris(state),
history: selectHistory(state),
};
};
const perform = (dispatch) => ({
doClearContentHistoryAll: () => dispatch(doClearContentHistoryAll()),
}); });
const perform = {
doClearContentHistoryAll,
doResolveUris,
};
export default withRouter(connect(select, perform)(WatchHistoryPage)); 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 * as ICONS from 'constants/icons';
import { YRBL_SAD_IMG_URL } from 'config'; import { YRBL_SAD_IMG_URL } from 'config';
import Tooltip from 'component/common/tooltip'; 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 = { type Props = {
history: Array<any>, historyUris: Array<string>,
doClearContentHistoryAll: () => void, doClearContentHistoryAll: () => void,
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean, resolveReposts: boolean) => void,
}; };
export default function WatchHistoryPage(props: Props) { export default function WatchHistoryPage(props: Props) {
const { history, doClearContentHistoryAll } = props; const { historyUris, doClearContentHistoryAll, doResolveUris } = props;
const [unavailableUris] = React.useState([]); const { uris, page, isLoadingPage, bumpPage } = useClaimListInfiniteScroll(
const watchHistory = []; historyUris,
for (let entry of history) { doResolveUris,
if (entry.uri.indexOf('@') !== -1) { PAGE_SIZE,
watchHistory.push(entry.uri); true
} );
}
function clearHistory() { function clearHistory() {
doClearContentHistoryAll(); doClearContentHistoryAll();
@ -43,7 +44,7 @@ export default function WatchHistoryPage(props: Props) {
</h1> </h1>
<div className="claim-list__alt-controls--wrap"> <div className="claim-list__alt-controls--wrap">
{watchHistory.length > 0 && ( {uris.length > 0 && (
<Button <Button
title={__('Clear History')} title={__('Clear History')}
button="primary" button="primary"
@ -53,8 +54,18 @@ export default function WatchHistoryPage(props: Props) {
)} )}
</div> </div>
</div> </div>
{watchHistory.length > 0 && <ClaimList uris={watchHistory} unavailableUris={unavailableUris} inWatchHistory />} {uris.length > 0 && (
{watchHistory.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' }}> <div style={{ textAlign: 'center' }}>
<img src={YRBL_SAD_IMG_URL} /> <img src={YRBL_SAD_IMG_URL} />
<h2 className="main--empty empty" style={{ marginTop: '0' }}> <h2 className="main--empty empty" style={{ marginTop: '0' }}>

View file

@ -69,7 +69,7 @@ export const selectContentPositionForUri = (state: State, uri: string) => {
return null; return null;
}; };
export const selectHistory = createSelector(selectState, (state) => state.history || []); export const selectHistory = (state: State) => selectState(state).history || [];
export const selectHistoryPageCount = createSelector(selectHistory, (history) => export const selectHistoryPageCount = createSelector(selectHistory, (history) =>
Math.ceil(history.length / HISTORY_ITEMS_PER_PAGE) 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); 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) => { export const selectShouldObscurePreviewForUri = (state: State, uri: string) => {
const showMatureContent = selectShowMatureContent(state); const showMatureContent = selectShowMatureContent(state);
const isClaimMature = selectClaimIsNsfwForUri(state, uri); const isClaimMature = selectClaimIsNsfwForUri(state, uri);