Reduce requested source data in queries

This commit is contained in:
schroda
2024-07-03 23:15:50 +02:00
parent 2fa1de578c
commit 7556ea9b38
18 changed files with 368 additions and 468 deletions

View File

@@ -17,11 +17,11 @@ import Typography from '@mui/material/Typography';
import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { TPartialSource } from '@/typings';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { translateExtensionLanguage } from '@/screens/util/Extensions'; import { translateExtensionLanguage } from '@/screens/util/Extensions';
import { SourceContentType } from '@/screens/SourceMangas'; import { SourceContentType } from '@/screens/SourceMangas';
import { SpinnerImage } from '@/components/util/SpinnerImage.tsx'; import { SpinnerImage } from '@/components/util/SpinnerImage.tsx';
import { GetSourcesListQuery } from '@/lib/graphql/generated/graphql.ts';
const MobileWidthButtons = styled('div')(({ theme }) => ({ const MobileWidthButtons = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@@ -42,7 +42,7 @@ const WiderWidthButtons = styled('div')(({ theme }) => ({
})); }));
interface IProps { interface IProps {
source: TPartialSource; source: GetSourcesListQuery['sources']['nodes'][number];
showSourceRepo: boolean; showSourceRepo: boolean;
} }

View File

@@ -16,7 +16,7 @@ import { t as translate } from 'i18next';
import Link from '@mui/material/Link'; import Link from '@mui/material/Link';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import { useLongPress } from 'use-long-press'; import { useLongPress } from 'use-long-press';
import { ISource, TManga } from '@/typings'; import { TManga } from '@/typings';
import { makeToast } from '@/components/util/Toast'; import { makeToast } from '@/components/util/Toast';
import { Mangas } from '@/lib/data/Mangas.ts'; import { Mangas } from '@/lib/data/Mangas.ts';
import { SpinnerImage } from '@/components/util/SpinnerImage.tsx'; import { SpinnerImage } from '@/components/util/SpinnerImage.tsx';
@@ -25,6 +25,7 @@ import { TrackMangaButton } from '@/components/manga/TrackMangaButton.tsx';
import { useManageMangaLibraryState } from '@/components/manga/useManageMangaLibraryState.tsx'; import { useManageMangaLibraryState } from '@/components/manga/useManageMangaLibraryState.tsx';
import { Metadata as BaseMetadata } from '@/components/atoms/Metadata.tsx'; import { Metadata as BaseMetadata } from '@/components/atoms/Metadata.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
const DetailsWrapper = styled('div')(({ theme }) => ({ const DetailsWrapper = styled('div')(({ theme }) => ({
width: '100%', width: '100%',
@@ -159,7 +160,7 @@ interface IProps {
manga: TManga; manga: TManga;
} }
function getSourceName(source?: ISource | null) { function getSourceName(source?: Pick<SourceType, 'id' | 'displayName'> | null): string {
if (!source) { if (!source) {
return translate('global.label.unknown'); return translate('global.label.unknown');
} }

View File

@@ -7,6 +7,7 @@
*/ */
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { SOURCE_BASE_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
export const PAGE_INFO = gql` export const PAGE_INFO = gql`
fragment PAGE_INFO on PageInfo { fragment PAGE_INFO on PageInfo {
@@ -51,169 +52,6 @@ export const UPDATER_CATEGORY_FIELDS = gql`
} }
`; `;
export const PARTIAL_SOURCE_FIELDS = gql`
fragment PARTIAL_SOURCE_FIELDS on SourceType {
displayName
iconUrl
id
isConfigurable
isNsfw
lang
name
supportsLatest
extension {
pkgName
repo
}
meta {
key
value
}
}
`;
export const FULL_SOURCE_FIELDS = gql`
${PARTIAL_SOURCE_FIELDS}
fragment FULL_SOURCE_FIELDS on SourceType {
...PARTIAL_SOURCE_FIELDS
preferences {
... on CheckBoxPreference {
type: __typename
CheckBoxCheckBoxCurrentValue: currentValue
summary
CheckBoxDefault: default
key
CheckBoxTitle: title
}
... on EditTextPreference {
type: __typename
EditTextPreferenceCurrentValue: currentValue
EditTextPreferenceDefault: default
EditTextPreferenceTitle: title
text
summary
key
dialogTitle
dialogMessage
}
... on SwitchPreference {
type: __typename
SwitchPreferenceCurrentValue: currentValue
summary
key
SwitchPreferenceDefault: default
SwitchPreferenceTitle: title
}
... on MultiSelectListPreference {
type: __typename
dialogMessage
dialogTitle
MultiSelectListPreferenceTitle: title
summary
key
entryValues
entries
MultiSelectListPreferenceDefault: default
MultiSelectListPreferenceCurrentValue: currentValue
}
... on ListPreference {
type: __typename
ListPreferenceCurrentValue: currentValue
ListPreferenceDefault: default
ListPreferenceTitle: title
summary
key
entryValues
entries
}
}
filters {
... on CheckBoxFilter {
type: __typename
CheckBoxFilterDefault: default
name
}
... on HeaderFilter {
type: __typename
name
}
... on SelectFilter {
type: __typename
SelectFilterDefault: default
name
values
}
... on TriStateFilter {
type: __typename
TriStateFilterDefault: default
name
}
... on TextFilter {
type: __typename
TextFilterDefault: default
name
}
... on SortFilter {
type: __typename
SortFilterDefault: default {
ascending
index
}
name
values
}
... on SeparatorFilter {
type: __typename
name
}
... on GroupFilter {
type: __typename
name
filters {
... on CheckBoxFilter {
type: __typename
CheckBoxFilterDefault: default
name
}
... on HeaderFilter {
type: __typename
name
}
... on SelectFilter {
type: __typename
SelectFilterDefault: default
name
values
}
... on TriStateFilter {
type: __typename
TriStateFilterDefault: default
name
}
... on TextFilter {
type: __typename
TextFilterDefault: default
name
}
... on SortFilter {
type: __typename
SortFilterDefault: default {
ascending
index
}
name
values
}
... on SeparatorFilter {
type: __typename
name
}
}
}
}
}
`;
export const FULL_TRACKER_FIELDS = gql` export const FULL_TRACKER_FIELDS = gql`
fragment FULL_TRACKER_FIELDS on TrackerType { fragment FULL_TRACKER_FIELDS on TrackerType {
id id
@@ -266,7 +104,7 @@ export const FULL_TRACK_RECORD_FIELDS = gql`
`; `;
export const BASE_MANGA_FIELDS = gql` export const BASE_MANGA_FIELDS = gql`
${PARTIAL_SOURCE_FIELDS} ${SOURCE_BASE_FIELDS}
${FULL_TRACK_RECORD_FIELDS} ${FULL_TRACK_RECORD_FIELDS}
fragment BASE_MANGA_FIELDS on MangaType { fragment BASE_MANGA_FIELDS on MangaType {
artist artist
@@ -285,7 +123,7 @@ export const BASE_MANGA_FIELDS = gql`
} }
realUrl realUrl
source { source {
...PARTIAL_SOURCE_FIELDS ...SOURCE_BASE_FIELDS
} }
status status
thumbnailUrl thumbnailUrl
@@ -304,7 +142,6 @@ export const BASE_MANGA_FIELDS = gql`
export const PARTIAL_MANGA_FIELDS = gql` export const PARTIAL_MANGA_FIELDS = gql`
${BASE_MANGA_FIELDS} ${BASE_MANGA_FIELDS}
${FULL_CATEGORY_FIELDS} ${FULL_CATEGORY_FIELDS}
${PARTIAL_SOURCE_FIELDS}
fragment PARTIAL_MANGA_FIELDS on MangaType { fragment PARTIAL_MANGA_FIELDS on MangaType {
...BASE_MANGA_FIELDS ...BASE_MANGA_FIELDS
unreadCount unreadCount

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import gql from 'graphql-tag';
export const SOURCE_BASE_FIELDS = gql`
fragment SOURCE_BASE_FIELDS on SourceType {
id
name
displayName
}
`;
export const SOURCE_MIGRATABLE_FIELDS = gql`
${SOURCE_BASE_FIELDS}
fragment SOURCE_MIGRATABLE_FIELDS on SourceType {
...SOURCE_BASE_FIELDS
lang
iconUrl
}
`;
export const SOURCE_LIST_FIELDS = gql`
${SOURCE_BASE_FIELDS}
fragment SOURCE_LIST_FIELDS on SourceType {
...SOURCE_BASE_FIELDS
lang
iconUrl
isNsfw
supportsLatest
extension {
pkgName
repo
}
}
`;
export const SOURCE_BROWSE_FIELDS = gql`
${SOURCE_BASE_FIELDS}
fragment SOURCE_BROWSE_FIELDS on SourceType {
...SOURCE_BASE_FIELDS
isConfigurable
supportsLatest
meta {
key
value
}
filters {
... on CheckBoxFilter {
type: __typename
CheckBoxFilterDefault: default
name
}
... on HeaderFilter {
type: __typename
name
}
... on SelectFilter {
type: __typename
SelectFilterDefault: default
name
values
}
... on TriStateFilter {
type: __typename
TriStateFilterDefault: default
name
}
... on TextFilter {
type: __typename
TextFilterDefault: default
name
}
... on SortFilter {
type: __typename
SortFilterDefault: default {
ascending
index
}
name
values
}
... on SeparatorFilter {
type: __typename
name
}
... on GroupFilter {
type: __typename
name
filters {
... on CheckBoxFilter {
type: __typename
CheckBoxFilterDefault: default
name
}
... on HeaderFilter {
type: __typename
name
}
... on SelectFilter {
type: __typename
SelectFilterDefault: default
name
values
}
... on TriStateFilter {
type: __typename
TriStateFilterDefault: default
name
}
... on TextFilter {
type: __typename
TextFilterDefault: default
name
}
... on SortFilter {
type: __typename
SortFilterDefault: default {
ascending
index
}
name
values
}
... on SeparatorFilter {
type: __typename
name
}
}
}
}
}
`;
export const SOURCE_SETTING_FIELDS = gql`
${SOURCE_BASE_FIELDS}
fragment SOURCE_SETTING_FIELDS on SourceType {
...SOURCE_BASE_FIELDS
preferences {
... on CheckBoxPreference {
type: __typename
CheckBoxCheckBoxCurrentValue: currentValue
summary
CheckBoxDefault: default
key
CheckBoxTitle: title
}
... on EditTextPreference {
type: __typename
EditTextPreferenceCurrentValue: currentValue
EditTextPreferenceDefault: default
EditTextPreferenceTitle: title
text
summary
key
dialogTitle
dialogMessage
}
... on SwitchPreference {
type: __typename
SwitchPreferenceCurrentValue: currentValue
summary
key
SwitchPreferenceDefault: default
SwitchPreferenceTitle: title
}
... on MultiSelectListPreference {
type: __typename
dialogMessage
dialogTitle
MultiSelectListPreferenceTitle: title
summary
key
entryValues
entries
MultiSelectListPreferenceDefault: default
MultiSelectListPreferenceCurrentValue: currentValue
}
... on ListPreference {
type: __typename
ListPreferenceCurrentValue: currentValue
ListPreferenceDefault: default
ListPreferenceTitle: title
summary
key
entryValues
entries
}
}
}
`;

View File

@@ -1,7 +1,7 @@
import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache'; import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
import { import {
GetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables, GetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
GetMangaQueryVariables, GetSourceQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables, GetMangaQueryVariables, GetSourceBrowseQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
} from "@/lib/graphql/generated/graphql.ts"; } from "@/lib/graphql/generated/graphql.ts";
import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies"; import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";
export type AboutServerPayloadKeySpecifier = ('buildTime' | 'buildType' | 'discord' | 'github' | 'name' | 'revision' | 'version' | AboutServerPayloadKeySpecifier)[]; export type AboutServerPayloadKeySpecifier = ('buildTime' | 'buildType' | 'discord' | 'github' | 'name' | 'revision' | 'version' | AboutServerPayloadKeySpecifier)[];
@@ -590,7 +590,7 @@ export type QueryFieldPolicy = {
restoreStatus?: FieldPolicy<any> | FieldReadFunction<any>, restoreStatus?: FieldPolicy<any> | FieldReadFunction<any>,
searchTracker?: FieldPolicy<any> | FieldReadFunction<any>, searchTracker?: FieldPolicy<any> | FieldReadFunction<any>,
settings?: FieldPolicy<any> | FieldReadFunction<any>, settings?: FieldPolicy<any> | FieldReadFunction<any>,
source?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>>, source?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetSourceBrowseQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetSourceBrowseQueryVariables>>,
sources?: FieldPolicy<any> | FieldReadFunction<any>, sources?: FieldPolicy<any> | FieldReadFunction<any>,
trackRecord?: FieldPolicy<any> | FieldReadFunction<any>, trackRecord?: FieldPolicy<any> | FieldReadFunction<any>,
trackRecords?: FieldPolicy<any> | FieldReadFunction<any>, trackRecords?: FieldPolicy<any> | FieldReadFunction<any>,

File diff suppressed because one or more lines are too long

View File

@@ -8,6 +8,7 @@
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { BASE_MANGA_FIELDS } from '@/lib/graphql/Fragments'; import { BASE_MANGA_FIELDS } from '@/lib/graphql/Fragments';
import { SOURCE_SETTING_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
export const GET_SOURCE_MANGAS_FETCH = gql` export const GET_SOURCE_MANGAS_FETCH = gql`
${BASE_MANGA_FIELDS} ${BASE_MANGA_FIELDS}
@@ -23,62 +24,13 @@ export const GET_SOURCE_MANGAS_FETCH = gql`
`; `;
export const UPDATE_SOURCE_PREFERENCES = gql` export const UPDATE_SOURCE_PREFERENCES = gql`
${SOURCE_SETTING_FIELDS}
mutation UPDATE_SOURCE_PREFERENCES($input: UpdateSourcePreferenceInput!) { mutation UPDATE_SOURCE_PREFERENCES($input: UpdateSourcePreferenceInput!) {
updateSourcePreference(input: $input) { updateSourcePreference(input: $input) {
clientMutationId clientMutationId
source { source {
id ...SOURCE_SETTING_FIELDS
preferences {
... on CheckBoxPreference {
type: __typename
CheckBoxCheckBoxCurrentValue: currentValue
summary
CheckBoxDefault: default
key
CheckBoxTitle: title
}
... on EditTextPreference {
type: __typename
EditTextPreferenceCurrentValue: currentValue
EditTextPreferenceDefault: default
EditTextPreferenceTitle: title
text
summary
key
dialogTitle
dialogMessage
}
... on SwitchPreference {
type: __typename
SwitchPreferenceCurrentValue: currentValue
summary
key
SwitchPreferenceDefault: default
SwitchPreferenceTitle: title
}
... on MultiSelectListPreference {
type: __typename
dialogMessage
dialogTitle
MultiSelectListPreferenceTitle: title
summary
key
entryValues
entries
MultiSelectListPreferenceDefault: default
MultiSelectListPreferenceCurrentValue: currentValue
}
... on ListPreference {
type: __typename
ListPreferenceCurrentValue: currentValue
ListPreferenceDefault: default
ListPreferenceTitle: title
summary
key
entryValues
entries
}
}
} }
} }
} }

View File

@@ -7,38 +7,64 @@
*/ */
import gql from 'graphql-tag'; import gql from 'graphql-tag';
import { FULL_SOURCE_FIELDS, PARTIAL_SOURCE_FIELDS } from '@/lib/graphql/Fragments'; import {
SOURCE_BROWSE_FIELDS,
SOURCE_LIST_FIELDS,
SOURCE_MIGRATABLE_FIELDS,
SOURCE_SETTING_FIELDS,
} from '@/lib/graphql/fragments/SourceFragments.ts';
export const GET_SOURCE = gql` export const GET_SOURCE_BROWSE = gql`
${FULL_SOURCE_FIELDS} ${SOURCE_BROWSE_FIELDS}
query GET_SOURCE($id: LongString!) {
query GET_SOURCE_BROWSE($id: LongString!) {
source(id: $id) { source(id: $id) {
...FULL_SOURCE_FIELDS ...SOURCE_BROWSE_FIELDS
} }
} }
`; `;
export const GET_SOURCES = gql` export const GET_SOURCE_SETTINGS = gql`
${PARTIAL_SOURCE_FIELDS} ${SOURCE_SETTING_FIELDS}
query GET_SOURCES {
query GET_SOURCE_SETTINGS($id: LongString!) {
source(id: $id) {
...SOURCE_SETTING_FIELDS
}
}
`;
export const GET_SOURCE_MIGRATABLE = gql`
${SOURCE_MIGRATABLE_FIELDS}
query GET_SOURCE_MIGRATABLE($id: LongString!) {
source(id: $id) {
...SOURCE_MIGRATABLE_FIELDS
}
}
`;
export const GET_SOURCES_LIST = gql`
${SOURCE_LIST_FIELDS}
query GET_SOURCES_LIST {
sources { sources {
nodes { nodes {
...PARTIAL_SOURCE_FIELDS ...SOURCE_LIST_FIELDS
} }
} }
} }
`; `;
export const GET_MIGRATABLE_SOURCES = gql` export const GET_MIGRATABLE_SOURCES = gql`
${SOURCE_MIGRATABLE_FIELDS}
query GET_MIGRATABLE_SOURCES { query GET_MIGRATABLE_SOURCES {
mangas(condition: { inLibrary: true }) { mangas(condition: { inLibrary: true }) {
nodes { nodes {
sourceId sourceId
source { source {
id ...SOURCE_MIGRATABLE_FIELDS
name
lang
iconUrl
} }
} }
} }

View File

@@ -15,10 +15,9 @@ import {
MetadataHolder, MetadataHolder,
MetadataKeyValuePair, MetadataKeyValuePair,
TManga, TManga,
TPartialSource,
} from '@/typings.ts'; } from '@/typings.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { MetaType } from '@/lib/graphql/generated/graphql.ts'; import { MetaType, SourceType } from '@/lib/graphql/generated/graphql.ts';
import { DEFAULT_DEVICE, getActiveDevice } from '@/util/device.ts'; import { DEFAULT_DEVICE, getActiveDevice } from '@/util/device.ts';
import { CategoryIdInfo } from '@/lib/data/Categories.ts'; import { CategoryIdInfo } from '@/lib/data/Categories.ts';
import { ChapterIdInfo } from '@/lib/data/Chapters.ts'; import { ChapterIdInfo } from '@/lib/data/Chapters.ts';
@@ -382,7 +381,8 @@ export const requestUpdateMetadataValue = async (
await requestManager.setMangaMeta((metadataHolder as TManga).id, metadataKey, value).response; await requestManager.setMangaMeta((metadataHolder as TManga).id, metadataKey, value).response;
break; break;
case 'source': case 'source':
await requestManager.setSourceMeta((metadataHolder as TPartialSource).id, metadataKey, value).response; await requestManager.setSourceMeta((metadataHolder as Pick<SourceType, 'id'>).id, metadataKey, value)
.response;
break; break;
default: default:
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`); throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
@@ -415,6 +415,6 @@ export const requestUpdateCategoryMetadata = async (
): Promise<void[]> => requestUpdateMetadata(category, 'category', keysToValues); ): Promise<void[]> => requestUpdateMetadata(category, 'category', keysToValues);
export const requestUpdateSourceMetadata = async ( export const requestUpdateSourceMetadata = async (
source: TPartialSource, source: Pick<SourceType, 'id'> & GqlMetaHolder,
keysToValue: MetadataKeyValuePair[], keysToValue: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata(source, 'source', keysToValue); ): Promise<void[]> => requestUpdateMetadata(source, 'source', keysToValue);

View File

@@ -13,11 +13,11 @@ import {
ISourceMetadata, ISourceMetadata,
Metadata, Metadata,
SourceMetadataKeys, SourceMetadataKeys,
TPartialSource,
} from '@/typings.ts'; } from '@/typings.ts';
import { jsonSaveParse } from '@/util/HelperFunctions.ts'; import { jsonSaveParse } from '@/util/HelperFunctions.ts';
import { convertFromGqlMeta, getMetadataFrom, requestUpdateSourceMetadata } from '@/lib/metadata/metadata.ts'; import { convertFromGqlMeta, getMetadataFrom, requestUpdateSourceMetadata } from '@/lib/metadata/metadata.ts';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
const convertAppMetadataToGqlMetadata = ( const convertAppMetadataToGqlMetadata = (
metadata: Partial<ISourceMetadata>, metadata: Partial<ISourceMetadata>,
@@ -42,7 +42,7 @@ export const updateSourceMetadata = async <
MetadataKeys extends SourceMetadataKeys = SourceMetadataKeys, MetadataKeys extends SourceMetadataKeys = SourceMetadataKeys,
MetadataKey extends MetadataKeys = MetadataKeys, MetadataKey extends MetadataKeys = MetadataKeys,
>( >(
source: TPartialSource, source: Pick<SourceType, 'id'> & GqlMetaHolder,
metadataKey: MetadataKey, metadataKey: MetadataKey,
value: ISourceMetadata[MetadataKey], value: ISourceMetadata[MetadataKey],
): Promise<void[]> => ): Promise<void[]> =>
@@ -52,7 +52,7 @@ export const updateSourceMetadata = async <
export const createUpdateSourceMetadata = export const createUpdateSourceMetadata =
<Settings extends SourceMetadataKeys>( <Settings extends SourceMetadataKeys>(
source: TPartialSource, source: Pick<SourceType, 'id'> & GqlMetaHolder,
handleError: (error: any) => void = defaultPromiseErrorHandler('createUpdateSourceMetadata'), handleError: (error: any) => void = defaultPromiseErrorHandler('createUpdateSourceMetadata'),
): ((...args: OmitFirst<Parameters<typeof updateSourceMetadata<Settings>>>) => Promise<void | void[]>) => ): ((...args: OmitFirst<Parameters<typeof updateSourceMetadata<Settings>>>) => Promise<void | void[]>) =>
(metadataKey, value) => (metadataKey, value) =>

View File

@@ -90,10 +90,6 @@ import {
GetServerSettingsQuery, GetServerSettingsQuery,
GetSourceMangasFetchMutation, GetSourceMangasFetchMutation,
GetSourceMangasFetchMutationVariables, GetSourceMangasFetchMutationVariables,
GetSourceQuery,
GetSourceQueryVariables,
GetSourcesQuery,
GetSourcesQueryVariables,
GetUpdateStatusQuery, GetUpdateStatusQuery,
GetUpdateStatusQueryVariables, GetUpdateStatusQueryVariables,
InstallExternalExtensionMutation, InstallExternalExtensionMutation,
@@ -201,6 +197,8 @@ import {
GetChaptersMangaQueryVariables, GetChaptersMangaQueryVariables,
GetChaptersUpdatesQuery, GetChaptersUpdatesQuery,
GetChaptersUpdatesQueryVariables, GetChaptersUpdatesQueryVariables,
GetSourcesListQuery,
GetSourcesListQueryVariables,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
import { GET_GLOBAL_METADATAS } from '@/lib/graphql/queries/GlobalMetadataQuery.ts'; import { GET_GLOBAL_METADATAS } from '@/lib/graphql/queries/GlobalMetadataQuery.ts';
import { SET_GLOBAL_METADATA } from '@/lib/graphql/mutations/GlobalMetadataMutation.ts'; import { SET_GLOBAL_METADATA } from '@/lib/graphql/mutations/GlobalMetadataMutation.ts';
@@ -216,7 +214,7 @@ import {
INSTALL_EXTERNAL_EXTENSION, INSTALL_EXTERNAL_EXTENSION,
UPDATE_EXTENSION, UPDATE_EXTENSION,
} from '@/lib/graphql/mutations/ExtensionMutation.ts'; } from '@/lib/graphql/mutations/ExtensionMutation.ts';
import { GET_MIGRATABLE_SOURCES, GET_SOURCE, GET_SOURCES } from '@/lib/graphql/queries/SourceQuery.ts'; import { GET_MIGRATABLE_SOURCES, GET_SOURCES_LIST } from '@/lib/graphql/queries/SourceQuery.ts';
import { import {
GET_MANGA_FETCH, GET_MANGA_FETCH,
GET_MANGA_TO_MIGRATE_TO_FETCH, GET_MANGA_TO_MIGRATE_TO_FETCH,
@@ -1352,16 +1350,17 @@ export class RequestManager {
} }
public useGetSourceList( public useGetSourceList(
options?: QueryHookOptions<GetSourcesQuery, GetSourcesQueryVariables>, options?: QueryHookOptions<GetSourcesListQuery, GetSourcesListQueryVariables>,
): AbortableApolloUseQueryResponse<GetSourcesQuery, GetSourcesQueryVariables> { ): AbortableApolloUseQueryResponse<GetSourcesListQuery, GetSourcesListQueryVariables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_SOURCES, {}, options); return this.doRequest(GQLMethod.USE_QUERY, GET_SOURCES_LIST, {}, options);
} }
public useGetSource( public useGetSource<Data, Variables extends OperationVariables>(
document: DocumentNode | TypedDocumentNode<Data, Variables>,
id: string, id: string,
options?: QueryHookOptions<GetSourceQuery, GetSourceQueryVariables>, options?: QueryHookOptions<Data, Variables>,
): AbortableApolloUseQueryResponse<GetSourceQuery, GetSourceQueryVariables> { ): AbortableApolloUseQueryResponse<Data, Variables> {
return this.doRequest(GQLMethod.USE_QUERY, GET_SOURCE, { id }, options); return this.doRequest(GQLMethod.USE_QUERY, document, { id } as unknown as Variables, options);
} }
public setSourceMeta( public setSourceMeta(

View File

@@ -8,7 +8,6 @@
import { useContext, useEffect, useState } from 'react'; import { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import gql from 'graphql-tag';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { NavBarContext } from '@/components/context/NavbarContext.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
@@ -21,6 +20,9 @@ import { GridLayouts } from '@/components/source/GridLayouts.tsx';
import { useLocalStorage } from '@/util/useStorage.tsx'; import { useLocalStorage } from '@/util/useStorage.tsx';
import { GridLayout } from '@/components/context/LibraryOptionsContext.tsx'; import { GridLayout } from '@/components/context/LibraryOptionsContext.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { GetSourceMigratableQuery, GetSourceMigratableQueryVariables } from '@/lib/graphql/generated/graphql.ts';
import { GET_SOURCE_MIGRATABLE } from '@/lib/graphql/queries/SourceQuery.ts';
import { SOURCE_BASE_FIELDS } from '@/lib/graphql/fragments/SourceFragments.ts';
export const Migrate = () => { export const Migrate = () => {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -34,12 +36,7 @@ export const Migrate = () => {
Pick<TMigratableSource, 'id' | 'name'> Pick<TMigratableSource, 'id' | 'name'>
>({ >({
id: requestManager.graphQLClient.client.cache.identify({ __typename: 'SourceType', id: paramSourceId }), id: requestManager.graphQLClient.client.cache.identify({ __typename: 'SourceType', id: paramSourceId }),
fragment: gql` fragment: SOURCE_BASE_FIELDS,
fragment MigratableSource on SourceType {
id
name
}
`,
}); });
const [isKnownSource, setIsKnownSource] = useState(fragmentSource !== null ? true : undefined); const [isKnownSource, setIsKnownSource] = useState(fragmentSource !== null ? true : undefined);
@@ -48,7 +45,11 @@ export const Migrate = () => {
loading: isSourceLoading, loading: isSourceLoading,
error: sourceError, error: sourceError,
refetch: refetchSource, refetch: refetchSource,
} = requestManager.useGetSource(paramSourceId, { skip: !!isKnownSource, notifyOnNetworkStatusChange: true }); } = requestManager.useGetSource<GetSourceMigratableQuery, GetSourceMigratableQueryVariables>(
GET_SOURCE_MIGRATABLE,
paramSourceId,
{ skip: !!isKnownSource, notifyOnNetworkStatusChange: true },
);
const { sourceId, name } = { const { sourceId, name } = {
sourceId: paramSourceId, sourceId: paramSourceId,

View File

@@ -13,7 +13,6 @@ import React, { useCallback, useContext, useEffect, useMemo, useState } from 're
import { Link, useLocation } from 'react-router-dom'; import { Link, useLocation } from 'react-router-dom';
import { StringParam, useQueryParam } from 'use-query-params'; import { StringParam, useQueryParam } from 'use-query-params';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ISource } from '@/typings';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { useLocalStorage } from '@/util/useStorage.tsx'; import { useLocalStorage } from '@/util/useStorage.tsx';
import { langSortCmp, sourceDefualtLangs, sourceForcedDefaultLangs } from '@/util/language'; import { langSortCmp, sourceDefualtLangs, sourceForcedDefaultLangs } from '@/util/language';
@@ -28,11 +27,12 @@ import { EmptyView } from '@/components/util/EmptyView';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean }; type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean };
type SourceToLoadingStateMap = Map<string, SourceLoadingState>; type SourceToLoadingStateMap = Map<string, SourceLoadingState>;
function sourceToLangList(sources: ISource[]) { function sourceToLangList(sources: Pick<SourceType, 'lang'>[]) {
const result: string[] = []; const result: string[] = [];
sources.forEach((source) => { sources.forEach((source) => {
@@ -45,7 +45,10 @@ function sourceToLangList(sources: ISource[]) {
return result; return result;
} }
const compareSourceByName = (sourceA: ISource, sourceB: ISource): -1 | 0 | 1 => { const compareSourceByName = (
sourceA: Pick<SourceType, 'displayName'>,
sourceB: Pick<SourceType, 'displayName'>,
): -1 | 0 | 1 => {
if (sourceA.displayName < sourceB.displayName) { if (sourceA.displayName < sourceB.displayName) {
return -1; return -1;
} }
@@ -56,8 +59,8 @@ const compareSourceByName = (sourceA: ISource, sourceB: ISource): -1 | 0 | 1 =>
}; };
const compareSourcesBySearchResult = ( const compareSourcesBySearchResult = (
sourceA: ISource, sourceA: Pick<SourceType, 'id'>,
sourceB: ISource, sourceB: Pick<SourceType, 'id'>,
sourceToFetchedStateMap: SourceToLoadingStateMap, sourceToFetchedStateMap: SourceToLoadingStateMap,
): -1 | 0 | 1 => { ): -1 | 0 | 1 => {
const isSourceAFetched = !sourceToFetchedStateMap.get(sourceA.id)?.isLoading; const isSourceAFetched = !sourceToFetchedStateMap.get(sourceA.id)?.isLoading;
@@ -93,9 +96,9 @@ const SourceSearchPreview = React.memo(
emptyQuery, emptyQuery,
mode, mode,
}: { }: {
source: ISource; source: Pick<SourceType, 'id' | 'displayName' | 'lang'>;
onSearchRequestFinished: ( onSearchRequestFinished: (
source: ISource, source: Pick<SourceType, 'id'>,
isLoading: boolean, isLoading: boolean,
hasResults: boolean, hasResults: boolean,
emptySearch: boolean, emptySearch: boolean,
@@ -130,9 +133,7 @@ const SourceSearchPreview = React.memo(
// INFO: // INFO:
// with strict mode + dev mode the first request will be aborted. due to using SWR there won't be an // with strict mode + dev mode the first request will be aborted. due to using SWR there won't be an
// immediate second request since it's the same key. instead the "second" request will be the error handling of SWR // immediate second request since it's the same key. instead the "second" request will be the error handling of SWR
abortRequest( abortRequest(new Error(`SourceSearchPreview(${id}, ${displayName}): search string changed`));
new Error(`SourceSearchPreview(${source.id}, ${source.displayName}): search string changed`),
);
}, },
[searchString], [searchString],
); );
@@ -221,7 +222,7 @@ export const SearchAll: React.FC = () => {
); );
const updateSourceLoadingState = useCallback( const updateSourceLoadingState = useCallback(
({ id }: ISource, isLoading: boolean, hasResults: boolean, emptySearch: boolean) => { ({ id }: Pick<SourceType, 'id'>, isLoading: boolean, hasResults: boolean, emptySearch: boolean) => {
setSourceToLoadingStateMap((currentMap) => { setSourceToLoadingStateMap((currentMap) => {
const mapCopy = new Map(currentMap); const mapCopy = new Map(currentMap);
mapCopy.set(id, { isLoading, hasResults, emptySearch }); mapCopy.set(id, { isLoading, hasResults, emptySearch });

View File

@@ -21,6 +21,8 @@ import { NavBarContext } from '@/components/context/NavbarContext.tsx';
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { GetCategoriesSettingsQueryVariables, GetSourceSettingsQuery } from '@/lib/graphql/generated/graphql.ts';
import { GET_SOURCE_SETTINGS } from '@/lib/graphql/queries/SourceQuery.ts';
function getPrefComponent(type: string) { function getPrefComponent(type: string) {
switch (type) { switch (type) {
@@ -54,7 +56,10 @@ export function SourceConfigure() {
}, [t]); }, [t]);
const { sourceId } = useParams<{ sourceId: string }>(); const { sourceId } = useParams<{ sourceId: string }>();
const { data, loading, error, refetch } = requestManager.useGetSource(sourceId, { const { data, loading, error, refetch } = requestManager.useGetSource<
GetSourceSettingsQuery,
GetCategoriesSettingsQueryVariables
>(GET_SOURCE_SETTINGS, sourceId, {
notifyOnNetworkStatusChange: true, notifyOnNetworkStatusChange: true,
}); });
const sourcePreferences = data?.source.preferences ?? []; const sourcePreferences = data?.source.preferences ?? [];

View File

@@ -20,7 +20,7 @@ import { styled } from '@mui/material/styles';
import FavoriteIcon from '@mui/icons-material/Favorite'; import FavoriteIcon from '@mui/icons-material/Favorite';
import NewReleasesIcon from '@mui/icons-material/NewReleases'; import NewReleasesIcon from '@mui/icons-material/NewReleases';
import FilterListIcon from '@mui/icons-material/FilterList'; import FilterListIcon from '@mui/icons-material/FilterList';
import { IPos, TPartialManga, TPartialSource, TranslationKey } from '@/typings'; import { IPos, TPartialManga, TranslationKey } from '@/typings';
import { import {
requestManager, requestManager,
AbortableApolloUseMutationPaginatedResponse, AbortableApolloUseMutationPaginatedResponse,
@@ -32,6 +32,8 @@ import { AppbarSearch } from '@/components/util/AppbarSearch';
import { SourceOptions } from '@/components/source/SourceOptions'; import { SourceOptions } from '@/components/source/SourceOptions';
import { SourceMangaGrid } from '@/components/source/SourceMangaGrid'; import { SourceMangaGrid } from '@/components/source/SourceMangaGrid';
import { import {
GetSourceBrowseQuery,
GetSourceBrowseQueryVariables,
GetSourceMangasFetchMutation, GetSourceMangasFetchMutation,
GetSourceMangasFetchMutationVariables, GetSourceMangasFetchMutationVariables,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
@@ -42,6 +44,7 @@ import { AppStorage } from '@/util/AppStorage.ts';
import { getGridSnapshotKey } from '@/components/MangaGrid.tsx'; import { getGridSnapshotKey } from '@/components/MangaGrid.tsx';
import { createUpdateSourceMetadata, getSourceMetadata } from '@/lib/metadata/sourceMetadata.ts'; import { createUpdateSourceMetadata, getSourceMetadata } from '@/lib/metadata/sourceMetadata.ts';
import { makeToast } from '@/components/util/Toast.tsx'; import { makeToast } from '@/components/util/Toast.tsx';
import { GET_SOURCE_BROWSE } from '@/lib/graphql/queries/SourceQuery.ts';
const ContentTypeMenu = styled('div')(({ theme }) => ({ const ContentTypeMenu = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
@@ -280,14 +283,16 @@ export function SourceMangas() {
const isLoading = loading || filteredOutAllItemsOfFetchedPage; const isLoading = loading || filteredOutAllItemsOfFetchedPage;
const mangas = data?.fetchSourceManga?.mangas ?? []; const mangas = data?.fetchSourceManga?.mangas ?? [];
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage; const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
const { data: sourceData } = requestManager.useGetSource(sourceId); const { data: sourceData } = requestManager.useGetSource<GetSourceBrowseQuery, GetSourceBrowseQueryVariables>(
GET_SOURCE_BROWSE,
sourceId,
);
const source = sourceData?.source; const source = sourceData?.source;
const filters = source?.filters ?? []; const filters = source?.filters ?? [];
const { savedSearches = {} } = useMemo(() => getSourceMetadata(source), [source, source?.meta]); const { savedSearches = {} } = useMemo(() => getSourceMetadata(source), [source, source?.meta]);
const updateSourceMetadata = createUpdateSourceMetadata<'savedSearches'>( const updateSourceMetadata = createUpdateSourceMetadata<'savedSearches'>(source ?? { id: sourceId }, () =>
source ?? ({ id: sourceId } as TPartialSource), makeToast(t('global.error.label.failed_to_save_changes'), 'error'),
() => makeToast(t('global.error.label.failed_to_save_changes'), 'error'),
); );
const selectSavedSearch = useCallback( const selectSavedSearch = useCallback(

View File

@@ -13,7 +13,6 @@ import Typography from '@mui/material/Typography';
import TravelExploreIcon from '@mui/icons-material/TravelExplore'; import TravelExploreIcon from '@mui/icons-material/TravelExplore';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ISource, TPartialSource } from '@/typings';
import { requestManager } from '@/lib/requests/RequestManager.ts'; import { requestManager } from '@/lib/requests/RequestManager.ts';
import { useLocalStorage } from '@/util/useStorage.tsx'; import { useLocalStorage } from '@/util/useStorage.tsx';
import { sourceDefualtLangs, sourceForcedDefaultLangs, langSortCmp } from '@/util/language'; import { sourceDefualtLangs, sourceForcedDefaultLangs, langSortCmp } from '@/util/language';
@@ -24,8 +23,9 @@ import { LangSelect } from '@/components/navbar/action/LangSelect';
import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { NavBarContext } from '@/components/context/NavbarContext.tsx';
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
import { SourceType } from '@/lib/graphql/generated/graphql.ts';
function sourceToLangList(sources: ISource[]) { function sourceToLangList(sources: Pick<SourceType, 'lang'>[]) {
const result: string[] = []; const result: string[] = [];
sources.forEach((source) => { sources.forEach((source) => {
@@ -38,11 +38,11 @@ function sourceToLangList(sources: ISource[]) {
return result; return result;
} }
function groupByLang(sources: ISource[]) { function groupByLang<Source extends Pick<SourceType, 'lang'>>(sources: Source[]): Record<string, Source[]> {
const result = {} as any; const result: Record<string, Source[]> = {};
sources.forEach((source) => { sources.forEach((source) => {
if (result[source.lang] === undefined) { if (result[source.lang] === undefined) {
result[source.lang] = [] as ISource[]; result[source.lang] = [];
} }
result[source.lang].push(source); result[source.lang].push(source);
}); });
@@ -150,7 +150,7 @@ export function Sources() {
> >
{translateExtensionLanguage(lang)} {translateExtensionLanguage(lang)}
</Typography> </Typography>
{(list as TPartialSource[]) {list
.filter((source) => showNsfw || !source.isNsfw) .filter((source) => showNsfw || !source.isNsfw)
.map((source) => ( .map((source) => (
<SourceCard <SourceCard

View File

@@ -15,8 +15,8 @@ import {
GetExtensionQuery, GetExtensionQuery,
GetMangaQuery, GetMangaQuery,
GetServerSettingsQuery, GetServerSettingsQuery,
GetSourceQuery, GetSourceBrowseQuery,
GetSourcesQuery, GetSourceSettingsQuery,
MetaType, MetaType,
SourcePreferenceChangeInput, SourcePreferenceChangeInput,
} from '@/lib/graphql/generated/graphql.ts'; } from '@/lib/graphql/generated/graphql.ts';
@@ -47,20 +47,7 @@ export interface ISourceMetadata {
savedSearches?: Record<string, SavedSourceSearch>; savedSearches?: Record<string, SavedSourceSearch>;
} }
export interface ISource { export type SourceFilters = GetSourceBrowseQuery['source']['filters'][number];
id: string;
name: string;
lang: string;
iconUrl: string;
supportsLatest: boolean;
isConfigurable: boolean;
isNsfw: boolean;
displayName: string;
}
export type TPartialSource = GetSourcesQuery['sources']['nodes'][number];
export type SourceFilters = GetSourceQuery['source']['filters'][number];
export interface IMetadataMigration { export interface IMetadataMigration {
appKeyPrefix?: { oldPrefix: string; newPrefix: string }; appKeyPrefix?: { oldPrefix: string; newPrefix: string };
@@ -100,19 +87,6 @@ export type AppMetadataKeys = MetadataServerSettingKeys | MangaMetadataKeys | Se
export type MetadataKeyValuePair = [AppMetadataKeys, AllowedMetadataValueTypes]; export type MetadataKeyValuePair = [AppMetadataKeys, AllowedMetadataValueTypes];
export interface IMangaCard {
id: number;
title: string;
genre: string[];
thumbnailUrl: string;
unreadCount?: number;
downloadCount?: number;
inLibrary?: boolean;
meta?: Metadata;
inLibraryAt: number;
lastReadAt: number;
}
export type TManga = GetMangaQuery['manga']; export type TManga = GetMangaQuery['manga'];
export type TPartialManga = OptionalProperty< export type TPartialManga = OptionalProperty<
@@ -120,84 +94,6 @@ export type TPartialManga = OptionalProperty<
'unreadCount' | 'downloadCount' | 'bookmarkCount' | 'categories' | 'chapters' 'unreadCount' | 'downloadCount' | 'bookmarkCount' | 'categories' | 'chapters'
>; >;
export interface IManga {
id: number;
sourceId: string;
url: string;
title: string;
thumbnailUrl: string;
artist: string;
author: string;
description: string;
genre: string[];
status: string;
inLibrary: boolean;
source: ISource;
meta: Metadata;
realUrl: string;
freshData: boolean;
unreadCount?: number;
downloadCount?: number;
age: number;
chaptersAge: number;
chaptersLastFetchedAt: number;
inLibraryAt: number;
initialized: boolean;
lastChapterRead: NullAndUndefined<IChapter>;
lastFetchedAt: number;
lastReadAt: number;
thumbnailUrlLastFetched: number;
updateStrategy: string;
}
export interface IChapter {
id: number;
url: string;
name: string;
uploadDate: number;
chapterNumber: number;
scanlator: string;
mangaId: number;
read: boolean;
bookmarked: boolean;
lastPageRead: number;
lastReadAt: number;
index: number;
fetchedAt: number;
chapterCount: number;
pageCount: number;
downloaded: boolean;
meta: Metadata;
}
export interface IMangaChapter {
manga: IManga;
chapter: IChapter;
}
export enum IncludeInGlobalUpdate {
EXCLUDE = 0,
INCLUDE = 1,
UNSET = -1,
}
export interface ICategory {
id: number;
order: number;
name: string;
default: boolean;
includeInUpdate: IncludeInGlobalUpdate;
includeInDownload: IncludeInGlobalUpdate;
meta: Metadata;
size: number;
}
export interface INavbarOverride { export interface INavbarOverride {
status: boolean; status: boolean;
value: any; value: any;
@@ -300,30 +196,7 @@ export interface IReaderProps {
prevChapter: () => void; prevChapter: () => void;
} }
export interface IDownloadChapter { export type SourcePreferences = GetSourceSettingsQuery['source']['preferences'][number];
chapterIndex: number;
mangaId: number;
state: 'Queued' | 'Downloading' | 'Finished' | 'Error';
progress: number;
chapter: IChapter;
manga: IManga;
}
export interface IQueue {
status: 'Stopped' | 'Started';
queue: IDownloadChapter[];
}
export interface IUpdateStatus {
running: boolean;
mangaStatusMap: {
COMPLETE?: IManga[];
RUNNING?: IManga[];
PENDING?: IManga[];
};
}
export type SourcePreferences = GetSourceQuery['source']['preferences'][number];
export interface PreferenceProps { export interface PreferenceProps {
updateValue: <Key extends keyof Omit<SourcePreferenceChangeInput, 'position'>>( updateValue: <Key extends keyof Omit<SourcePreferenceChangeInput, 'position'>>(
@@ -360,16 +233,6 @@ export interface NavbarItem {
show: 'mobile' | 'desktop' | 'both'; show: 'mobile' | 'desktop' | 'both';
} }
export interface PaginatedList<T> {
page: T[];
hasNextPage: boolean;
}
export type PaginatedMangaList = {
mangaList: IManga[];
hasNextPage: boolean;
};
export type NullAndUndefined<T> = T | null | undefined; export type NullAndUndefined<T> = T | null | undefined;
export type ChapterSortMode = 'fetchedAt' | 'source' | 'chapterNumber' | 'uploadedAt'; export type ChapterSortMode = 'fetchedAt' | 'source' | 'chapterNumber' | 'uploadedAt';
@@ -422,21 +285,4 @@ export interface LibraryOptions {
tracker: Record<TBaseTracker['id'], NullAndUndefined<boolean>>; tracker: Record<TBaseTracker['id'], NullAndUndefined<boolean>>;
} }
export type UpdateCheck = {
channel: 'Stable' | 'Preview';
tag: string;
url: string;
};
export type SourceSearchResult = {
mangaList: IManga[];
hasNextPage: boolean;
};
export type BackupValidationResult = {
missingSources: string[];
missingTrackers: string[];
mangasMissingSources: string[];
};
export type ServerSettings = GetServerSettingsQuery['settings']; export type ServerSettings = GetServerSettingsQuery['settings'];

View File

@@ -42,7 +42,7 @@ const addImports = format(
`import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache'; `import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
import { import {
\tGetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables, \tGetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
\tGetMangaQueryVariables, GetSourceQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables, \tGetMangaQueryVariables, GetSourceBrowseQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
} from "@/lib/graphql/generated/graphql.ts"; } from "@/lib/graphql/generated/graphql.ts";
import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";`, import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";`,
); );
@@ -100,7 +100,7 @@ const fixTypingOfQueryTypePolicies = format(
\trestoreStatus?: FieldPolicy<any> | FieldReadFunction<any>, \trestoreStatus?: FieldPolicy<any> | FieldReadFunction<any>,
\tsearchTracker?: FieldPolicy<any> | FieldReadFunction<any>, \tsearchTracker?: FieldPolicy<any> | FieldReadFunction<any>,
\tsettings?: FieldPolicy<any> | FieldReadFunction<any>, \tsettings?: FieldPolicy<any> | FieldReadFunction<any>,
\tsource?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>>, \tsource?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetSourceBrowseQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetSourceBrowseQueryVariables>>,
\tsources?: FieldPolicy<any> | FieldReadFunction<any>, \tsources?: FieldPolicy<any> | FieldReadFunction<any>,
\ttrackRecord?: FieldPolicy<any> | FieldReadFunction<any>, \ttrackRecord?: FieldPolicy<any> | FieldReadFunction<any>,
\ttrackRecords?: FieldPolicy<any> | FieldReadFunction<any>, \ttrackRecords?: FieldPolicy<any> | FieldReadFunction<any>,