Reduce requested manga data in queries

This commit is contained in:
schroda
2024-07-08 18:02:50 +02:00
parent 4b30e9bc48
commit 3d21266f92
47 changed files with 759 additions and 471 deletions

View File

@@ -9,14 +9,12 @@
import React, { useEffect, useLayoutEffect } from 'react';
import { StringParam, useQueryParam } from 'use-query-params';
import { useTranslation } from 'react-i18next';
import { TManga } from '@/typings';
import { GridLayout, useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext';
import { IMangaGridProps, MangaGrid } from '@/components/MangaGrid';
interface LibraryMangaGridProps
extends Required<Pick<IMangaGridProps, 'isSelectModeActive' | 'selectedMangaIds' | 'handleSelection'>>,
extends Required<Pick<IMangaGridProps, 'isSelectModeActive' | 'selectedMangaIds' | 'handleSelection' | 'mangas'>>,
Pick<IMangaGridProps, 'retry' | 'message' | 'messageExtra'> {
mangas: TManga[];
showFilteredOutMessage: boolean;
isLoading: boolean;
}

View File

@@ -8,10 +8,11 @@
import { StringParam, useQueryParam } from 'use-query-params';
import { useMemo } from 'react';
import { LibraryOptions, LibrarySortMode, NullAndUndefined, TManga } from '@/typings.ts';
import { LibraryOptions, LibrarySortMode, NullAndUndefined } from '@/typings.ts';
import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext.tsx';
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
import { Trackers } from '@/lib/data/Trackers.ts';
import { ChapterType, MangaType, TrackRecordType } from '@/lib/graphql/generated/graphql.ts';
import { MangaIdInfo } from '@/lib/data/Mangas.ts';
const triStateFilter = (
triState: NullAndUndefined<boolean>,
@@ -35,22 +36,26 @@ const triStateFilterNumber = (triState: NullAndUndefined<boolean>, count?: numbe
() => count === 0,
);
const queryFilter = (query: NullAndUndefined<string>, { title }: TManga): boolean => {
type TMangaQueryFilter = Pick<MangaType, 'title'>;
const queryFilter = (query: NullAndUndefined<string>, { title }: TMangaQueryFilter): boolean => {
if (!query) return true;
return title.toLowerCase().includes(query.toLowerCase());
};
const queryGenreFilter = (query: NullAndUndefined<string>, { genre }: TManga): boolean => {
type TMangaQueryGenreFilter = Pick<MangaType, 'genre'>;
const queryGenreFilter = (query: NullAndUndefined<string>, { genre }: TMangaQueryGenreFilter): boolean => {
if (!query) return true;
const queries = query.split(',').map((str) => str.toLowerCase().trim());
return queries.every((element) => genre.map((el) => el.toLowerCase()).includes(element));
};
const trackerFilter = (trackFilters: LibraryOptions['tracker'], manga: TManga): boolean =>
type TMangaTrackerFilter = { trackRecords: { nodes: Pick<TrackRecordType, 'id' | 'trackerId'>[] } };
const trackerFilter = (trackFilters: LibraryOptions['tracker'], manga: TMangaTrackerFilter): boolean =>
Object.entries(trackFilters)
.map(([trackFilterId, trackFilterState]) => {
const mangaTrackers = Trackers.getTrackers(manga.trackRecords.nodes);
const isTrackerBound = mangaTrackers.some((tracker) => tracker.id === Number(trackFilterId));
const isTrackerBound = manga.trackRecords.nodes.some(
(trackRecord) => trackRecord.trackerId === Number(trackFilterId),
);
return triStateFilter(
trackFilterState,
@@ -60,15 +65,19 @@ const trackerFilter = (trackFilters: LibraryOptions['tracker'], manga: TManga):
})
.every((matchesFilter) => matchesFilter);
const filterManga = (
mangas: TManga[],
type TMangaFilter = TMangaQueryFilter &
TMangaQueryGenreFilter &
TMangaTrackerFilter &
Pick<MangaType, 'downloadCount' | 'unreadCount' | 'bookmarkCount'>;
const filterManga = <Manga extends TMangaFilter>(
mangas: Manga[],
query: NullAndUndefined<string>,
unread: NullAndUndefined<boolean>,
downloaded: NullAndUndefined<boolean>,
bookmarked: NullAndUndefined<boolean>,
tracker: LibraryOptions['tracker'],
ignoreFilters: boolean,
): TManga[] =>
): Manga[] =>
mangas.filter((manga) => {
const ignoreFiltersWhileSearching = ignoreFilters && query?.length;
const matchesSearch = queryFilter(query, manga) || queryGenreFilter(query, manga);
@@ -86,11 +95,16 @@ const sortByNumber = (a: number | string = 0, b: number | string = 0) => Number(
const sortByString = (a: string, b: string): number => a.localeCompare(b);
const sortManga = (
manga: TManga[],
type TMangaSort = Pick<MangaType, 'title' | 'inLibraryAt' | 'unreadCount'> & {
lastReadChapter?: Pick<ChapterType, 'lastReadAt'> | null;
latestUploadedChapter?: Pick<ChapterType, 'uploadDate'> | null;
latestFetchedChapter?: Pick<ChapterType, 'fetchedAt'> | null;
};
const sortManga = <Manga extends TMangaSort>(
manga: Manga[],
sort: NullAndUndefined<LibrarySortMode>,
desc: NullAndUndefined<boolean>,
): TManga[] => {
): Manga[] => {
const result = [...manga];
switch (sort) {
@@ -125,7 +139,12 @@ const sortManga = (
return result;
};
export const useGetVisibleLibraryMangas = (mangas: TManga[]) => {
export const useGetVisibleLibraryMangas = <Manga extends MangaIdInfo & TMangaFilter & TMangaSort>(
mangas: Manga[],
): {
visibleMangas: Manga[];
showFilteredOutMessage: boolean;
} => {
const [query] = useQueryParam('query', StringParam);
const { options } = useLibraryOptionsContext();
const { unread, downloaded, bookmarked, tracker } = options;