diff --git a/src/components/chapter/ChapterCard.tsx b/src/components/chapter/ChapterCard.tsx index 5e7c709f..18584d94 100644 --- a/src/components/chapter/ChapterCard.tsx +++ b/src/components/chapter/ChapterCard.tsx @@ -24,13 +24,14 @@ import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state'; import { useLongPress } from 'use-long-press'; import { getDateString } from '@/util/date.ts'; import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator.tsx'; -import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts'; +import { ChapterType } from '@/lib/graphql/generated/graphql.ts'; import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx'; import { Menu } from '@/components/menu/Menu.tsx'; import { TypographyMaxLines } from '@/components/atoms/TypographyMaxLines.tsx'; import { ChapterBookmarkInfo, ChapterDownloadInfo, + ChapterDownloadStatus, ChapterIdInfo, ChapterMangaInfo, ChapterNumberInfo, @@ -50,7 +51,7 @@ type TChapter = ChapterIdInfo & interface IProps { chapter: TChapter; allChapters: TChapter[]; - downloadChapter: DownloadType | undefined; + downloadChapter: ChapterDownloadStatus | undefined; showChapterNumber: boolean; onSelect: (selected: boolean, isShiftKey?: boolean) => void; selected: boolean | null; diff --git a/src/components/chapter/ChapterList.tsx b/src/components/chapter/ChapterList.tsx index 7c394a5b..bfb32298 100644 --- a/src/components/chapter/ChapterList.tsx +++ b/src/components/chapter/ChapterList.tsx @@ -11,7 +11,7 @@ import Stack from '@mui/material/Stack'; import Tooltip from '@mui/material/Tooltip'; import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; -import React, { useMemo } from 'react'; +import { ComponentProps, useMemo } from 'react'; import { Virtuoso } from 'react-virtuoso'; import { useTranslation } from 'react-i18next'; import IconButton from '@mui/material/IconButton'; @@ -28,7 +28,6 @@ import { ChaptersToolbarMenu } from '@/components/chapter/ChaptersToolbarMenu.ts import { SelectionFAB } from '@/components/collection/SelectionFAB.tsx'; import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab.tsx'; import { - DownloadType, GetChaptersMangaQuery, GetChaptersMangaQueryVariables, MangaScreenFieldsFragment, @@ -36,7 +35,7 @@ import { import { useSelectableCollection } from '@/components/collection/useSelectableCollection.ts'; import { SelectableCollectionSelectAll } from '@/components/collection/SelectableCollectionSelectAll.tsx'; import { Chapters } from '@/lib/data/Chapters.ts'; -import { ChaptersWithMeta } from '@/lib/data/ChaptersWithMeta.ts'; +import { ChaptersWithMeta, ChapterWithMetaType } from '@/lib/data/ChaptersWithMeta.ts'; import { ChapterActionMenuItems } from '@/components/chapter/ChapterActionMenuItems.tsx'; import { ChaptersDownloadActionMenuItems } from '@/components/chapter/ChaptersDownloadActionMenuItems.tsx'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; @@ -65,25 +64,24 @@ const StyledVirtuoso = styled(Virtuoso)(({ theme }) => ({ }, })); -export interface IChapterWithMeta { - chapter: React.ComponentProps['chapter']; - downloadChapter: DownloadType | undefined; +export interface IChapterWithMeta extends ChapterWithMetaType['chapter']> { selected: boolean | null; } -interface IProps { +export const ChapterList = ({ + manga, + isRefreshing, +}: { manga: Pick< MangaScreenFieldsFragment, 'id' | 'firstUnreadChapter' | 'chapters' | 'latestReadChapter' | 'unreadCount' | 'downloadCount' >; isRefreshing: boolean; -} - -export const ChapterList: React.FC = ({ manga, isRefreshing }) => { +}) => { const { t } = useTranslation(); const { data: downloaderData } = requestManager.useGetDownloadStatus(); - const queue = (downloaderData?.downloadStatus.queue as DownloadType[]) ?? []; + const queue = downloaderData?.downloadStatus.queue ?? []; const [options, dispatch] = useChapterOptions(manga.id); const { @@ -117,9 +115,7 @@ export const ChapterList: React.FC = ({ manga, isRefreshing }) => { const chaptersWithMeta: IChapterWithMeta[] = useMemo( () => visibleChapters.map((chapter) => { - const downloadChapter = queue?.find( - (cd) => cd.chapter.sourceOrder === chapter.sourceOrder && cd.chapter.manga.id === chapter.mangaId, - ); + const downloadChapter = queue?.find((cd) => cd.chapter.id === chapter.id); const selected = !areNoItemsSelected ? selectedItemIds.includes(chapter.id) : null; return { chapter, diff --git a/src/components/molecules/DownloadStateIndicator.tsx b/src/components/molecules/DownloadStateIndicator.tsx index 70948ca8..3c782c99 100644 --- a/src/components/molecules/DownloadStateIndicator.tsx +++ b/src/components/molecules/DownloadStateIndicator.tsx @@ -9,14 +9,10 @@ import CircularProgress from '@mui/material/CircularProgress'; import Box from '@mui/material/Box'; import Typography from '@mui/material/Typography'; -import React from 'react'; import { useTranslation } from 'react-i18next'; import { TranslationKey } from '@/typings'; -import { DownloadState, DownloadType } from '@/lib/graphql/generated/graphql.ts'; - -interface DownloadStateIndicatorProps { - download: DownloadType; -} +import { DownloadState } from '@/lib/graphql/generated/graphql.ts'; +import { ChapterDownloadStatus } from '@/lib/data/Chapters.ts'; const DOWNLOAD_STATE_TO_TRANSLATION_KEY_MAP: { [state in DownloadState]: TranslationKey } = { DOWNLOADING: 'download.state.label.downloading', @@ -25,7 +21,7 @@ const DOWNLOAD_STATE_TO_TRANSLATION_KEY_MAP: { [state in DownloadState]: Transla QUEUED: 'download.state.label.queued', } as const; -export const DownloadStateIndicator: React.FC = ({ download }) => { +export const DownloadStateIndicator = ({ download }: { download: ChapterDownloadStatus }) => { const { t } = useTranslation(); return ( diff --git a/src/lib/data/Chapters.ts b/src/lib/data/Chapters.ts index 91adcee3..ece1fab0 100644 --- a/src/lib/data/Chapters.ts +++ b/src/lib/data/Chapters.ts @@ -13,7 +13,11 @@ import { ChapterOffset, TranslationKey } from '@/typings.ts'; import { makeToast } from '@/components/util/Toast.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; import { getMetadataServerSettings } from '@/lib/metadata/metadataServerSettings.ts'; -import { ChapterListFieldsFragment, ChapterType } from '@/lib/graphql/generated/graphql.ts'; +import { + ChapterListFieldsFragment, + ChapterType, + DownloadStatusFieldsFragment, +} from '@/lib/graphql/generated/graphql.ts'; import { CHAPTER_LIST_FIELDS } from '@/lib/graphql/fragments/ChapterFragments.ts'; import { MangaIdInfo } from '@/lib/data/Mangas.ts'; @@ -79,6 +83,8 @@ export const actionToTranslationKey: { }, }; +export type ChapterDownloadStatus = DownloadStatusFieldsFragment['queue'][number]; + export type ChapterIdInfo = Pick; export type ChapterMangaInfo = Pick; export type ChapterDownloadInfo = ChapterIdInfo & Pick; diff --git a/src/lib/data/ChaptersWithMeta.ts b/src/lib/data/ChaptersWithMeta.ts index 0a92fadf..e74381a8 100644 --- a/src/lib/data/ChaptersWithMeta.ts +++ b/src/lib/data/ChaptersWithMeta.ts @@ -6,12 +6,21 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { DownloadType } from '@/lib/graphql/generated/graphql.ts'; -import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterReadInfo, Chapters } from '@/lib/data/Chapters.ts'; +import { + ChapterBookmarkInfo, + ChapterDownloadInfo, + ChapterDownloadStatus, + ChapterReadInfo, + Chapters, +} from '@/lib/data/Chapters.ts'; -export type ChapterWithMetaType = { - chapter: ChapterDownloadInfo & ChapterReadInfo & ChapterBookmarkInfo; - downloadChapter: DownloadType | undefined; +export type ChapterWithMetaType< + Chapter extends ChapterDownloadInfo & ChapterReadInfo & ChapterBookmarkInfo = ChapterDownloadInfo & + ChapterReadInfo & + ChapterBookmarkInfo, +> = { + chapter: Chapter; + downloadChapter: ChapterDownloadStatus | undefined; }; export class ChaptersWithMeta { diff --git a/src/screens/DownloadQueue.tsx b/src/screens/DownloadQueue.tsx index 2b1c9efd..3d95db48 100644 --- a/src/screens/DownloadQueue.tsx +++ b/src/screens/DownloadQueue.tsx @@ -28,11 +28,10 @@ import { StrictModeDroppable } from '@/lib/StrictModeDroppable'; import { makeToast } from '@/components/util/Toast'; import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; -import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts'; import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder.tsx'; import { defaultPromiseErrorHandler } from '@/util/defaultPromiseErrorHandler.ts'; -import { ChapterIdInfo } from '@/lib/data/Chapters.ts'; +import { ChapterDownloadStatus, ChapterIdInfo } from '@/lib/data/Chapters.ts'; const HeightPreservingItem = ({ children, ...props }: BoxProps) => ( // the height is necessary to prevent the item container from collapsing, which confuses Virtuoso measurements @@ -48,9 +47,9 @@ const DownloadChapterItem = ({ handleDelete, }: { provided: DraggableProvided; - item: DownloadType; + item: ChapterDownloadStatus; isDragging: boolean; - handleDelete: (chapter: ChapterType) => void; + handleDelete: (chapter: ChapterIdInfo) => void; }) => { const { t } = useTranslation(); @@ -63,7 +62,7 @@ const DownloadChapterItem = ({ > - {item.chapter.manga.title} + {item.manga.title} {item.chapter.name} @@ -111,7 +110,7 @@ export const DownloadQueue: React.FC = () => { } = requestManager.useGetDownloadStatus({ notifyOnNetworkStatusChange: true }); const downloaderData = downloadStatusData?.downloadStatus; - const queue = (downloaderData?.queue as DownloadType[]) ?? []; + const queue = downloaderData?.queue ?? []; const status = downloaderData?.state ?? 'STARTED'; const isQueueEmpty = !queue.length; @@ -174,7 +173,7 @@ export const DownloadQueue: React.FC = () => { return () => window.removeEventListener('error', ignoreError); }, []); - const categoryReorder = (list: DownloadType[], from: number, to: number) => { + const categoryReorder = (list: ChapterDownloadStatus[], from: number, to: number) => { if (from === to) { return; } @@ -262,8 +261,8 @@ export const DownloadQueue: React.FC = () => { }} itemContent={(index, item) => ( {(draggableProvided) => ( diff --git a/src/screens/Updates.tsx b/src/screens/Updates.tsx index 207aedf6..47d104c9 100644 --- a/src/screens/Updates.tsx +++ b/src/screens/Updates.tsx @@ -22,7 +22,7 @@ import { requestManager } from '@/lib/requests/RequestManager.ts'; import { LoadingPlaceholder } from '@/components/util/LoadingPlaceholder'; import { EmptyViewAbsoluteCentered } from '@/components/util/EmptyViewAbsoluteCentered.tsx'; import { DownloadStateIndicator } from '@/components/molecules/DownloadStateIndicator'; -import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts'; +import { ChapterType } from '@/lib/graphql/generated/graphql.ts'; import { NavBarContext } from '@/components/context/NavbarContext.tsx'; import { UpdateChecker } from '@/components/library/UpdateChecker.tsx'; import { StyledGroupedVirtuoso } from '@/components/virtuoso/StyledGroupedVirtuoso.tsx'; @@ -70,7 +70,7 @@ export const Updates: React.FC = () => { const groupedUpdates = useMemo(() => groupByDate(updateEntries), [updateEntries]); const groupCounts: number[] = useMemo(() => groupedUpdates.map((group) => group[1]), [groupedUpdates]); const { data: downloaderData } = requestManager.useGetDownloadStatus(); - const queue = (downloaderData?.downloadStatus.queue as DownloadType[]) ?? []; + const queue = downloaderData?.downloadStatus.queue ?? []; const lastUpdateTimestampCompRef = useRef(null); const [lastUpdateTimestampCompHeight, setLastUpdateTimestampCompHeight] = useState(0); @@ -98,7 +98,7 @@ export const Updates: React.FC = () => { const downloadForChapter = (chapter: Pick & ChapterMangaInfo) => { const { sourceOrder, 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.manga.id); }; const downloadChapter = (chapter: ChapterIdInfo) => {