Correctly get total library size

The total size was the sum of all categories, which could include duplicates, since manga can be in multiple categories.

This still will show an incorrect number, because server side there is the same issue with the "mangas" query including duplicates in the total count, however, once this is fixed, the correct count will be displayed
This commit is contained in:
schroda
2024-11-28 12:20:36 +01:00
parent 55dc1aa6a5
commit 0c02de5b92
3 changed files with 42 additions and 11 deletions

View File

@@ -519,9 +519,11 @@ export enum DownloadUpdateType {
Dequeued = 'DEQUEUED', Dequeued = 'DEQUEUED',
Error = 'ERROR', Error = 'ERROR',
Finished = 'FINISHED', Finished = 'FINISHED',
Paused = 'PAUSED',
Position = 'POSITION', Position = 'POSITION',
Progress = 'PROGRESS', Progress = 'PROGRESS',
Queued = 'QUEUED' Queued = 'QUEUED',
Stopped = 'STOPPED'
} }
export type DownloadUpdates = { export type DownloadUpdates = {
@@ -1501,6 +1503,7 @@ export type PartialSettingsType = Settings & {
flareSolverrTimeout?: Maybe<Scalars['Int']['output']>; flareSolverrTimeout?: Maybe<Scalars['Int']['output']>;
flareSolverrUrl?: Maybe<Scalars['String']['output']>; flareSolverrUrl?: Maybe<Scalars['String']['output']>;
globalUpdateInterval?: Maybe<Scalars['Float']['output']>; globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
/** @deprecated Removed - does not do anything */
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>; gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>; initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
ip?: Maybe<Scalars['String']['output']>; ip?: Maybe<Scalars['String']['output']>;
@@ -1551,7 +1554,6 @@ export type PartialSettingsTypeInput = {
flareSolverrTimeout?: InputMaybe<Scalars['Int']['input']>; flareSolverrTimeout?: InputMaybe<Scalars['Int']['input']>;
flareSolverrUrl?: InputMaybe<Scalars['String']['input']>; flareSolverrUrl?: InputMaybe<Scalars['String']['input']>;
globalUpdateInterval?: InputMaybe<Scalars['Float']['input']>; globalUpdateInterval?: InputMaybe<Scalars['Float']['input']>;
gqlDebugLogsEnabled?: InputMaybe<Scalars['Boolean']['input']>;
initialOpenInBrowserEnabled?: InputMaybe<Scalars['Boolean']['input']>; initialOpenInBrowserEnabled?: InputMaybe<Scalars['Boolean']['input']>;
ip?: InputMaybe<Scalars['String']['input']>; ip?: InputMaybe<Scalars['String']['input']>;
localSourcePath?: InputMaybe<Scalars['String']['input']>; localSourcePath?: InputMaybe<Scalars['String']['input']>;
@@ -1925,6 +1927,7 @@ export type Settings = {
flareSolverrTimeout?: Maybe<Scalars['Int']['output']>; flareSolverrTimeout?: Maybe<Scalars['Int']['output']>;
flareSolverrUrl?: Maybe<Scalars['String']['output']>; flareSolverrUrl?: Maybe<Scalars['String']['output']>;
globalUpdateInterval?: Maybe<Scalars['Float']['output']>; globalUpdateInterval?: Maybe<Scalars['Float']['output']>;
/** @deprecated Removed - does not do anything */
gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>; gqlDebugLogsEnabled?: Maybe<Scalars['Boolean']['output']>;
initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>; initialOpenInBrowserEnabled?: Maybe<Scalars['Boolean']['output']>;
ip?: Maybe<Scalars['String']['output']>; ip?: Maybe<Scalars['String']['output']>;
@@ -1978,6 +1981,7 @@ export type SettingsType = Settings & {
flareSolverrTimeout: Scalars['Int']['output']; flareSolverrTimeout: Scalars['Int']['output'];
flareSolverrUrl: Scalars['String']['output']; flareSolverrUrl: Scalars['String']['output'];
globalUpdateInterval: Scalars['Float']['output']; globalUpdateInterval: Scalars['Float']['output'];
/** @deprecated Removed - does not do anything */
gqlDebugLogsEnabled: Scalars['Boolean']['output']; gqlDebugLogsEnabled: Scalars['Boolean']['output'];
initialOpenInBrowserEnabled: Scalars['Boolean']['output']; initialOpenInBrowserEnabled: Scalars['Boolean']['output'];
ip: Scalars['String']['output']; ip: Scalars['String']['output'];
@@ -3512,6 +3516,11 @@ export type GetMigratableSourceMangasQueryVariables = Exact<{
export type GetMigratableSourceMangasQuery = { __typename?: 'Query', mangas: { __typename?: 'MangaNodeList', nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, sourceId: string, categories: { __typename?: 'CategoryNodeList', nodes: Array<{ __typename?: 'CategoryType', id: number }> } }> } }; export type GetMigratableSourceMangasQuery = { __typename?: 'Query', mangas: { __typename?: 'MangaNodeList', nodes: Array<{ __typename?: 'MangaType', id: number, title: string, thumbnailUrl?: string | null, sourceId: string, categories: { __typename?: 'CategoryNodeList', nodes: Array<{ __typename?: 'CategoryType', id: number }> } }> } };
export type GetLibraryMangaCountQueryVariables = Exact<{ [key: string]: never; }>;
export type GetLibraryMangaCountQuery = { __typename?: 'Query', mangas: { __typename?: 'MangaNodeList', totalCount: number } };
export type GetAboutQueryVariables = Exact<{ [key: string]: never; }>; export type GetAboutQueryVariables = Exact<{ [key: string]: never; }>;

View File

@@ -239,3 +239,11 @@ export const GET_MIGRATABLE_SOURCE_MANGAS = gql`
} }
} }
`; `;
export const GET_LIBRARY_MANGA_COUNT = gql`
query GET_LIBRARY_MANGA_COUNT {
mangas(condition: { inLibrary: true }) {
totalCount
}
}
`;

View File

@@ -32,6 +32,8 @@ import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts'
import { import {
GetCategoriesLibraryQuery, GetCategoriesLibraryQuery,
GetCategoriesLibraryQueryVariables, GetCategoriesLibraryQueryVariables,
GetLibraryMangaCountQuery,
GetLibraryMangaCountQueryVariables,
MangaChapterStatFieldsFragment, MangaChapterStatFieldsFragment,
MangaType, MangaType,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
@@ -41,6 +43,7 @@ import { MANGA_CHAPTER_STAT_FIELDS } from '@/lib/graphql/fragments/MangaFragment
import { useLibraryOptionsContext } from '@/modules/library/contexts/LibraryOptionsContext.tsx'; import { useLibraryOptionsContext } from '@/modules/library/contexts/LibraryOptionsContext.tsx';
import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts'; import { useMetadataServerSettings } from '@/modules/settings/services/ServerSettingsMetadata.ts';
import { getCategoryMetadata } from '@/modules/category/services/CategoryMetadata.ts'; import { getCategoryMetadata } from '@/modules/category/services/CategoryMetadata.ts';
import { GET_LIBRARY_MANGA_COUNT } from '@/lib/graphql/queries/MangaQuery.ts';
const TitleWithSizeTag = styled('span')({ const TitleWithSizeTag = styled('span')({
display: 'flex', display: 'flex',
@@ -73,10 +76,13 @@ export function Library() {
(category) => category.id !== 0 || (category.id === 0 && category.mangas.totalCount), (category) => category.id !== 0 || (category.id === 0 && category.mangas.totalCount),
); );
const tabs = tabsData ?? []; const tabs = tabsData ?? [];
const librarySize = useMemo(
() => tabs.map((tab) => tab.mangas.totalCount).reduce((prev, curr) => prev + curr, 0), const librarySizeResponse = requestManager.useGetMangas<
[tabs], GetLibraryMangaCountQuery,
); GetLibraryMangaCountQueryVariables
>(GET_LIBRARY_MANGA_COUNT, {});
const librarySize = librarySizeResponse.data?.mangas.totalCount ?? 0;
const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', NumberParam); const [tabSearchParam, setTabSearchParam] = useQueryParam('tab', NumberParam);
@@ -216,17 +222,25 @@ export function Library() {
setTabSearchParam(newTab); setTabSearchParam(newTab);
}; };
if (tabsError != null) { if (tabsError != null || librarySizeResponse.error) {
return ( return (
<EmptyViewAbsoluteCentered <EmptyViewAbsoluteCentered
message={t('category.error.label.request_failure')} message={t('global.error.label.failed_to_load_data')}
messageExtra={tabsError.message} messageExtra={tabsError?.message ?? librarySizeResponse.error?.message}
retry={() => refetchCategories().catch(defaultPromiseErrorHandler('Library::refetchCategories'))} retry={() => {
if (tabsError) {
refetchCategories().catch(defaultPromiseErrorHandler('Library::refetchCategories'));
}
if (librarySizeResponse.error) {
librarySizeResponse.refetch().catch(defaultPromiseErrorHandler('Library::refetchLibrarySize'));
}
}}
/> />
); );
} }
if (areCategoriesLoading) { if (areCategoriesLoading || librarySizeResponse.loading) {
return <LoadingPlaceholder />; return <LoadingPlaceholder />;
} }