Chapters grouped by manga series (#1085)

* show only the last chapter red

* fix : case when a load has not enough different manga

* fix : problems with the load of chapters

* Fix "filteredOutAllItemsOfFetchedPage" determination

* Remove logic to load until scrollbar appears

`Virtuoso` (list) doesn't have the same issue as `GridVirtuoso`, i.e. `endReached` gets called on initial render in case there weren't enough items

* Increase history page size (50 -> 150)

Due to the new filtering, it can take forever to load the initial pages/next pages

* Use lodash "uniqBy" for filtering

* Update changelog

---------

Co-authored-by: schroda <50052685+schroda@users.noreply.github.com>
This commit is contained in:
matsuaa
2026-07-04 15:29:41 +02:00
committed by GitHub
parent f7f65a69d2
commit 0ffaa0fb3e
3 changed files with 21 additions and 6 deletions

View File

@@ -40,6 +40,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- (**Reader**) Improve preloading pages from the previous/next chapter
- (**Category**) Require confirmation before deleting a category
- (**Download**) Respect manga chapter filters on bulk manga download in the library
- (**History**) Show only the last read chapter per manga
### Fixed

View File

@@ -7,7 +7,7 @@
*/
import Typography from '@mui/material/Typography';
import React, { useCallback, useMemo } from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useLingui } from '@lingui/react/macro';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
@@ -22,6 +22,7 @@ import { ChapterHistoryCard } from '@/features/history/components/ChapterHistory
import { Chapters } from '@/features/chapter/services/Chapters.ts';
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
import uniqBy from 'lodash/fp/uniqBy';
export const History: React.FC = () => {
const { t } = useLingui();
@@ -38,8 +39,13 @@ export const History: React.FC = () => {
fetchPolicy: 'cache-and-network',
});
const hasNextPage = !!chapterHistoryData?.chapters.pageInfo.hasNextPage;
const endCursor = chapterHistoryData?.chapters.pageInfo.endCursor;
const readEntries = chapterHistoryData?.chapters.nodes ?? STABLE_EMPTY_ARRAY;
const allReadEntries = chapterHistoryData?.chapters.nodes ?? STABLE_EMPTY_ARRAY;
const readEntries = useMemo(() => uniqBy('mangaId', allReadEntries), [allReadEntries]);
const [prevReadEntriesLength, setPrevReadEntriesLength] = useState(0);
const filteredOutAllItemsOfFetchedPage = allReadEntries.length > 0 && readEntries.length === prevReadEntriesLength;
const groupedHistory = useMemo(
() => Object.entries(Chapters.groupByDate(readEntries, 'lastReadAt')),
[readEntries],
@@ -60,8 +66,16 @@ export const History: React.FC = () => {
return;
}
fetchMore({ variables: { offset: readEntries.length } });
}, [hasNextPage, endCursor]);
fetchMore({ variables: { offset: allReadEntries.length } }).then(() =>
setPrevReadEntriesLength(readEntries.length),
);
}, [hasNextPage, allReadEntries.length, readEntries.length]);
useEffect(() => {
if (filteredOutAllItemsOfFetchedPage && hasNextPage && !isLoading) {
loadMore();
}
}, [filteredOutAllItemsOfFetchedPage, isLoading, hasNextPage, loadMore]);
if (error) {
return (

View File

@@ -3478,7 +3478,7 @@ export class RequestManager {
initialPages: number = 1,
options?: QueryHookOptions<GetChaptersHistoryQuery, GetChaptersHistoryQueryVariables>,
): AbortableApolloUseQueryResponse<GetChaptersHistoryQuery, GetChaptersHistoryQueryVariables> {
const PAGE_SIZE = 50;
const PAGE_SIZE = 150;
const CACHE_KEY = 'useGetRecentlyReadChapters';
const offset = this.cache.getResponseFor<number>(CACHE_KEY, undefined) ?? 0;