Reduce requested chapter data in queries
This commit is contained in:
@@ -29,7 +29,6 @@ import {
|
|||||||
ChapterRealUrlInfo,
|
ChapterRealUrlInfo,
|
||||||
Chapters,
|
Chapters,
|
||||||
} from '@/lib/data/Chapters.ts';
|
} from '@/lib/data/Chapters.ts';
|
||||||
import { TChapter } from '@/typings.ts';
|
|
||||||
import { MenuItem } from '@/components/menu/MenuItem.tsx';
|
import { MenuItem } from '@/components/menu/MenuItem.tsx';
|
||||||
import { IChapterWithMeta } from '@/components/chapter/ChapterList.tsx';
|
import { IChapterWithMeta } from '@/components/chapter/ChapterList.tsx';
|
||||||
import { ChaptersWithMeta } from '@/lib/data/ChaptersWithMeta.ts';
|
import { ChaptersWithMeta } from '@/lib/data/ChaptersWithMeta.ts';
|
||||||
@@ -39,13 +38,15 @@ import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings
|
|||||||
|
|
||||||
type BaseProps = { onClose: () => void };
|
type BaseProps = { onClose: () => void };
|
||||||
|
|
||||||
|
type TChapter = ChapterIdInfo &
|
||||||
|
ChapterMangaInfo &
|
||||||
|
ChapterDownloadInfo &
|
||||||
|
ChapterBookmarkInfo &
|
||||||
|
ChapterReadInfo &
|
||||||
|
ChapterRealUrlInfo;
|
||||||
|
|
||||||
type SingleModeProps = {
|
type SingleModeProps = {
|
||||||
chapter: ChapterIdInfo &
|
chapter: TChapter;
|
||||||
ChapterMangaInfo &
|
|
||||||
ChapterDownloadInfo &
|
|
||||||
ChapterBookmarkInfo &
|
|
||||||
ChapterReadInfo &
|
|
||||||
ChapterRealUrlInfo;
|
|
||||||
allChapters: TChapter[];
|
allChapters: TChapter[];
|
||||||
handleSelection?: SelectableCollectionReturnType<TChapter['id']>['handleSelection'];
|
handleSelection?: SelectableCollectionReturnType<TChapter['id']>['handleSelection'];
|
||||||
canBeDownloaded: boolean;
|
canBeDownloaded: boolean;
|
||||||
|
|||||||
@@ -24,11 +24,28 @@ import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
|||||||
import { useLongPress } from 'use-long-press';
|
import { useLongPress } from 'use-long-press';
|
||||||
import { getDateString } from '@/util/date.ts';
|
import { getDateString } from '@/util/date.ts';
|
||||||
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator.tsx';
|
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator.tsx';
|
||||||
import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { TChapter } from '@/typings.ts';
|
|
||||||
import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx';
|
import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx';
|
||||||
import { Menu } from '@/components/menu/Menu.tsx';
|
import { Menu } from '@/components/menu/Menu.tsx';
|
||||||
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
|
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
|
||||||
|
import {
|
||||||
|
ChapterBookmarkInfo,
|
||||||
|
ChapterDownloadInfo,
|
||||||
|
ChapterIdInfo,
|
||||||
|
ChapterMangaInfo,
|
||||||
|
ChapterNumberInfo,
|
||||||
|
ChapterReadInfo,
|
||||||
|
ChapterScanlatorInfo,
|
||||||
|
} from '@/lib/data/Chapters.ts';
|
||||||
|
|
||||||
|
type TChapter = ChapterIdInfo &
|
||||||
|
ChapterMangaInfo &
|
||||||
|
ChapterDownloadInfo &
|
||||||
|
ChapterReadInfo &
|
||||||
|
ChapterBookmarkInfo &
|
||||||
|
ChapterNumberInfo &
|
||||||
|
ChapterScanlatorInfo &
|
||||||
|
Pick<ChapterType, 'name' | 'sourceOrder' | 'uploadDate'>;
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
chapter: TChapter;
|
chapter: TChapter;
|
||||||
@@ -86,7 +103,7 @@ export const ChapterCard: React.FC<IProps> = (props: IProps) => {
|
|||||||
<Card sx={{ touchCallout: 'none' }}>
|
<Card sx={{ touchCallout: 'none' }}>
|
||||||
<CardActionArea
|
<CardActionArea
|
||||||
component={Link}
|
component={Link}
|
||||||
to={`/manga/${chapter.manga.id}/chapter/${chapter.sourceOrder}`}
|
to={`/manga/${chapter.mangaId}/chapter/${chapter.sourceOrder}`}
|
||||||
style={{
|
style={{
|
||||||
color: theme.palette.text[chapter.isRead ? 'disabled' : 'primary'],
|
color: theme.palette.text[chapter.isRead ? 'disabled' : 'primary'],
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import DownloadIcon from '@mui/icons-material/Download';
|
|||||||
import DoneAllIcon from '@mui/icons-material/DoneAll';
|
import DoneAllIcon from '@mui/icons-material/DoneAll';
|
||||||
import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state';
|
||||||
import Menu from '@mui/material/Menu';
|
import Menu from '@mui/material/Menu';
|
||||||
import { TChapter, TManga } from '@/typings.ts';
|
import { TManga } from '@/typings.ts';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { ChapterCard } from '@/components/chapter/ChapterCard.tsx';
|
import { ChapterCard } from '@/components/chapter/ChapterCard.tsx';
|
||||||
import { ResumeFab } from '@/components/manga/ResumeFAB.tsx';
|
import { ResumeFab } from '@/components/manga/ResumeFAB.tsx';
|
||||||
@@ -28,7 +28,11 @@ import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCe
|
|||||||
import { ChaptersToolbarMenu } from '@/components/chapter/ChaptersToolbarMenu.tsx';
|
import { ChaptersToolbarMenu } from '@/components/chapter/ChaptersToolbarMenu.tsx';
|
||||||
import { SelectionFAB } from '@/components/collection/SelectionFAB.tsx';
|
import { SelectionFAB } from '@/components/collection/SelectionFAB.tsx';
|
||||||
import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab.tsx';
|
import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab.tsx';
|
||||||
import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
import {
|
||||||
|
DownloadType,
|
||||||
|
GetChaptersMangaQuery,
|
||||||
|
GetChaptersMangaQueryVariables,
|
||||||
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { useSelectableCollection } from '@/components/collection/useSelectableCollection.ts';
|
import { useSelectableCollection } from '@/components/collection/useSelectableCollection.ts';
|
||||||
import { SelectableCollectionSelectAll } from '@/components/collection/SelectableCollectionSelectAll.tsx';
|
import { SelectableCollectionSelectAll } from '@/components/collection/SelectableCollectionSelectAll.tsx';
|
||||||
import { Chapters } from '@/lib/data/Chapters.ts';
|
import { Chapters } from '@/lib/data/Chapters.ts';
|
||||||
@@ -37,6 +41,7 @@ import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuIt
|
|||||||
import { ChaptersDownloadActionMenuItems } from '@/components/chapter/ChaptersDownloadActionMenuItems.tsx';
|
import { ChaptersDownloadActionMenuItems } from '@/components/chapter/ChaptersDownloadActionMenuItems.tsx';
|
||||||
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 { GET_CHAPTERS_MANGA } from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||||
|
|
||||||
const ChapterListHeader = styled(Stack)(({ theme }) => ({
|
const ChapterListHeader = styled(Stack)(({ theme }) => ({
|
||||||
margin: 8,
|
margin: 8,
|
||||||
@@ -61,7 +66,7 @@ const StyledVirtuoso = styled(Virtuoso)(({ theme }) => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
export interface IChapterWithMeta {
|
export interface IChapterWithMeta {
|
||||||
chapter: TChapter;
|
chapter: React.ComponentProps<typeof ChapterCard>['chapter'];
|
||||||
downloadChapter: DownloadType | undefined;
|
downloadChapter: DownloadType | undefined;
|
||||||
selected: boolean | null;
|
selected: boolean | null;
|
||||||
}
|
}
|
||||||
@@ -83,7 +88,11 @@ export const ChapterList: React.FC<IProps> = ({ manga, isRefreshing }) => {
|
|||||||
loading: isLoading,
|
loading: isLoading,
|
||||||
error,
|
error,
|
||||||
refetch,
|
refetch,
|
||||||
} = requestManager.useGetMangaChapters(manga.id, { notifyOnNetworkStatusChange: true });
|
} = requestManager.useGetMangaChapters<GetChaptersMangaQuery, GetChaptersMangaQueryVariables>(
|
||||||
|
GET_CHAPTERS_MANGA,
|
||||||
|
manga.id,
|
||||||
|
{ notifyOnNetworkStatusChange: true },
|
||||||
|
);
|
||||||
const chapters = useMemo(() => chaptersData?.chapters.nodes ?? [], [chaptersData?.chapters.nodes]);
|
const chapters = useMemo(() => chaptersData?.chapters.nodes ?? [], [chaptersData?.chapters.nodes]);
|
||||||
|
|
||||||
const chapterIds = useMemo(() => chapters.map((chapter) => chapter.id), [chapters]);
|
const chapterIds = useMemo(() => chapters.map((chapter) => chapter.id), [chapters]);
|
||||||
@@ -106,7 +115,7 @@ export const ChapterList: React.FC<IProps> = ({ manga, isRefreshing }) => {
|
|||||||
() =>
|
() =>
|
||||||
visibleChapters.map((chapter) => {
|
visibleChapters.map((chapter) => {
|
||||||
const downloadChapter = queue?.find(
|
const downloadChapter = queue?.find(
|
||||||
(cd) => cd.chapter.sourceOrder === chapter.sourceOrder && cd.chapter.manga.id === chapter.manga.id,
|
(cd) => cd.chapter.sourceOrder === chapter.sourceOrder && cd.chapter.manga.id === chapter.mangaId,
|
||||||
);
|
);
|
||||||
const selected = !areNoItemsSelected ? selectedItemIds.includes(chapter.id) : null;
|
const selected = !areNoItemsSelected ? selectedItemIds.includes(chapter.id) : null;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ import {
|
|||||||
ChapterOptionsReducerAction,
|
ChapterOptionsReducerAction,
|
||||||
ChapterSortMode,
|
ChapterSortMode,
|
||||||
NullAndUndefined,
|
NullAndUndefined,
|
||||||
TChapter,
|
|
||||||
TranslationKey,
|
TranslationKey,
|
||||||
} from '@/typings.ts';
|
} from '@/typings.ts';
|
||||||
import { useReducerLocalStorage } from '@/util/useStorage.tsx';
|
import { useReducerLocalStorage } from '@/util/useStorage.tsx';
|
||||||
|
import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterReadInfo } from '@/lib/data/Chapters.ts';
|
||||||
|
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
const defaultChapterOptions: ChapterListOptions = {
|
const defaultChapterOptions: ChapterListOptions = {
|
||||||
active: false,
|
active: false,
|
||||||
@@ -46,7 +47,7 @@ function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOption
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChapterRead }: TChapter) {
|
export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChapterRead }: ChapterReadInfo) {
|
||||||
switch (unread) {
|
switch (unread) {
|
||||||
case true:
|
case true:
|
||||||
return !isChapterRead;
|
return !isChapterRead;
|
||||||
@@ -57,7 +58,7 @@ export function unreadFilter(unread: NullAndUndefined<boolean>, { isRead: isChap
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadFilter(downloaded: NullAndUndefined<boolean>, { isDownloaded: chapterDownload }: TChapter) {
|
function downloadFilter(downloaded: NullAndUndefined<boolean>, { isDownloaded: chapterDownload }: ChapterDownloadInfo) {
|
||||||
switch (downloaded) {
|
switch (downloaded) {
|
||||||
case true:
|
case true:
|
||||||
return chapterDownload;
|
return chapterDownload;
|
||||||
@@ -68,7 +69,10 @@ function downloadFilter(downloaded: NullAndUndefined<boolean>, { isDownloaded: c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function bookmarkedFilter(bookmarked: NullAndUndefined<boolean>, { isBookmarked: chapterBookmarked }: TChapter) {
|
function bookmarkedFilter(
|
||||||
|
bookmarked: NullAndUndefined<boolean>,
|
||||||
|
{ isBookmarked: chapterBookmarked }: ChapterBookmarkInfo,
|
||||||
|
) {
|
||||||
switch (bookmarked) {
|
switch (bookmarked) {
|
||||||
case true:
|
case true:
|
||||||
return chapterBookmarked;
|
return chapterBookmarked;
|
||||||
@@ -79,11 +83,12 @@ function bookmarkedFilter(bookmarked: NullAndUndefined<boolean>, { isBookmarked:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortChapters = (
|
type TChapterSort = Pick<ChapterType, 'sourceOrder' | 'fetchedAt' | 'chapterNumber' | 'uploadDate'>;
|
||||||
chapters: TChapter[],
|
const sortChapters = <T extends TChapterSort>(
|
||||||
|
chapters: T[],
|
||||||
{ sortBy, reverse }: Pick<ChapterListOptions, 'sortBy' | 'reverse'>,
|
{ sortBy, reverse }: Pick<ChapterListOptions, 'sortBy' | 'reverse'>,
|
||||||
): TChapter[] => {
|
): T[] => {
|
||||||
const sortedChapters: TChapter[] = [...chapters];
|
const sortedChapters: T[] = [...chapters];
|
||||||
|
|
||||||
switch (sortBy) {
|
switch (sortBy) {
|
||||||
case 'source':
|
case 'source':
|
||||||
@@ -109,7 +114,11 @@ const sortChapters = (
|
|||||||
return sortedChapters;
|
return sortedChapters;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function filterAndSortChapters(chapters: TChapter[], options: ChapterListOptions): TChapter[] {
|
type TChapterFilter = TChapterSort & ChapterReadInfo & ChapterDownloadInfo & ChapterBookmarkInfo;
|
||||||
|
export function filterAndSortChapters<Chapters extends TChapterFilter>(
|
||||||
|
chapters: Chapters[],
|
||||||
|
options: ChapterListOptions,
|
||||||
|
): Chapters[] {
|
||||||
const filtered = options.active
|
const filtered = options.active
|
||||||
? chapters.filter(
|
? chapters.filter(
|
||||||
(chp) =>
|
(chp) =>
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ import ListItem from '@mui/material/ListItem';
|
|||||||
import ListItemText from '@mui/material/ListItemText';
|
import ListItemText from '@mui/material/ListItemText';
|
||||||
import Collapse from '@mui/material/Collapse';
|
import Collapse from '@mui/material/Collapse';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings, TChapter, TManga } from '@/typings';
|
import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings, TManga } from '@/typings';
|
||||||
import { ReaderSettingsOptions } from '@/components/reader/ReaderSettingsOptions';
|
import { ReaderSettingsOptions } from '@/components/reader/ReaderSettingsOptions';
|
||||||
import { useBackButton } from '@/util/useBackButton.ts';
|
import { useBackButton } from '@/util/useBackButton.ts';
|
||||||
import { Select } from '@/components/atoms/Select.tsx';
|
import { Select } from '@/components/atoms/Select.tsx';
|
||||||
import { getOptionForDirection } from '@/theme.ts';
|
import { getOptionForDirection } from '@/theme.ts';
|
||||||
|
import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
|
||||||
const Root = styled('div')({
|
const Root = styled('div')({
|
||||||
zIndex: 10,
|
zIndex: 10,
|
||||||
@@ -123,8 +124,8 @@ interface IProps {
|
|||||||
settings: IReaderSettings;
|
settings: IReaderSettings;
|
||||||
setSettingValue: (key: keyof IReaderSettings, value: AllowedMetadataValueTypes, persist?: boolean) => void;
|
setSettingValue: (key: keyof IReaderSettings, value: AllowedMetadataValueTypes, persist?: boolean) => void;
|
||||||
manga: TManga;
|
manga: TManga;
|
||||||
chapter: TChapter;
|
chapter: Pick<ChapterType, 'name' | 'sourceOrder' | 'pageCount'>;
|
||||||
chapters: TChapter[];
|
chapters: Pick<ChapterType, 'id' | 'sourceOrder' | 'name' | 'chapterNumber' | 'scanlator'>[];
|
||||||
curPage: number;
|
curPage: number;
|
||||||
scrollToPage: (page: number) => void;
|
scrollToPage: (page: number) => void;
|
||||||
openNextChapter: (offset: ChapterOffset) => void;
|
openNextChapter: (offset: ChapterOffset) => void;
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
import { t as translate } from 'i18next';
|
import { t as translate } from 'i18next';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { DocumentNode } from '@apollo/client';
|
import { DocumentNode } from '@apollo/client';
|
||||||
import { ChapterOffset, TChapter, TManga, TranslationKey } from '@/typings.ts';
|
import { ChapterOffset, TManga, TranslationKey } from '@/typings.ts';
|
||||||
import { makeToast } from '@/components/util/Toast.tsx';
|
import { makeToast } from '@/components/util/Toast.tsx';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||||
import { FULL_CHAPTER_FIELDS } from '@/lib/graphql/Fragments.ts';
|
import { ChapterListFieldsFragment, ChapterType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
|
import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts';
|
||||||
|
|
||||||
export type ChapterAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread';
|
export type ChapterAction = 'download' | 'delete' | 'bookmark' | 'unbookmark' | 'mark_as_read' | 'mark_as_unread';
|
||||||
|
|
||||||
@@ -77,24 +78,24 @@ export const actionToTranslationKey: {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ChapterIdInfo = Pick<TChapter, 'id'>;
|
export type ChapterIdInfo = Pick<ChapterType, 'id'>;
|
||||||
export type ChapterMangaInfo = Pick<TChapter, 'mangaId'>;
|
export type ChapterMangaInfo = Pick<ChapterType, 'mangaId'>;
|
||||||
export type ChapterDownloadInfo = ChapterIdInfo & Pick<TChapter, 'isDownloaded'>;
|
export type ChapterDownloadInfo = ChapterIdInfo & Pick<ChapterType, 'isDownloaded'>;
|
||||||
export type ChapterBookmarkInfo = ChapterIdInfo & Pick<TChapter, 'isBookmarked'>;
|
export type ChapterBookmarkInfo = ChapterIdInfo & Pick<ChapterType, 'isBookmarked'>;
|
||||||
export type ChapterReadInfo = ChapterIdInfo & Pick<TChapter, 'isRead'>;
|
export type ChapterReadInfo = ChapterIdInfo & Pick<ChapterType, 'isRead'>;
|
||||||
export type ChapterNumberInfo = ChapterIdInfo & Pick<TChapter, 'chapterNumber'>;
|
export type ChapterNumberInfo = ChapterIdInfo & Pick<ChapterType, 'chapterNumber'>;
|
||||||
export type ChapterScanlatorInfo = ChapterIdInfo & Pick<TChapter, 'scanlator'>;
|
export type ChapterScanlatorInfo = ChapterIdInfo & Pick<ChapterType, 'scanlator'>;
|
||||||
export type ChapterRealUrlInfo = Pick<TChapter, 'realUrl'>;
|
export type ChapterRealUrlInfo = Pick<ChapterType, 'realUrl'>;
|
||||||
|
|
||||||
export class Chapters {
|
export class Chapters {
|
||||||
static getIds(chapters: { id: number }[]): number[] {
|
static getIds(chapters: { id: number }[]): number[] {
|
||||||
return chapters.map((chapter) => chapter.id);
|
return chapters.map((chapter) => chapter.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getFromCache<T>(
|
static getFromCache<T = ChapterListFieldsFragment>(
|
||||||
id: number,
|
id: number,
|
||||||
fragment: DocumentNode = FULL_CHAPTER_FIELDS,
|
fragment: DocumentNode = CHAPTER_LIST_FIELDS,
|
||||||
fragmentName: string = 'FULL_CHAPTER_FIELDS',
|
fragmentName: string = 'CHAPTER_LIST_FIELDS',
|
||||||
): T | null {
|
): T | null {
|
||||||
return requestManager.graphQLClient.client.cache.readFragment<T>({
|
return requestManager.graphQLClient.client.cache.readFragment<T>({
|
||||||
id: requestManager.graphQLClient.client.cache.identify({
|
id: requestManager.graphQLClient.client.cache.identify({
|
||||||
@@ -107,7 +108,7 @@ export class Chapters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static isDownloading(id: number): boolean {
|
static isDownloading(id: number): boolean {
|
||||||
return !!requestManager.graphQLClient.client.cache.readFragment<TChapter>({
|
return !!requestManager.graphQLClient.client.cache.readFragment<ChapterType>({
|
||||||
id: requestManager.graphQLClient.client.cache.identify({
|
id: requestManager.graphQLClient.client.cache.identify({
|
||||||
__typename: 'DownloadType',
|
__typename: 'DownloadType',
|
||||||
chapter: {
|
chapter: {
|
||||||
|
|||||||
@@ -6,17 +6,18 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { TChapter } from '@/typings.ts';
|
|
||||||
import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { Chapters } from '@/lib/data/Chapters.ts';
|
import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterReadInfo, Chapters } from '@/lib/data/Chapters.ts';
|
||||||
|
|
||||||
export type ChapterWithMetaType = {
|
export type ChapterWithMetaType = {
|
||||||
chapter: TChapter;
|
chapter: ChapterDownloadInfo & ChapterReadInfo & ChapterBookmarkInfo;
|
||||||
downloadChapter: DownloadType | undefined;
|
downloadChapter: DownloadType | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ChaptersWithMeta {
|
export class ChaptersWithMeta {
|
||||||
static getChapters(chapters: ChapterWithMetaType[]): TChapter[] {
|
static getChapters<ChaptersWithMeta extends ChapterWithMetaType>(
|
||||||
|
chapters: ChaptersWithMeta[],
|
||||||
|
): ChaptersWithMeta['chapter'][] {
|
||||||
return chapters.map(({ chapter }) => chapter);
|
return chapters.map(({ chapter }) => chapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
84
src/lib/graphql/fragments/ChapterFragments.ts
Normal file
84
src/lib/graphql/fragments/ChapterFragments.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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';
|
||||||
|
|
||||||
|
const MANGA_BASE_FIELDS = gql`
|
||||||
|
fragment MANGA_BASE_FIELDS on MangaType {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
|
||||||
|
thumbnailUrl
|
||||||
|
thumbnailUrlLastFetched
|
||||||
|
|
||||||
|
inLibrary
|
||||||
|
initialized
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CHAPTER_BASE_FIELDS = gql`
|
||||||
|
fragment CHAPTER_BASE_FIELDS on ChapterType {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
|
||||||
|
mangaId
|
||||||
|
scanlator
|
||||||
|
realUrl
|
||||||
|
|
||||||
|
sourceOrder
|
||||||
|
chapterNumber
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CHAPTER_STATE_FIELDS = gql`
|
||||||
|
fragment CHAPTER_STATE_FIELDS on ChapterType {
|
||||||
|
id
|
||||||
|
isRead
|
||||||
|
isDownloaded
|
||||||
|
isBookmarked
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CHAPTER_READER_FIELDS = gql`
|
||||||
|
${CHAPTER_BASE_FIELDS}
|
||||||
|
${CHAPTER_STATE_FIELDS}
|
||||||
|
|
||||||
|
fragment CHAPTER_READER_FIELDS on ChapterType {
|
||||||
|
...CHAPTER_BASE_FIELDS
|
||||||
|
...CHAPTER_STATE_FIELDS
|
||||||
|
|
||||||
|
lastPageRead
|
||||||
|
pageCount
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CHAPTER_LIST_FIELDS = gql`
|
||||||
|
${CHAPTER_BASE_FIELDS}
|
||||||
|
${CHAPTER_STATE_FIELDS}
|
||||||
|
|
||||||
|
fragment CHAPTER_LIST_FIELDS on ChapterType {
|
||||||
|
...CHAPTER_BASE_FIELDS
|
||||||
|
...CHAPTER_STATE_FIELDS
|
||||||
|
|
||||||
|
fetchedAt
|
||||||
|
uploadDate
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CHAPTER_UPDATE_LIST_FIELDS = gql`
|
||||||
|
${CHAPTER_LIST_FIELDS}
|
||||||
|
${MANGA_BASE_FIELDS}
|
||||||
|
|
||||||
|
fragment CHAPTER_UPDATE_LIST_FIELDS on ChapterType {
|
||||||
|
...CHAPTER_LIST_FIELDS
|
||||||
|
|
||||||
|
manga {
|
||||||
|
...MANGA_BASE_FIELDS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
|
import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
|
||||||
import {
|
import {
|
||||||
GetChapterQueryVariables,
|
GetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
|
||||||
GetChaptersQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
|
|
||||||
GetMangaQueryVariables, GetSourceQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
|
GetMangaQueryVariables, GetSourceQueryVariables, 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";
|
||||||
@@ -575,8 +574,8 @@ export type QueryFieldPolicy = {
|
|||||||
aboutWebUI?: FieldPolicy<any> | FieldReadFunction<any>,
|
aboutWebUI?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
categories?: FieldPolicy<any> | FieldReadFunction<any>,
|
categories?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
category?: FieldPolicy<any> | FieldReadFunction<any>,
|
category?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
chapter?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>>,
|
chapter?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
chapters?: FieldPolicy<GetChaptersQuery['chapters']> | FieldReadFunction<GetChaptersQuery['chapters']>,
|
chapters?: FieldPolicy<GetChaptersMangaQuery['chapters']> | FieldReadFunction<GetChaptersMangaQuery['chapters']>,
|
||||||
checkForServerUpdates?: FieldPolicy<any> | FieldReadFunction<any>,
|
checkForServerUpdates?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
checkForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
checkForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
downloadStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>>,
|
downloadStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>>,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { BASE_TRACK_RECORD_FIELDS, FULL_CHAPTER_FIELDS } from '@/lib/graphql/Fragments';
|
import { BASE_TRACK_RECORD_FIELDS } from '@/lib/graphql/Fragments';
|
||||||
|
import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts';
|
||||||
|
|
||||||
export const DELETE_CHAPTER_METADATA = gql`
|
export const DELETE_CHAPTER_METADATA = gql`
|
||||||
mutation DELETE_CHAPTER_METADATA($input: DeleteChapterMetaInput!) {
|
mutation DELETE_CHAPTER_METADATA($input: DeleteChapterMetaInput!) {
|
||||||
@@ -51,12 +52,13 @@ export const GET_CHAPTER_PAGES_FETCH = gql`
|
|||||||
|
|
||||||
// makes the server fetch and return the chapters of the manga
|
// makes the server fetch and return the chapters of the manga
|
||||||
export const GET_MANGA_CHAPTERS_FETCH = gql`
|
export const GET_MANGA_CHAPTERS_FETCH = gql`
|
||||||
${FULL_CHAPTER_FIELDS}
|
${CHAPTER_LIST_FIELDS}
|
||||||
|
|
||||||
mutation GET_MANGA_CHAPTERS_FETCH($input: FetchChaptersInput!) {
|
mutation GET_MANGA_CHAPTERS_FETCH($input: FetchChaptersInput!) {
|
||||||
fetchChapters(input: $input) {
|
fetchChapters(input: $input) {
|
||||||
clientMutationId
|
clientMutationId
|
||||||
chapters {
|
chapters {
|
||||||
...FULL_CHAPTER_FIELDS
|
...CHAPTER_LIST_FIELDS
|
||||||
manga {
|
manga {
|
||||||
id
|
id
|
||||||
chapters {
|
chapters {
|
||||||
|
|||||||
@@ -7,23 +7,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { FULL_CHAPTER_FIELDS, PAGE_INFO } from '@/lib/graphql/Fragments';
|
import { PAGE_INFO } from '@/lib/graphql/Fragments';
|
||||||
|
import {
|
||||||
// returns the current chapter from the database
|
CHAPTER_LIST_FIELDS,
|
||||||
export const GET_CHAPTER = gql`
|
CHAPTER_READER_FIELDS,
|
||||||
${FULL_CHAPTER_FIELDS}
|
CHAPTER_STATE_FIELDS,
|
||||||
query GET_CHAPTER($id: Int!) {
|
CHAPTER_UPDATE_LIST_FIELDS,
|
||||||
chapter(id: $id) {
|
} from '@/lib/graphql/fragments/ChapterFragments.ts';
|
||||||
...FULL_CHAPTER_FIELDS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
// returns the current chapters from the database
|
// returns the current chapters from the database
|
||||||
export const GET_CHAPTERS = gql`
|
export const GET_CHAPTERS_READER = gql`
|
||||||
${FULL_CHAPTER_FIELDS}
|
${CHAPTER_READER_FIELDS}
|
||||||
${PAGE_INFO}
|
${PAGE_INFO}
|
||||||
query GET_CHAPTERS(
|
|
||||||
|
query GET_CHAPTERS_READER(
|
||||||
$after: Cursor
|
$after: Cursor
|
||||||
$before: Cursor
|
$before: Cursor
|
||||||
$condition: ChapterConditionInput
|
$condition: ChapterConditionInput
|
||||||
@@ -46,7 +43,83 @@ export const GET_CHAPTERS = gql`
|
|||||||
orderByType: $orderByType
|
orderByType: $orderByType
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
...FULL_CHAPTER_FIELDS
|
...CHAPTER_READER_FIELDS
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PAGE_INFO
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// returns the current chapters from the database
|
||||||
|
export const GET_CHAPTERS_MANGA = gql`
|
||||||
|
${CHAPTER_LIST_FIELDS}
|
||||||
|
${PAGE_INFO}
|
||||||
|
|
||||||
|
query GET_CHAPTERS_MANGA(
|
||||||
|
$after: Cursor
|
||||||
|
$before: Cursor
|
||||||
|
$condition: ChapterConditionInput
|
||||||
|
$filter: ChapterFilterInput
|
||||||
|
$first: Int
|
||||||
|
$last: Int
|
||||||
|
$offset: Int
|
||||||
|
$orderBy: ChapterOrderBy
|
||||||
|
$orderByType: SortOrder
|
||||||
|
) {
|
||||||
|
chapters(
|
||||||
|
after: $after
|
||||||
|
before: $before
|
||||||
|
condition: $condition
|
||||||
|
filter: $filter
|
||||||
|
first: $first
|
||||||
|
last: $last
|
||||||
|
offset: $offset
|
||||||
|
orderBy: $orderBy
|
||||||
|
orderByType: $orderByType
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...CHAPTER_LIST_FIELDS
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
...PAGE_INFO
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// returns the current chapters from the database
|
||||||
|
export const GET_CHAPTERS_UPDATES = gql`
|
||||||
|
${CHAPTER_UPDATE_LIST_FIELDS}
|
||||||
|
${PAGE_INFO}
|
||||||
|
|
||||||
|
query GET_CHAPTERS_UPDATES(
|
||||||
|
$after: Cursor
|
||||||
|
$before: Cursor
|
||||||
|
$condition: ChapterConditionInput
|
||||||
|
$filter: ChapterFilterInput
|
||||||
|
$first: Int
|
||||||
|
$last: Int
|
||||||
|
$offset: Int
|
||||||
|
$orderBy: ChapterOrderBy
|
||||||
|
$orderByType: SortOrder
|
||||||
|
) {
|
||||||
|
chapters(
|
||||||
|
after: $after
|
||||||
|
before: $before
|
||||||
|
condition: $condition
|
||||||
|
filter: $filter
|
||||||
|
first: $first
|
||||||
|
last: $last
|
||||||
|
offset: $offset
|
||||||
|
orderBy: $orderBy
|
||||||
|
orderByType: $orderByType
|
||||||
|
) {
|
||||||
|
nodes {
|
||||||
|
...CHAPTER_UPDATE_LIST_FIELDS
|
||||||
}
|
}
|
||||||
pageInfo {
|
pageInfo {
|
||||||
...PAGE_INFO
|
...PAGE_INFO
|
||||||
@@ -57,6 +130,8 @@ export const GET_CHAPTERS = gql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const GET_MANGAS_CHAPTER_IDS_WITH_STATE = gql`
|
export const GET_MANGAS_CHAPTER_IDS_WITH_STATE = gql`
|
||||||
|
${CHAPTER_STATE_FIELDS}
|
||||||
|
|
||||||
query GET_MANGAS_CHAPTER_IDS_WITH_STATE(
|
query GET_MANGAS_CHAPTER_IDS_WITH_STATE(
|
||||||
$mangaIds: [Int!]!
|
$mangaIds: [Int!]!
|
||||||
$isDownloaded: Boolean = null
|
$isDownloaded: Boolean = null
|
||||||
@@ -69,10 +144,7 @@ export const GET_MANGAS_CHAPTER_IDS_WITH_STATE = gql`
|
|||||||
orderBy: SOURCE_ORDER
|
orderBy: SOURCE_ORDER
|
||||||
) {
|
) {
|
||||||
nodes {
|
nodes {
|
||||||
id
|
...CHAPTER_STATE_FIELDS
|
||||||
isDownloaded
|
|
||||||
isRead
|
|
||||||
isBookmarked
|
|
||||||
mangaId
|
mangaId
|
||||||
scanlator
|
scanlator
|
||||||
chapterNumber
|
chapterNumber
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
Metadata,
|
Metadata,
|
||||||
MetadataHolder,
|
MetadataHolder,
|
||||||
MetadataKeyValuePair,
|
MetadataKeyValuePair,
|
||||||
TChapter,
|
|
||||||
TManga,
|
TManga,
|
||||||
TPartialSource,
|
TPartialSource,
|
||||||
} from '@/typings.ts';
|
} from '@/typings.ts';
|
||||||
@@ -22,6 +21,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts';
|
|||||||
import { MetaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MetaType } 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';
|
||||||
|
|
||||||
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
const APP_METADATA_KEY_PREFIX = 'webUI_';
|
||||||
|
|
||||||
@@ -373,7 +373,7 @@ export const requestUpdateMetadataValue = async (
|
|||||||
await requestManager.setCategoryMeta((metadataHolder as CategoryIdInfo).id, metadataKey, value).response;
|
await requestManager.setCategoryMeta((metadataHolder as CategoryIdInfo).id, metadataKey, value).response;
|
||||||
break;
|
break;
|
||||||
case 'chapter':
|
case 'chapter':
|
||||||
await requestManager.setChapterMeta((metadataHolder as TChapter).id, metadataKey, value).response;
|
await requestManager.setChapterMeta((metadataHolder as ChapterIdInfo).id, metadataKey, value).response;
|
||||||
break;
|
break;
|
||||||
case 'global':
|
case 'global':
|
||||||
await requestManager.setGlobalMetadata(metadataKey, value).response;
|
await requestManager.setGlobalMetadata(metadataKey, value).response;
|
||||||
@@ -405,7 +405,7 @@ export const requestUpdateMangaMetadata = async (
|
|||||||
): Promise<void[]> => requestUpdateMetadata(manga, 'manga', keysToValues);
|
): Promise<void[]> => requestUpdateMetadata(manga, 'manga', keysToValues);
|
||||||
|
|
||||||
export const requestUpdateChapterMetadata = async (
|
export const requestUpdateChapterMetadata = async (
|
||||||
chapter: TChapter,
|
chapter: ChapterIdInfo & GqlMetaHolder,
|
||||||
keysToValues: MetadataKeyValuePair[],
|
keysToValues: MetadataKeyValuePair[],
|
||||||
): Promise<void[]> => requestUpdateMetadata(chapter, 'chapter', keysToValues);
|
): Promise<void[]> => requestUpdateMetadata(chapter, 'chapter', keysToValues);
|
||||||
|
|
||||||
|
|||||||
@@ -69,8 +69,6 @@ import {
|
|||||||
GetCategoryMangasQueryVariables,
|
GetCategoryMangasQueryVariables,
|
||||||
GetChapterPagesFetchMutation,
|
GetChapterPagesFetchMutation,
|
||||||
GetChapterPagesFetchMutationVariables,
|
GetChapterPagesFetchMutationVariables,
|
||||||
GetChaptersQuery,
|
|
||||||
GetChaptersQueryVariables,
|
|
||||||
GetExtensionsFetchMutation,
|
GetExtensionsFetchMutation,
|
||||||
GetExtensionsFetchMutationVariables,
|
GetExtensionsFetchMutationVariables,
|
||||||
GetExtensionsQuery,
|
GetExtensionsQuery,
|
||||||
@@ -199,6 +197,10 @@ import {
|
|||||||
SetSourceMetadataMutationVariables,
|
SetSourceMetadataMutationVariables,
|
||||||
GetCategoriesSettingsQuery,
|
GetCategoriesSettingsQuery,
|
||||||
GetCategoriesSettingsQueryVariables,
|
GetCategoriesSettingsQueryVariables,
|
||||||
|
GetChaptersMangaQuery,
|
||||||
|
GetChaptersMangaQueryVariables,
|
||||||
|
GetChaptersUpdatesQuery,
|
||||||
|
GetChaptersUpdatesQueryVariables,
|
||||||
} 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';
|
||||||
@@ -253,7 +255,11 @@ import {
|
|||||||
START_DOWNLOADER,
|
START_DOWNLOADER,
|
||||||
STOP_DOWNLOADER,
|
STOP_DOWNLOADER,
|
||||||
} from '@/lib/graphql/mutations/DownloaderMutation.ts';
|
} from '@/lib/graphql/mutations/DownloaderMutation.ts';
|
||||||
import { GET_CHAPTERS, GET_MANGAS_CHAPTER_IDS_WITH_STATE } from '@/lib/graphql/queries/ChapterQuery.ts';
|
import {
|
||||||
|
GET_CHAPTERS_MANGA,
|
||||||
|
GET_CHAPTERS_UPDATES,
|
||||||
|
GET_MANGAS_CHAPTER_IDS_WITH_STATE,
|
||||||
|
} from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||||
import {
|
import {
|
||||||
GET_CHAPTER_PAGES_FETCH,
|
GET_CHAPTER_PAGES_FETCH,
|
||||||
GET_MANGA_CHAPTERS_FETCH,
|
GET_MANGA_CHAPTERS_FETCH,
|
||||||
@@ -1835,30 +1841,34 @@ export class RequestManager {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public useGetChapters(
|
public useGetChapters<Data, Variables extends OperationVariables>(
|
||||||
variables: GetChaptersQueryVariables,
|
document: DocumentNode | TypedDocumentNode<Data, Variables>,
|
||||||
options?: QueryHookOptions<GetChaptersQuery, GetChaptersQueryVariables>,
|
variables: Variables,
|
||||||
): AbortableApolloUseQueryResponse<GetChaptersQuery, GetChaptersQueryVariables> {
|
options?: QueryHookOptions<Data, Variables>,
|
||||||
return this.doRequest(GQLMethod.USE_QUERY, GET_CHAPTERS, variables, options);
|
): AbortableApolloUseQueryResponse<Data, Variables> {
|
||||||
|
return this.doRequest(GQLMethod.USE_QUERY, document, variables, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChapters(
|
public getChapters<Data, Variables extends OperationVariables>(
|
||||||
variables: GetChaptersQueryVariables,
|
document: DocumentNode | TypedDocumentNode<Data, Variables>,
|
||||||
options?: QueryOptions<GetChaptersQueryVariables, GetChaptersQuery>,
|
variables: Variables,
|
||||||
): AbortabaleApolloQueryResponse<GetChaptersQuery> {
|
options?: QueryOptions<Variables, Data>,
|
||||||
return this.doRequest(GQLMethod.QUERY, GET_CHAPTERS, variables, options);
|
): AbortabaleApolloQueryResponse<Data> {
|
||||||
|
return this.doRequest(GQLMethod.QUERY, document, variables, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public useGetMangaChapters(
|
public useGetMangaChapters<Data, Variables extends OperationVariables>(
|
||||||
|
document: DocumentNode | TypedDocumentNode<Data, Variables>,
|
||||||
mangaId: number | string,
|
mangaId: number | string,
|
||||||
options?: QueryHookOptions<GetChaptersQuery, GetChaptersQueryVariables>,
|
options?: QueryHookOptions<Data, Variables>,
|
||||||
): AbortableApolloUseQueryResponse<GetChaptersQuery, GetChaptersQueryVariables> {
|
): AbortableApolloUseQueryResponse<Data, Variables> {
|
||||||
return this.useGetChapters(
|
return this.useGetChapters(
|
||||||
|
document,
|
||||||
{
|
{
|
||||||
condition: { mangaId: Number(mangaId) },
|
condition: { mangaId: Number(mangaId) },
|
||||||
orderBy: ChapterOrderBy.SourceOrder,
|
orderBy: ChapterOrderBy.SourceOrder,
|
||||||
orderByType: SortOrder.Desc,
|
orderByType: SortOrder.Desc,
|
||||||
},
|
} as unknown as Variables,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1887,24 +1897,25 @@ export class RequestManager {
|
|||||||
GQLMethod.MUTATION,
|
GQLMethod.MUTATION,
|
||||||
GET_MANGA_CHAPTERS_FETCH,
|
GET_MANGA_CHAPTERS_FETCH,
|
||||||
{ input: { mangaId: Number(mangaId) } },
|
{ input: { mangaId: Number(mangaId) } },
|
||||||
{ refetchQueries: [GET_CHAPTERS], ...options },
|
{ refetchQueries: [GET_CHAPTERS_MANGA], ...options },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public useGetMangaChapter(
|
public useGetMangaChapter(
|
||||||
mangaId: number | string,
|
mangaId: number | string,
|
||||||
chapterIndex: number | string,
|
chapterIndex: number | string,
|
||||||
options?: QueryHookOptions<GetChaptersQuery, GetChaptersQueryVariables>,
|
options?: QueryHookOptions<GetChaptersMangaQuery, GetChaptersMangaQueryVariables>,
|
||||||
): AbortableApolloUseQueryResponse<
|
): AbortableApolloUseQueryResponse<
|
||||||
Omit<GetChaptersQuery, 'chapters'> & { chapter: GetChaptersQuery['chapters']['nodes'][number] },
|
Omit<GetChaptersMangaQuery, 'chapters'> & { chapter: GetChaptersMangaQuery['chapters']['nodes'][number] },
|
||||||
GetChaptersQueryVariables
|
GetChaptersMangaQueryVariables
|
||||||
> {
|
> {
|
||||||
type Response = AbortableApolloUseQueryResponse<
|
type Response = AbortableApolloUseQueryResponse<
|
||||||
Omit<GetChaptersQuery, 'chapters'> & { chapter: GetChaptersQuery['chapters']['nodes'][number] },
|
Omit<GetChaptersMangaQuery, 'chapters'> & { chapter: GetChaptersMangaQuery['chapters']['nodes'][number] },
|
||||||
GetChaptersQueryVariables
|
GetChaptersMangaQueryVariables
|
||||||
>;
|
>;
|
||||||
|
|
||||||
const chapterResponse = this.useGetChapters(
|
const chapterResponse = this.useGetChapters<GetChaptersMangaQuery, GetChaptersMangaQueryVariables>(
|
||||||
|
GET_CHAPTERS_MANGA,
|
||||||
{ condition: { mangaId: Number(mangaId), sourceOrder: Number(chapterIndex) } },
|
{ condition: { mangaId: Number(mangaId), sourceOrder: Number(chapterIndex) } },
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
@@ -1921,43 +1932,6 @@ export class RequestManager {
|
|||||||
} as unknown as Response;
|
} as unknown as Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getChapter(
|
|
||||||
mangaId: number | string,
|
|
||||||
chapterIndex: number | string,
|
|
||||||
options?: QueryOptions<GetChaptersQueryVariables, GetChaptersQuery>,
|
|
||||||
): AbortabaleApolloQueryResponse<
|
|
||||||
Omit<GetChaptersQuery, 'chapters'> & { chapter: GetChaptersQuery['chapters']['nodes'][number] }
|
|
||||||
> {
|
|
||||||
type ResponseData = Omit<GetChaptersQuery, 'chapters'> & {
|
|
||||||
chapter: GetChaptersQuery['chapters']['nodes'][number];
|
|
||||||
};
|
|
||||||
|
|
||||||
const chapterRequest = this.doRequest<GetChaptersQuery, GetChaptersQueryVariables>(
|
|
||||||
GQLMethod.QUERY,
|
|
||||||
GET_CHAPTERS,
|
|
||||||
{
|
|
||||||
condition: { mangaId: Number(mangaId), sourceOrder: Number(chapterIndex) },
|
|
||||||
},
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...chapterRequest,
|
|
||||||
response: chapterRequest.response.then((chapterResponse) => {
|
|
||||||
if (!chapterResponse.data) {
|
|
||||||
return chapterResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
...chapterResponse,
|
|
||||||
data: {
|
|
||||||
chapter: chapterResponse.data.chapters.nodes[0],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}) as Promise<ApolloQueryResult<ResponseData>>,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public useGetChapterPagesFetch(
|
public useGetChapterPagesFetch(
|
||||||
chapterId: string | number,
|
chapterId: string | number,
|
||||||
options?: MutationHookOptions<GetChapterPagesFetchMutation, GetChapterPagesFetchMutationVariables>,
|
options?: MutationHookOptions<GetChapterPagesFetchMutation, GetChapterPagesFetchMutationVariables>,
|
||||||
@@ -2425,15 +2399,16 @@ export class RequestManager {
|
|||||||
|
|
||||||
public useGetRecentlyUpdatedChapters(
|
public useGetRecentlyUpdatedChapters(
|
||||||
initialPages: number = 1,
|
initialPages: number = 1,
|
||||||
options?: QueryHookOptions<GetChaptersQuery, GetChaptersQueryVariables>,
|
options?: QueryHookOptions<GetChaptersUpdatesQuery, GetChaptersUpdatesQueryVariables>,
|
||||||
): AbortableApolloUseQueryResponse<GetChaptersQuery, GetChaptersQueryVariables> {
|
): AbortableApolloUseQueryResponse<GetChaptersUpdatesQuery, GetChaptersUpdatesQueryVariables> {
|
||||||
const PAGE_SIZE = 50;
|
const PAGE_SIZE = 50;
|
||||||
const CACHE_KEY = 'useGetRecentlyUpdatedChapters';
|
const CACHE_KEY = 'useGetRecentlyUpdatedChapters';
|
||||||
|
|
||||||
const offset = this.cache.getResponseFor<number>(CACHE_KEY, undefined) ?? 0;
|
const offset = this.cache.getResponseFor<number>(CACHE_KEY, undefined) ?? 0;
|
||||||
const [lastOffset] = useState(offset);
|
const [lastOffset] = useState(offset);
|
||||||
|
|
||||||
const result = this.useGetChapters(
|
const result = this.useGetChapters<GetChaptersUpdatesQuery, GetChaptersUpdatesQueryVariables>(
|
||||||
|
GET_CHAPTERS_UPDATES,
|
||||||
{
|
{
|
||||||
filter: { inLibrary: { equalTo: true } },
|
filter: { inLibrary: { equalTo: true } },
|
||||||
orderBy: ChapterOrderBy.FetchedAt,
|
orderBy: ChapterOrderBy.FetchedAt,
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ import { makeToast } from '@/components/util/Toast';
|
|||||||
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator';
|
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
||||||
import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { TChapter } from '@/typings.ts';
|
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx';
|
||||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||||
|
import { ChapterIdInfo } from '@/lib/data/Chapters.ts';
|
||||||
|
|
||||||
const HeightPreservingItem = ({ children, ...props }: BoxProps) => (
|
const HeightPreservingItem = ({ children, ...props }: BoxProps) => (
|
||||||
// the height is necessary to prevent the item container from collapsing, which confuses Virtuoso measurements
|
// the height is necessary to prevent the item container from collapsing, which confuses Virtuoso measurements
|
||||||
@@ -192,7 +192,7 @@ export const DownloadQueue: React.FC = () => {
|
|||||||
categoryReorder(queue, result.source.index, result.destination.index);
|
categoryReorder(queue, result.source.index, result.destination.index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = async (chapter: TChapter) => {
|
const handleDelete = async (chapter: ChapterIdInfo) => {
|
||||||
const isRunning = status === 'STARTED';
|
const isRunning = status === 'STARTED';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'r
|
|||||||
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
import { useLocation, useNavigate, useParams } from 'react-router-dom';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings, ReaderType, TChapter, TManga } from '@/typings';
|
import { AllowedMetadataValueTypes, ChapterOffset, IReaderSettings, ReaderType, TManga } from '@/typings';
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import {
|
import {
|
||||||
checkAndHandleMissingStoredReaderSettings,
|
checkAndHandleMissingStoredReaderSettings,
|
||||||
@@ -28,11 +28,18 @@ import { ReaderNavBar } from '@/components/navbar/ReaderNavBar';
|
|||||||
import { makeToast } from '@/components/util/Toast';
|
import { makeToast } from '@/components/util/Toast';
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { useDebounce } from '@/util/useDebounce.ts';
|
import { useDebounce } from '@/util/useDebounce.ts';
|
||||||
import { UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
|
import {
|
||||||
|
GetChaptersReaderQuery,
|
||||||
|
GetChaptersReaderQueryVariables,
|
||||||
|
UpdateChapterPatchInput,
|
||||||
|
} from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
import { useMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||||
import { Chapters } from '@/lib/data/Chapters.ts';
|
import { Chapters } from '@/lib/data/Chapters.ts';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
||||||
|
import { GET_CHAPTERS_READER } from '@/lib/graphql/queries/ChapterQuery.ts';
|
||||||
|
|
||||||
|
type TChapter = GetChaptersReaderQuery['chapters']['nodes'][number];
|
||||||
|
|
||||||
const getReaderComponent = (readerType: ReaderType) => {
|
const getReaderComponent = (readerType: ReaderType) => {
|
||||||
switch (readerType) {
|
switch (readerType) {
|
||||||
@@ -99,16 +106,25 @@ export function Reader() {
|
|||||||
} = requestManager.useGetManga(mangaId);
|
} = requestManager.useGetManga(mangaId);
|
||||||
const loadedChapter = useRef<TChapter | null>(null);
|
const loadedChapter = useRef<TChapter | null>(null);
|
||||||
const isChapterLoaded =
|
const isChapterLoaded =
|
||||||
Number(mangaId) === loadedChapter.current?.manga.id &&
|
Number(mangaId) === loadedChapter.current?.mangaId &&
|
||||||
Number(chapterIndex) === loadedChapter.current?.sourceOrder &&
|
Number(chapterIndex) === loadedChapter.current?.sourceOrder &&
|
||||||
loadedChapter.current?.pageCount !== -1;
|
loadedChapter.current?.pageCount !== -1;
|
||||||
const manga = data?.manga ?? fallbackManga;
|
const manga = data?.manga ?? fallbackManga;
|
||||||
const {
|
const {
|
||||||
data: chapterData,
|
data: chaptersData,
|
||||||
loading: isChapterLoading,
|
loading: isChapterLoading,
|
||||||
error: chapterError,
|
error: chapterError,
|
||||||
refetch: fetchChapter,
|
refetch: fetchChapter,
|
||||||
} = requestManager.useGetMangaChapter(mangaId, chapterIndex, { notifyOnNetworkStatusChange: true });
|
} = requestManager.useGetChapters<GetChaptersReaderQuery, GetChaptersReaderQueryVariables>(
|
||||||
|
GET_CHAPTERS_READER,
|
||||||
|
{
|
||||||
|
condition: { mangaId: Number(mangaId), sourceOrder: Number(chapterIndex) },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
notifyOnNetworkStatusChange: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const chapterData = chaptersData?.chapters.nodes[0];
|
||||||
const arePagesUpdatedRef = useRef(false);
|
const arePagesUpdatedRef = useRef(false);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -121,15 +137,14 @@ export function Reader() {
|
|||||||
|
|
||||||
const isSameAsLoadedChapter = isAChapterLoaded && isChapterLoaded;
|
const isSameAsLoadedChapter = isAChapterLoaded && isChapterLoaded;
|
||||||
if (isSameAsLoadedChapter) {
|
if (isSameAsLoadedChapter) {
|
||||||
const didPageCountChange =
|
const didPageCountChange = chapterData && loadedChapter.current?.pageCount !== chapterData.pageCount;
|
||||||
chapterData?.chapter && loadedChapter.current?.pageCount !== chapterData.chapter.pageCount;
|
return didPageCountChange ? chapterData! : loadedChapter.current;
|
||||||
return didPageCountChange ? chapterData!.chapter : loadedChapter.current;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arePagesUpdatedRef.current = false;
|
arePagesUpdatedRef.current = false;
|
||||||
|
|
||||||
if (chapterData?.chapter) {
|
if (chapterData) {
|
||||||
return chapterData.chapter;
|
return chapterData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -142,7 +157,7 @@ export function Reader() {
|
|||||||
if (initialChapterRef.current === fallbackChapter) {
|
if (initialChapterRef.current === fallbackChapter) {
|
||||||
initialChapterRef.current = chapter;
|
initialChapterRef.current = chapter;
|
||||||
}
|
}
|
||||||
if (chapter.manga.id !== initialChapterRef.current?.manga.id) {
|
if (chapter.mangaId !== initialChapterRef.current?.mangaId) {
|
||||||
initialChapterRef.current = fallbackChapter;
|
initialChapterRef.current = fallbackChapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +194,11 @@ export function Reader() {
|
|||||||
loading: areChaptersLoading,
|
loading: areChaptersLoading,
|
||||||
error: chaptersError,
|
error: chaptersError,
|
||||||
refetch: refetchChapters,
|
refetch: refetchChapters,
|
||||||
} = requestManager.useGetMangaChapters(mangaId, { nextFetchPolicy: 'standby' });
|
} = requestManager.useGetMangaChapters<GetChaptersReaderQuery, GetChaptersReaderQueryVariables>(
|
||||||
|
GET_CHAPTERS_READER,
|
||||||
|
mangaId,
|
||||||
|
{ nextFetchPolicy: 'standby' },
|
||||||
|
);
|
||||||
const mangaChapters = mangaChaptersData?.chapters.nodes;
|
const mangaChapters = mangaChaptersData?.chapters.nodes;
|
||||||
|
|
||||||
const isLoading =
|
const isLoading =
|
||||||
@@ -276,7 +295,7 @@ export function Reader() {
|
|||||||
|
|
||||||
const inDownloadRange = (patch.lastPageRead ?? 0) / chapter.pageCount > 0.25;
|
const inDownloadRange = (patch.lastPageRead ?? 0) / chapter.pageCount > 0.25;
|
||||||
const shouldCheckDownloadAhead =
|
const shouldCheckDownloadAhead =
|
||||||
isDownloadAheadEnabled && chapter.manga.inLibrary && !!currentChapter?.isDownloaded && inDownloadRange;
|
isDownloadAheadEnabled && manga.inLibrary && !!currentChapter?.isDownloaded && inDownloadRange;
|
||||||
|
|
||||||
if (shouldCheckDownloadAhead) {
|
if (shouldCheckDownloadAhead) {
|
||||||
const nextChapterUpToDate = nextChapter ? Chapters.getFromCache<TChapter>(nextChapter.id) : null;
|
const nextChapterUpToDate = nextChapter ? Chapters.getFromCache<TChapter>(nextChapter.id) : null;
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts';
|
|||||||
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder';
|
import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder';
|
||||||
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx';
|
||||||
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator';
|
import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator';
|
||||||
import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { TChapter } from '@/typings.ts';
|
|
||||||
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
import { NavBarContext } from '@/components/context/NavbarContext.tsx';
|
||||||
import { UpdateChecker } from '@/components/library/UpdateChecker.tsx';
|
import { UpdateChecker } from '@/components/library/UpdateChecker.tsx';
|
||||||
import { StyledGroupedVirtuoso } from '@/components/virtuoso/StyledGroupedVirtuoso.tsx';
|
import { StyledGroupedVirtuoso } from '@/components/virtuoso/StyledGroupedVirtuoso.tsx';
|
||||||
@@ -34,8 +33,9 @@ import { SpinnerImage } from '@/components/util/SpinnerImage.tsx';
|
|||||||
import { dateTimeFormatter, epochToDate, getDateString } from '@/util/date.ts';
|
import { dateTimeFormatter, epochToDate, getDateString } from '@/util/date.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts';
|
||||||
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
|
import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx';
|
||||||
|
import { ChapterIdInfo, ChapterMangaInfo } from '@/lib/data/Chapters.ts';
|
||||||
|
|
||||||
const groupByDate = (updates: TChapter[]): [date: string, items: number][] => {
|
const groupByDate = (updates: Pick<ChapterType, 'fetchedAt'>[]): [date: string, items: number][] => {
|
||||||
if (!updates.length) {
|
if (!updates.length) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -96,15 +96,12 @@ export const Updates: React.FC = () => {
|
|||||||
};
|
};
|
||||||
}, [t, lastUpdateTimestamp]);
|
}, [t, lastUpdateTimestamp]);
|
||||||
|
|
||||||
const downloadForChapter = (chapter: TChapter) => {
|
const downloadForChapter = (chapter: Pick<ChapterType, 'sourceOrder'> & ChapterMangaInfo) => {
|
||||||
const {
|
const { sourceOrder, mangaId } = chapter;
|
||||||
sourceOrder,
|
|
||||||
manga: { id: mangaId },
|
|
||||||
} = chapter;
|
|
||||||
return queue.find((q) => sourceOrder === q.chapter.sourceOrder && mangaId === q.chapter.manga.id);
|
return queue.find((q) => sourceOrder === q.chapter.sourceOrder && mangaId === q.chapter.manga.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const downloadChapter = (chapter: TChapter) => {
|
const downloadChapter = (chapter: ChapterIdInfo) => {
|
||||||
requestManager.addChapterToDownloadQueue(chapter.id);
|
requestManager.addChapterToDownloadQueue(chapter.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { SvgIconTypeMap } from '@mui/material/SvgIcon';
|
|||||||
import { ParseKeys } from 'i18next';
|
import { ParseKeys } from 'i18next';
|
||||||
import { Location } from 'react-router-dom';
|
import { Location } from 'react-router-dom';
|
||||||
import {
|
import {
|
||||||
GetChapterQuery,
|
GetChaptersReaderQuery,
|
||||||
GetExtensionQuery,
|
GetExtensionQuery,
|
||||||
GetMangaQuery,
|
GetMangaQuery,
|
||||||
GetServerSettingsQuery,
|
GetServerSettingsQuery,
|
||||||
@@ -181,8 +181,6 @@ export interface IMangaChapter {
|
|||||||
chapter: IChapter;
|
chapter: IChapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TChapter = GetChapterQuery['chapter'];
|
|
||||||
|
|
||||||
export enum IncludeInGlobalUpdate {
|
export enum IncludeInGlobalUpdate {
|
||||||
EXCLUDE = 0,
|
EXCLUDE = 0,
|
||||||
INCLUDE = 1,
|
INCLUDE = 1,
|
||||||
@@ -297,7 +295,7 @@ export interface IReaderProps {
|
|||||||
initialPage: number;
|
initialPage: number;
|
||||||
settings: IReaderSettings;
|
settings: IReaderSettings;
|
||||||
manga: TManga;
|
manga: TManga;
|
||||||
chapter: TChapter;
|
chapter: GetChaptersReaderQuery['chapters']['nodes'][number];
|
||||||
nextChapter: () => void;
|
nextChapter: () => void;
|
||||||
prevChapter: () => void;
|
prevChapter: () => void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,7 @@ const addImports = format(
|
|||||||
`import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';`,
|
`import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';`,
|
||||||
`import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
|
`import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
|
||||||
import {
|
import {
|
||||||
\tGetChapterQueryVariables,
|
\tGetChaptersMangaQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
|
||||||
\tGetChaptersQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
|
|
||||||
\tGetMangaQueryVariables, GetSourceQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
|
\tGetMangaQueryVariables, GetSourceQueryVariables, 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";`,
|
||||||
@@ -85,8 +84,8 @@ const fixTypingOfQueryTypePolicies = format(
|
|||||||
\taboutWebUI?: FieldPolicy<any> | FieldReadFunction<any>,
|
\taboutWebUI?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tcategories?: FieldPolicy<any> | FieldReadFunction<any>,
|
\tcategories?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tcategory?: FieldPolicy<any> | FieldReadFunction<any>,
|
\tcategory?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tchapter?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>>,
|
\tchapter?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tchapters?: FieldPolicy<GetChaptersQuery['chapters']> | FieldReadFunction<GetChaptersQuery['chapters']>,
|
\tchapters?: FieldPolicy<GetChaptersMangaQuery['chapters']> | FieldReadFunction<GetChaptersMangaQuery['chapters']>,
|
||||||
\tcheckForServerUpdates?: FieldPolicy<any> | FieldReadFunction<any>,
|
\tcheckForServerUpdates?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tcheckForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
\tcheckForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
|
||||||
\tdownloadStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>>,
|
\tdownloadStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>>,
|
||||||
|
|||||||
Reference in New Issue
Block a user