From b3a432ed2e459cad395a9bbef7f1963a0c168af3 Mon Sep 17 00:00:00 2001
From: schroda <50052685+schroda@users.noreply.github.com>
Date: Sun, 15 Oct 2023 16:03:08 +0200
Subject: [PATCH] Update typings
---
src/components/ExtensionCard.tsx | 4 +--
src/components/MangaCard.tsx | 8 +++---
src/components/MangaGrid.tsx | 8 +++---
src/components/library/LibraryMangaGrid.tsx | 29 ++++++++++-----------
src/components/manga/ChapterCard.tsx | 5 ++--
src/components/manga/ChapterList.tsx | 13 ++++-----
src/components/manga/MangaDetails.tsx | 5 ++--
src/components/manga/MangaToolbarMenu.tsx | 4 +--
src/components/manga/util.tsx | 10 +++----
src/components/navbar/ReaderNavBar.tsx | 7 +++--
src/components/source/SourceMangaGrid.tsx | 4 +--
src/screens/DownloadQueue.tsx | 5 ++--
src/screens/Extensions.tsx | 8 +++---
src/screens/Library.tsx | 5 ++--
src/screens/Manga.tsx | 3 +--
src/screens/Reader.tsx | 17 ++++++------
src/screens/SearchAll.tsx | 3 +--
src/screens/SourceMangas.tsx | 11 ++++----
src/screens/Updates.tsx | 11 ++++----
src/screens/settings/Categories.tsx | 6 ++---
src/screens/settings/LibrarySettings.tsx | 19 +++++++-------
src/screens/util/Extensions.ts | 10 +++----
src/typings.ts | 23 +++++++++++-----
src/util/metadata.ts | 17 +++++++-----
src/util/readerSettings.ts | 6 ++---
25 files changed, 124 insertions(+), 117 deletions(-)
diff --git a/src/components/ExtensionCard.tsx b/src/components/ExtensionCard.tsx
index 2825f30b..cc917968 100644
--- a/src/components/ExtensionCard.tsx
+++ b/src/components/ExtensionCard.tsx
@@ -14,11 +14,11 @@ import Avatar from '@mui/material/Avatar';
import Typography from '@mui/material/Typography';
import { Box } from '@mui/material';
import { useTranslation } from 'react-i18next';
-import { Extension, TranslationKey } from '@/typings';
+import { PartialExtension, TranslationKey } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
interface IProps {
- extension: Extension;
+ extension: PartialExtension;
}
enum ExtensionAction {
diff --git a/src/components/MangaCard.tsx b/src/components/MangaCard.tsx
index c6e07626..bba7181f 100644
--- a/src/components/MangaCard.tsx
+++ b/src/components/MangaCard.tsx
@@ -15,7 +15,7 @@ import { useTranslation } from 'react-i18next';
import requestManager from '@/lib/requests/RequestManager.ts';
import { GridLayout, useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext';
import SpinnerImage from '@/components/util/SpinnerImage';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
+import { TPartialManga } from '@/typings.ts';
const BottomGradient = styled('div')({
position: 'absolute',
@@ -66,7 +66,7 @@ const BadgeContainer = styled('div')({
});
interface IProps {
- manga: MangaType;
+ manga: TPartialManga;
gridLayout?: GridLayout;
inLibraryIndicator?: boolean;
}
@@ -120,10 +120,10 @@ const MangaCard = (props: IProps) => {
{t('manga.button.in_library')}
)}
- {showUnreadBadge && unread! > 0 && (
+ {showUnreadBadge && (unread ?? 0) > 0 && (
{unread}
)}
- {showDownloadBadge && downloadCount! > 0 && (
+ {showDownloadBadge && (downloadCount ?? 0) > 0 && (
(({ children, ...props }, ref) => (
@@ -40,13 +40,13 @@ const GridItemContainerWithDimension = (
);
};
-const createMangaCard = (manga: MangaType, gridLayout?: GridLayout, inLibraryIndicator?: boolean) => (
+const createMangaCard = (manga: TPartialManga, gridLayout?: GridLayout, inLibraryIndicator?: boolean) => (
);
type DefaultGridProps = {
isLoading: boolean;
- mangas: MangaType[];
+ mangas: TPartialManga[];
inLibraryIndicator?: boolean;
GridItemContainer: (props: GridTypeMap['props'] & Partial) => JSX.Element;
gridLayout?: GridLayout;
@@ -150,7 +150,7 @@ const VerticalGrid = ({
};
export interface IMangaGridProps {
- mangas: MangaType[];
+ mangas: TPartialManga[];
isLoading: boolean;
message?: string;
messageExtra?: JSX.Element;
diff --git a/src/components/library/LibraryMangaGrid.tsx b/src/components/library/LibraryMangaGrid.tsx
index c2534b2c..93b67d99 100644
--- a/src/components/library/LibraryMangaGrid.tsx
+++ b/src/components/library/LibraryMangaGrid.tsx
@@ -9,13 +9,12 @@
import React, { useEffect, useMemo } from 'react';
import { StringParam, useQueryParam } from 'use-query-params';
import { useTranslation } from 'react-i18next';
-import { LibrarySortMode, NullAndUndefined } from '@/typings';
+import { LibrarySortMode, NullAndUndefined, TManga } from '@/typings';
import { useSearchSettings } from '@/util/searchSettings';
import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext';
import MangaGrid from '@/components/MangaGrid';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
-const unreadFilter = (unread: NullAndUndefined, { unreadCount }: MangaType): boolean => {
+const unreadFilter = (unread: NullAndUndefined, { unreadCount }: TManga): boolean => {
switch (unread) {
case true:
return !!unreadCount && unreadCount >= 1;
@@ -26,7 +25,7 @@ const unreadFilter = (unread: NullAndUndefined, { unreadCount }: MangaT
}
};
-const downloadedFilter = (downloaded: NullAndUndefined, { downloadCount }: MangaType): boolean => {
+const downloadedFilter = (downloaded: NullAndUndefined, { downloadCount }: TManga): boolean => {
switch (downloaded) {
case true:
return !!downloadCount && downloadCount >= 1;
@@ -37,24 +36,24 @@ const downloadedFilter = (downloaded: NullAndUndefined, { downloadCount
}
};
-const queryFilter = (query: NullAndUndefined, { title }: MangaType): boolean => {
+const queryFilter = (query: NullAndUndefined, { title }: TManga): boolean => {
if (!query) return true;
return title.toLowerCase().includes(query.toLowerCase());
};
-const queryGenreFilter = (query: NullAndUndefined, { genre }: MangaType): boolean => {
+const queryGenreFilter = (query: NullAndUndefined, { genre }: TManga): boolean => {
if (!query) return true;
const queries = query.split(',').map((str) => str.toLowerCase().trim());
return queries.every((element) => genre.map((el) => el.toLowerCase()).includes(element));
};
const filterManga = (
- mangas: MangaType[],
+ mangas: TManga[],
query: NullAndUndefined,
unread: NullAndUndefined,
downloaded: NullAndUndefined,
ignoreFilters: boolean,
-): MangaType[] =>
+): TManga[] =>
mangas.filter((manga) => {
const ignoreFiltersWhileSearching = ignoreFilters && query?.length;
const matchesSearch = queryFilter(query, manga) || queryGenreFilter(query, manga);
@@ -64,20 +63,20 @@ const filterManga = (
return matchesSearch && matchesFilters;
});
-const sortByUnread = (a: MangaType, b: MangaType): number => (a.unreadCount ?? 0) - (b.unreadCount ?? 0);
+const sortByUnread = (a: TManga, b: TManga): number => (a.unreadCount ?? 0) - (b.unreadCount ?? 0);
-const sortByTitle = (a: MangaType, b: MangaType): number => a.title.localeCompare(b.title);
+const sortByTitle = (a: TManga, b: TManga): number => a.title.localeCompare(b.title);
-const sortByDateAdded = (a: MangaType, b: MangaType): number => Number(a.inLibraryAt) - Number(b.inLibraryAt);
+const sortByDateAdded = (a: TManga, b: TManga): number => Number(a.inLibraryAt) - Number(b.inLibraryAt);
-const sortByLastRead = (a: MangaType, b: MangaType): number =>
+const sortByLastRead = (a: TManga, b: TManga): number =>
Number(b.lastReadChapter?.lastReadAt ?? 0) - Number(a.lastReadChapter?.lastReadAt ?? 0);
const sortManga = (
- manga: MangaType[],
+ manga: TManga[],
sort: NullAndUndefined,
desc: NullAndUndefined,
-): MangaType[] => {
+): TManga[] => {
const result = [...manga];
switch (sort) {
@@ -105,7 +104,7 @@ const sortManga = (
};
interface LibraryMangaGridProps {
- mangas: MangaType[];
+ mangas: TManga[];
isLoading: boolean;
message?: string;
}
diff --git a/src/components/manga/ChapterCard.tsx b/src/components/manga/ChapterCard.tsx
index b415db85..a39db05a 100644
--- a/src/components/manga/ChapterCard.tsx
+++ b/src/components/manga/ChapterCard.tsx
@@ -30,10 +30,11 @@ import { useTranslation } from 'react-i18next';
import requestManager from '@/lib/requests/RequestManager.ts';
import { getUploadDateString } from '@/util/date';
import DownloadStateIndicator from '@/components/molecules/DownloadStateIndicator';
-import { ChapterType, DownloadType, UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
+import { DownloadType, UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
+import { TChapter } from '@/typings.ts';
interface IProps {
- chapter: ChapterType;
+ chapter: TChapter;
chapterIds: number[];
downloadChapter: DownloadType | undefined;
showChapterNumber: boolean;
diff --git a/src/components/manga/ChapterList.tsx b/src/components/manga/ChapterList.tsx
index bb53fb22..b53e5732 100644
--- a/src/components/manga/ChapterList.tsx
+++ b/src/components/manga/ChapterList.tsx
@@ -11,7 +11,7 @@ import Typography from '@mui/material/Typography';
import React, { ComponentProps, useEffect, useMemo, useRef, useState } from 'react';
import { Virtuoso } from 'react-virtuoso';
import { useTranslation } from 'react-i18next';
-import { TranslationKey } from '@/typings';
+import { TChapter, TManga, TranslationKey } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import ChapterCard from '@/components/manga/ChapterCard';
import ResumeFab from '@/components/manga/ResumeFAB';
@@ -21,7 +21,7 @@ import makeToast from '@/components/util/Toast';
import ChaptersToolbarMenu from '@/components/manga/ChaptersToolbarMenu';
import SelectionFAB from '@/components/manga/SelectionFAB';
import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab';
-import { ChapterType, DownloadType, MangaType, UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
+import { DownloadType, UpdateChapterPatchInput } from '@/lib/graphql/generated/graphql.ts';
const StyledVirtuoso = styled(Virtuoso)(({ theme }) => ({
listStyle: 'none',
@@ -68,13 +68,13 @@ const actionsStrings: {
};
export interface IChapterWithMeta {
- chapter: ChapterType;
+ chapter: TChapter;
downloadChapter: DownloadType | undefined;
selected: boolean | null;
}
interface IProps {
- manga: MangaType;
+ manga: TManga;
isRefreshing: boolean;
}
@@ -88,10 +88,7 @@ const ChapterList: React.FC = ({ manga, isRefreshing }) => {
const [options, dispatch] = useChapterOptions(manga.id);
const { data: chaptersData, loading: isLoading, refetch } = requestManager.useGetMangaChapters(manga.id);
- const chapters = useMemo(
- () => (chaptersData?.chapters.nodes as ChapterType[]) ?? [],
- [chaptersData?.chapters.nodes],
- );
+ const chapters = useMemo(() => chaptersData?.chapters.nodes ?? [], [chaptersData?.chapters.nodes]);
const mangaChapterIds = useMemo(() => chapters.map((chapter) => chapter.id), [chapters]);
useEffect(() => {
diff --git a/src/components/manga/MangaDetails.tsx b/src/components/manga/MangaDetails.tsx
index 71a67232..19cbc91d 100644
--- a/src/components/manga/MangaDetails.tsx
+++ b/src/components/manga/MangaDetails.tsx
@@ -14,10 +14,9 @@ import React, { useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import { t as translate } from 'i18next';
import Button from '@mui/material/Button';
-import { ISource } from '@/typings';
+import { ISource, TManga } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import makeToast from '@/components/util/Toast';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const DetailsWrapper = styled('div')(({ theme }) => ({
width: '100%',
@@ -151,7 +150,7 @@ const OpenSourceButton = ({ url }: { url?: string | null }) => {
};
interface IProps {
- manga: MangaType;
+ manga: TManga;
}
function getSourceName(source?: ISource | null) {
diff --git a/src/components/manga/MangaToolbarMenu.tsx b/src/components/manga/MangaToolbarMenu.tsx
index 4e035d04..5a2f886b 100644
--- a/src/components/manga/MangaToolbarMenu.tsx
+++ b/src/components/manga/MangaToolbarMenu.tsx
@@ -22,10 +22,10 @@ import {
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import CategorySelect from '@/components/navbar/action/CategorySelect';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
+import { TManga } from '@/typings.ts';
interface IProps {
- manga: MangaType;
+ manga: TManga;
onRefresh: () => any;
refreshing: boolean;
}
diff --git a/src/components/manga/util.tsx b/src/components/manga/util.tsx
index edfb25c0..ec63ee08 100644
--- a/src/components/manga/util.tsx
+++ b/src/components/manga/util.tsx
@@ -12,10 +12,10 @@ import {
ChapterOptionsReducerAction,
ChapterSortMode,
NullAndUndefined,
+ TChapter,
TranslationKey,
} from '@/typings';
import { useReducerLocalStorage } from '@/util/useLocalStorage';
-import { ChapterType } from '@/lib/graphql/generated/graphql.ts';
const defaultChapterOptions: ChapterListOptions = {
active: false,
@@ -46,7 +46,7 @@ function chapterOptionsReducer(state: ChapterListOptions, actions: ChapterOption
}
}
-export function unreadFilter(unread: NullAndUndefined, { isRead: isChapterRead }: ChapterType) {
+export function unreadFilter(unread: NullAndUndefined, { isRead: isChapterRead }: TChapter) {
switch (unread) {
case true:
return !isChapterRead;
@@ -57,7 +57,7 @@ export function unreadFilter(unread: NullAndUndefined, { isRead: isChap
}
}
-function downloadFilter(downloaded: NullAndUndefined, { isDownloaded: chapterDownload }: ChapterType) {
+function downloadFilter(downloaded: NullAndUndefined, { isDownloaded: chapterDownload }: TChapter) {
switch (downloaded) {
case true:
return chapterDownload;
@@ -68,7 +68,7 @@ function downloadFilter(downloaded: NullAndUndefined, { isDownloaded: c
}
}
-function bookmarkedFilter(bookmarked: NullAndUndefined, { isBookmarked: chapterBookmarked }: ChapterType) {
+function bookmarkedFilter(bookmarked: NullAndUndefined, { isBookmarked: chapterBookmarked }: TChapter) {
switch (bookmarked) {
case true:
return chapterBookmarked;
@@ -79,7 +79,7 @@ function bookmarkedFilter(bookmarked: NullAndUndefined, { isBookmarked:
}
}
-export function filterAndSortChapters(chapters: ChapterType[], options: ChapterListOptions): ChapterType[] {
+export function filterAndSortChapters(chapters: TChapter[], options: ChapterListOptions): TChapter[] {
const filtered = options.active
? chapters.filter(
(chp) =>
diff --git a/src/components/navbar/ReaderNavBar.tsx b/src/components/navbar/ReaderNavBar.tsx
index 236e6474..3ad637d1 100644
--- a/src/components/navbar/ReaderNavBar.tsx
+++ b/src/components/navbar/ReaderNavBar.tsx
@@ -24,9 +24,8 @@ import ListItemText from '@mui/material/ListItemText';
import ListItemSecondaryAction from '@mui/material/ListItemSecondaryAction';
import Collapse from '@mui/material/Collapse';
import { useTranslation } from 'react-i18next';
-import { ChapterOffset, IReaderSettings } from '@/typings';
+import { ChapterOffset, IReaderSettings, TChapter, TManga } from '@/typings';
import ReaderSettingsOptions from '@/components/reader/ReaderSettingsOptions';
-import { ChapterType, MangaType } from '@/lib/graphql/generated/graphql.ts';
const Root = styled('div')(({ theme }) => ({
top: 0,
@@ -115,8 +114,8 @@ const OpenDrawerButton = styled(IconButton)(({ theme }) => ({
interface IProps {
settings: IReaderSettings;
setSettingValue: (key: keyof IReaderSettings, value: string | boolean) => void;
- manga: MangaType;
- chapter: ChapterType;
+ manga: TManga;
+ chapter: TChapter;
curPage: number;
scrollToPage: (page: number) => void;
openNextChapter: (offset: ChapterOffset, setHistory: (nextChapterIndex: number) => void) => Promise;
diff --git a/src/components/source/SourceMangaGrid.tsx b/src/components/source/SourceMangaGrid.tsx
index 9b6cb7a8..8fcb14ed 100644
--- a/src/components/source/SourceMangaGrid.tsx
+++ b/src/components/source/SourceMangaGrid.tsx
@@ -8,9 +8,9 @@
import { useTranslation } from 'react-i18next';
import MangaGrid, { IMangaGridProps } from '@/components/MangaGrid';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
+import { TPartialManga } from '@/typings.ts';
-function filterManga(mangas: MangaType[]): MangaType[] {
+function filterManga(mangas: TPartialManga[]): TPartialManga[] {
return mangas;
}
diff --git a/src/screens/DownloadQueue.tsx b/src/screens/DownloadQueue.tsx
index a913c58b..325ecc14 100644
--- a/src/screens/DownloadQueue.tsx
+++ b/src/screens/DownloadQueue.tsx
@@ -25,7 +25,8 @@ import { NavbarToolbar } from '@/components/navbar/DefaultNavBar';
import DownloadStateIndicator from '@/components/molecules/DownloadStateIndicator';
import EmptyView from '@/components/util/EmptyView';
import NavbarContext from '@/components/context/NavbarContext';
-import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
+import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
+import { TChapter } from '@/typings.ts';
const DownloadQueue: React.FC = () => {
const { t } = useTranslation();
@@ -55,7 +56,7 @@ const DownloadQueue: React.FC = () => {
return ;
}
- const handleDelete = async (chapter: ChapterType) => {
+ const handleDelete = async (chapter: TChapter) => {
const isRunning = status === 'STARTED';
try {
diff --git a/src/screens/Extensions.tsx b/src/screens/Extensions.tsx
index 805a60f2..aeb5172e 100644
--- a/src/screens/Extensions.tsx
+++ b/src/screens/Extensions.tsx
@@ -30,12 +30,12 @@ import { makeToaster } from '@/components/util/Toast';
import LangSelect from '@/components/navbar/action/LangSelect';
import NavbarContext from '@/components/context/NavbarContext';
import ExtensionCard from '@/components/ExtensionCard';
-import { Extension } from '@/typings.ts';
+import { PartialExtension } from '@/typings.ts';
const LANGUAGE = 0;
const EXTENSIONS = 1;
-function getExtensionsInfo(extensions: Extension[]): {
+function getExtensionsInfo(extensions: PartialExtension[]): {
allLangs: string[];
groupedExtensions: GroupedExtensionsResult;
} {
@@ -132,7 +132,7 @@ export default function MangaExtensions() {
[shownLangs, groupedExtensions],
);
- const flatRenderItems: (Extension | string)[] = filteredGroupedExtensions.flat(2);
+ const flatRenderItems: (PartialExtension | string)[] = filteredGroupedExtensions.flat(2);
const [toasts, makeToast] = makeToaster(useState([]));
@@ -229,7 +229,7 @@ export default function MangaExtensions() {
);
}
- const item = flatRenderItems[index] as Extension;
+ const item = flatRenderItems[index] as PartialExtension;
return ;
}}
diff --git a/src/screens/Library.tsx b/src/screens/Library.tsx
index 4b708fb2..20150cca 100644
--- a/src/screens/Library.tsx
+++ b/src/screens/Library.tsx
@@ -7,7 +7,7 @@
*/
import { Chip, Tab, Tabs, styled, Box } from '@mui/material';
-import React, { useContext, useEffect, useMemo, useRef } from 'react';
+import React, { useContext, useEffect, useMemo } from 'react';
import { useQueryParam, NumberParam } from 'use-query-params';
import { useTranslation } from 'react-i18next';
import requestManager from '@/lib/requests/RequestManager.ts';
@@ -20,7 +20,6 @@ import LibraryMangaGrid from '@/components/library/LibraryMangaGrid';
import AppbarSearch from '@/components/util/AppbarSearch';
import UpdateChecker from '@/components/library/UpdateChecker';
import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const StyledGridWrapper = styled(Box)(({ theme }) => ({
// TabsMenu height + TabsMenu bottom padding - grid item top padding
@@ -85,7 +84,7 @@ export default function Library() {
error: mangaError,
loading: mangaLoading,
} = requestManager.useGetCategoryMangas(activeTab?.id, { skip: !activeTab, nextFetchPolicy: 'cache-only' });
- const mangas = (categoryMangaResponse?.category.mangas.nodes as unknown as MangaType[]) ?? [];
+ const mangas = categoryMangaResponse?.category.mangas.nodes ?? [];
const { setTitle, setAction } = useContext(NavbarContext);
useEffect(() => {
diff --git a/src/screens/Manga.tsx b/src/screens/Manga.tsx
index 48958c04..7768d0a1 100644
--- a/src/screens/Manga.tsx
+++ b/src/screens/Manga.tsx
@@ -20,7 +20,6 @@ import MangaDetails from '@/components/manga/MangaDetails';
import MangaToolbarMenu from '@/components/manga/MangaToolbarMenu';
import EmptyView from '@/components/util/EmptyView';
import LoadingPlaceholder from '@/components/util/LoadingPlaceholder';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
const AUTOFETCH_AGE = 1000 * 60 * 60 * 24; // 24 hours
@@ -33,7 +32,7 @@ const Manga: React.FC = () => {
const { data, error, loading: isLoading, networkStatus, refetch } = requestManager.useGetManga(id);
const isValidating = isNetworkRequestInFlight(networkStatus);
- const manga = data?.manga as MangaType | undefined;
+ const manga = data?.manga;
const [refresh, { loading: refreshing }] = useRefreshManga(id);
useSetDefaultBackTo('library');
diff --git a/src/screens/Reader.tsx b/src/screens/Reader.tsx
index 5fc012bf..e6baa514 100644
--- a/src/screens/Reader.tsx
+++ b/src/screens/Reader.tsx
@@ -11,7 +11,7 @@ import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'r
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { Box } from '@mui/material';
import { useTranslation } from 'react-i18next';
-import { ChapterOffset, IReaderSettings, ReaderType, TranslationKey } from '@/typings';
+import { ChapterOffset, IReaderSettings, ReaderType, TChapter, TManga, TranslationKey } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import {
checkAndHandleMissingStoredReaderSettings,
@@ -27,9 +27,8 @@ import VerticalPager from '@/components/reader/pager/VerticalPager';
import ReaderNavBar from '@/components/navbar/ReaderNavBar';
import NavbarContext from '@/components/context/NavbarContext';
import makeToast from '@/components/util/Toast';
-import { ChapterType, MangaType } from '@/lib/graphql/generated/graphql.ts';
-const isDupChapter = async (chapterIndex: number, currentChapter: ChapterType) => {
+const isDupChapter = async (chapterIndex: number, currentChapter: TChapter) => {
const nextChapter = await requestManager.getChapter(currentChapter.manga.id, chapterIndex).response;
return nextChapter.data.chapter.chapterNumber === currentChapter.chapterNumber;
@@ -42,7 +41,7 @@ const isDupChapter = async (chapterIndex: number, currentChapter: ChapterType) =
*/
const getOffsetChapter = async (
chapterIndex: number,
- currentChapter: ChapterType,
+ currentChapter: TChapter,
skipDupChapters: boolean,
offset: ChapterOffset,
): Promise => {
@@ -86,7 +85,7 @@ const initialChapter = {
chapterCount: 0,
lastPageRead: 0,
name: 'Loading...',
-} as unknown as ChapterType;
+} as unknown as TChapter;
export default function Reader() {
const { t } = useTranslation();
@@ -105,17 +104,17 @@ export default function Reader() {
inLibraryAt: 0,
lastReadAt: 0,
chapters: { totalCount: 0 },
- }) as unknown as MangaType,
+ }) as unknown as TManga,
[mangaId],
);
const { data, loading: isMangaLoading } = requestManager.useGetManga(mangaId);
- const loadedChapter = useRef(null);
+ const loadedChapter = useRef(null);
const isChapterLoaded =
Number(mangaId) === loadedChapter.current?.manga.id &&
Number(chapterIndex) === loadedChapter.current?.sourceOrder &&
loadedChapter.current?.pageCount !== -1;
- const manga = (data?.manga as MangaType) ?? initialManga;
+ const manga = data?.manga ?? initialManga;
const { data: chapterData, loading: isChapterLoading } = requestManager.useGetMangaChapter(mangaId, chapterIndex, {
skip: isChapterLoaded,
});
@@ -129,7 +128,7 @@ export default function Reader() {
}
if (chapterData?.chapter) {
- return chapterData.chapter as ChapterType;
+ return chapterData.chapter;
}
return null;
diff --git a/src/screens/SearchAll.tsx b/src/screens/SearchAll.tsx
index 2afc5336..903956d3 100644
--- a/src/screens/SearchAll.tsx
+++ b/src/screens/SearchAll.tsx
@@ -21,7 +21,6 @@ import LangSelect from '@/components/navbar/action/LangSelect';
import MangaGrid from '@/components/MangaGrid';
import NavbarContext from '@/components/context/NavbarContext';
import { useDebounce } from '@/components/manga/hooks';
-import { MangaType } from '@/lib/graphql/generated/graphql.ts';
type SourceLoadingState = { isLoading: boolean; hasResults: boolean; emptySearch: boolean };
type SourceToLoadingStateMap = Map;
@@ -103,7 +102,7 @@ const SourceSearchPreview = React.memo(
skipRequest: !searchString,
});
const { data: searchResult, isLoading, error, abortRequest } = results[0]!;
- const mangas = (searchResult?.fetchSourceManga.mangas as MangaType[]) ?? [];
+ const mangas = searchResult?.fetchSourceManga.mangas ?? [];
const noMangasFound = !isLoading && !mangas.length;
useEffect(() => {
diff --git a/src/screens/SourceMangas.tsx b/src/screens/SourceMangas.tsx
index 3db87ace..442a6012 100644
--- a/src/screens/SourceMangas.tsx
+++ b/src/screens/SourceMangas.tsx
@@ -17,7 +17,7 @@ import { Box, Button, styled, useTheme, useMediaQuery } from '@mui/material';
import FavoriteIcon from '@mui/icons-material/Favorite';
import NewReleasesIcon from '@mui/icons-material/NewReleases';
import FilterListIcon from '@mui/icons-material/FilterList';
-import { TranslationKey } from '@/typings';
+import { TPartialManga, TranslationKey } from '@/typings';
import requestManager, { AbortableApolloUseMutationPaginatedResponse } from '@/lib/requests/RequestManager.ts';
import { useDebounce } from '@/components/manga/hooks';
import { useLibraryOptionsContext } from '@/components/context/LibraryOptionsContext';
@@ -29,7 +29,6 @@ import SourceMangaGrid from '@/components/source/SourceMangaGrid';
import {
GetSourceMangasFetchMutation,
GetSourceMangasFetchMutationVariables,
- MangaType,
} from '@/lib/graphql/generated/graphql.ts';
const ContentTypeMenu = styled('div')(({ theme }) => ({
@@ -87,8 +86,8 @@ const SOURCE_CONTENT_TYPE_TO_ERROR_MSG_KEY: { [contentType in SourceContentType]
[SourceContentType.SEARCH]: 'manga.error.label.no_mangas_found',
};
-const getUniqueMangas = (mangas: MangaType[]): MangaType[] => {
- const uniqueMangas: MangaType[] = [];
+const getUniqueMangas = (mangas: TPartialManga[]): TPartialManga[] => {
+ const uniqueMangas: TPartialManga[] = [];
mangas.forEach((manga) => {
const isDuplicate = uniqueMangas.some((uniqueManga) => uniqueManga.id === manga.id);
@@ -166,7 +165,7 @@ const useSourceManga = (
.map((page) => page.data?.fetchSourceManga.mangas ?? [])
.reduce((prevList, list) => [...prevList, ...list], []),
[pages],
- ) as MangaType[];
+ );
const uniqueItems = useMemo(() => getUniqueMangas(items), [items]);
if (!uniqueItems.length) {
@@ -224,7 +223,7 @@ export default function SourceMangas() {
filtersToApply,
isLargeScreen ? 2 : 1,
);
- const mangas = (data?.fetchSourceManga.mangas as MangaType[]) ?? [];
+ const mangas = data?.fetchSourceManga.mangas ?? [];
const hasNextPage = data?.fetchSourceManga.hasNextPage ?? false;
const { data: sourceData } = requestManager.useGetSource(sourceId);
diff --git a/src/screens/Updates.tsx b/src/screens/Updates.tsx
index 12c98818..2776e252 100644
--- a/src/screens/Updates.tsx
+++ b/src/screens/Updates.tsx
@@ -23,7 +23,8 @@ import LoadingPlaceholder from '@/components/util/LoadingPlaceholder';
import EmptyView from '@/components/util/EmptyView';
import DownloadStateIndicator from '@/components/molecules/DownloadStateIndicator';
import NavbarContext from '@/components/context/NavbarContext';
-import { ChapterType, DownloadType } from '@/lib/graphql/generated/graphql.ts';
+import { DownloadType } from '@/lib/graphql/generated/graphql.ts';
+import { TChapter } from '@/typings.ts';
const StyledGroupedVirtuoso = styled(GroupedVirtuoso)(({ theme }) => ({
// 64px header
@@ -81,7 +82,7 @@ function getDateString(date: Date) {
return date.toLocaleDateString();
}
-const groupByDate = (updates: ChapterType[]): [date: string, items: number][] => {
+const groupByDate = (updates: TChapter[]): [date: string, items: number][] => {
if (!updates.length) {
return [];
}
@@ -111,7 +112,7 @@ const Updates: React.FC = () => {
});
const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage;
const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;
- const updateEntries = (chapterUpdateData?.chapters.nodes as ChapterType[]) ?? [];
+ const updateEntries = chapterUpdateData?.chapters.nodes ?? [];
const groupedUpdates = useMemo(() => groupByDate(updateEntries), [updateEntries]);
const groupCounts: number[] = useMemo(() => groupedUpdates.map((group) => group[1]), [groupedUpdates]);
const { data: downloaderData } = requestManager.useDownloadSubscription();
@@ -123,7 +124,7 @@ const Updates: React.FC = () => {
setAction(null);
}, [t]);
- const downloadForChapter = (chapter: ChapterType) => {
+ const downloadForChapter = (chapter: TChapter) => {
const {
sourceOrder,
manga: { id: mangaId },
@@ -131,7 +132,7 @@ const Updates: React.FC = () => {
return queue.find((q) => sourceOrder === q.chapter.sourceOrder && mangaId === q.chapter.manga.id);
};
- const downloadChapter = (chapter: ChapterType) => {
+ const downloadChapter = (chapter: TChapter) => {
requestManager.addChapterToDownloadQueue(chapter.id);
};
diff --git a/src/screens/settings/Categories.tsx b/src/screens/settings/Categories.tsx
index 001e4691..212d54aa 100644
--- a/src/screens/settings/Categories.tsx
+++ b/src/screens/settings/Categories.tsx
@@ -28,7 +28,7 @@ import requestManager from '@/lib/requests/RequestManager.ts';
import StrictModeDroppable from '@/lib/StrictModeDroppable';
import { DEFAULT_FULL_FAB_HEIGHT } from '@/components/util/StyledFab';
import NavbarContext, { useSetDefaultBackTo } from '@/components/context/NavbarContext';
-import { CategoryType } from '@/lib/graphql/generated/graphql.ts';
+import { TCategory } from '@/typings.ts';
const getItemStyle = (
isDragging: boolean,
@@ -58,7 +58,7 @@ export default function Categories() {
if (res.length > 0 && res[0].name === 'Default') {
res.shift();
}
- return res as CategoryType[];
+ return res;
}, [data]);
const [categoryToEdit, setCategoryToEdit] = useState(-1); // -1 means new category
@@ -69,7 +69,7 @@ export default function Categories() {
useSetDefaultBackTo('settings');
- const categoryReorder = (list: CategoryType[], from: number, to: number) => {
+ const categoryReorder = (list: TCategory[], from: number, to: number) => {
const reorderedCategory = list[from];
const newData = [...list];
const [removed] = newData.splice(from, 1);
diff --git a/src/screens/settings/LibrarySettings.tsx b/src/screens/settings/LibrarySettings.tsx
index fa601885..99d0ebcb 100644
--- a/src/screens/settings/LibrarySettings.tsx
+++ b/src/screens/settings/LibrarySettings.tsx
@@ -25,7 +25,8 @@ import makeToast from '@/components/util/Toast';
import ThreeStateCheckboxInput from '@/components/atoms/ThreeStateCheckboxInput';
import NavbarContext, { useSetDefaultBackTo } from '@/components/context/NavbarContext';
import SearchSettings from '@/screens/settings/SearchSettings';
-import { CategoryType, IncludeInUpdate } from '@/lib/graphql/generated/graphql.ts';
+import { IncludeInUpdate } from '@/lib/graphql/generated/graphql.ts';
+import { TCategory } from '@/typings.ts';
const CategoriesDiv = styled('div')({
display: 'flex',
@@ -62,7 +63,7 @@ const includeInUpdateStatusToBoolean = (status: IncludeInUpdate): boolean | null
};
const getCategoryUpdateInfo = (
- categories: CategoryType[],
+ categories: TCategory[],
areIncluded: boolean,
unsetCategories: number,
allCategories: number,
@@ -100,19 +101,19 @@ export default function LibrarySettings() {
useSetDefaultBackTo('settings');
const { data, error: requestError } = requestManager.useGetCategories();
- const categories = (data?.categories.nodes ?? []) as CategoryType[];
- const [dialogCategories, setDialogCategories] = useState(categories);
+ const categories = data?.categories.nodes ?? [];
+ const [dialogCategories, setDialogCategories] = useState(categories);
const [isDialogOpen, setIsDialogOpen] = useState(false);
useEffect(() => {
setDialogCategories(categories);
}, [categories]);
- const unsetCategories: CategoryType[] =
+ const unsetCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Unset) ?? [];
- const excludedCategories: CategoryType[] =
+ const excludedCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Exclude) ?? [];
- const includedCategories: CategoryType[] =
+ const includedCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Include) ?? [];
const excludedCategoriesText = getCategoryUpdateInfo(
excludedCategories,
@@ -129,7 +130,7 @@ export default function LibrarySettings() {
requestError,
);
- const updateCategory = (category: CategoryType) =>
+ const updateCategory = (category: TCategory) =>
requestManager.updateCategory(category.id, { includeInUpdate: category.includeInUpdate }).response;
const updateCategories = async () => {
@@ -218,7 +219,7 @@ export default function LibrarySettings() {
const categoryIndex = dialogCategories.findIndex(
(category_) => category_ === category,
);
- const updatedDialogCategories: CategoryType[] = [
+ const updatedDialogCategories: TCategory[] = [
...dialogCategories.slice(0, categoryIndex),
{
...category,
diff --git a/src/screens/util/Extensions.ts b/src/screens/util/Extensions.ts
index 09e5d4de..5d83890c 100644
--- a/src/screens/util/Extensions.ts
+++ b/src/screens/util/Extensions.ts
@@ -7,7 +7,7 @@
*/
import { t } from 'i18next';
-import { Extension, TranslationKey } from '@/typings';
+import { PartialExtension, TranslationKey } from '@/typings';
import { DefaultLanguage, langCodeToName } from '@/util/language';
export enum ExtensionState {
@@ -16,16 +16,16 @@ export enum ExtensionState {
OBSOLETE = 'OBSOLETE',
}
-export type GroupedExtensionsResult = [KEY, Extension[]][];
+export type GroupedExtensionsResult = [KEY, PartialExtension[]][];
export type GroupedByExtensionState = {
- [state in ExtensionState]: Extension[];
+ [state in ExtensionState]: PartialExtension[];
};
export type GroupedByLanguage = {
- [language in DefaultLanguage]: Extension[];
+ [language in DefaultLanguage]: PartialExtension[];
} & {
- [language: string]: Extension[];
+ [language: string]: PartialExtension[];
};
export type GroupedExtensions = GroupedByExtensionState & GroupedByLanguage;
diff --git a/src/typings.ts b/src/typings.ts
index 9bae87a2..589a4b50 100644
--- a/src/typings.ts
+++ b/src/typings.ts
@@ -11,10 +11,11 @@ import { SvgIconTypeMap } from '@mui/material/SvgIcon/SvgIcon';
import { ParseKeys } from 'i18next';
import { Location } from 'react-router-dom';
import {
- ChapterType,
- ExtensionType,
+ GetCategoryQuery,
+ GetChapterQuery,
+ GetExtensionQuery,
+ GetMangaQuery,
GetSourceQuery,
- MangaType,
MetaType,
SourcePreferenceChangeInput,
} from '@/lib/graphql/generated/graphql.ts';
@@ -33,6 +34,8 @@ export type RecursivePartial = {
: T[P];
};
+export type OptionalProperty = Omit & Partial>;
+
type GenericLocation = Omit & { state?: State };
declare module 'react-router-dom' {
@@ -43,7 +46,7 @@ declare module 'react-router-dom' {
export type TranslationKey = ParseKeys;
-export type Extension = Omit;
+export type PartialExtension = GetExtensionQuery['extension'];
export interface ISource {
id: string;
@@ -105,6 +108,10 @@ export interface IMangaCard {
lastReadAt: number;
}
+export type TManga = GetMangaQuery['manga'];
+
+export type TPartialManga = OptionalProperty;
+
export interface IManga {
id: number;
sourceId: string;
@@ -166,12 +173,16 @@ export interface IMangaChapter {
chapter: IChapter;
}
+export type TChapter = GetChapterQuery['chapter'];
+
export enum IncludeInGlobalUpdate {
EXCLUDE = 0,
INCLUDE = 1,
UNSET = -1,
}
+export type TCategory = GetCategoryQuery['category'];
+
export interface ICategory {
id: number;
order: number;
@@ -230,8 +241,8 @@ export interface IReaderProps {
curPage: number;
initialPage: number;
settings: IReaderSettings;
- manga: MangaType;
- chapter: ChapterType;
+ manga: TManga;
+ chapter: TChapter;
nextChapter: () => void;
prevChapter: () => void;
}
diff --git a/src/util/metadata.ts b/src/util/metadata.ts
index 8ef3464d..d16bd040 100644
--- a/src/util/metadata.ts
+++ b/src/util/metadata.ts
@@ -14,9 +14,12 @@ import {
Metadata,
MetadataHolder,
MetadataKeyValuePair,
+ TCategory,
+ TChapter,
+ TManga,
} from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
-import { CategoryType, ChapterType, MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
+import { MetaType } from '@/lib/graphql/generated/graphql.ts';
const APP_METADATA_KEY_PREFIX = 'webUI_';
@@ -322,16 +325,16 @@ export const requestUpdateMetadataValue = async (
switch (holderType) {
case 'category':
- await requestManager.setCategoryMeta((metadataHolder as CategoryType).id, metadataKey, value).response;
+ await requestManager.setCategoryMeta((metadataHolder as TCategory).id, metadataKey, value).response;
break;
case 'chapter':
- await requestManager.setChapterMeta((metadataHolder as ChapterType).id, metadataKey, value).response;
+ await requestManager.setChapterMeta((metadataHolder as TChapter).id, metadataKey, value).response;
break;
case 'global':
await requestManager.setGlobalMetadata(metadataKey, value).response;
break;
case 'manga':
- await requestManager.setMangaMeta((metadataHolder as MangaType).id, metadataKey, value).response;
+ await requestManager.setMangaMeta((metadataHolder as TManga).id, metadataKey, value).response;
break;
default:
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
@@ -351,16 +354,16 @@ export const requestUpdateServerMetadata = async (
): Promise => requestUpdateMetadata({ meta: serverMetadata }, 'global', keysToValues);
export const requestUpdateMangaMetadata = async (
- manga: MangaType,
+ manga: TManga,
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata(manga, 'manga', keysToValues);
export const requestUpdateChapterMetadata = async (
- chapter: ChapterType,
+ chapter: TChapter,
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata(chapter, 'chapter', keysToValues);
export const requestUpdateCategoryMetadata = async (
- category: CategoryType,
+ category: TCategory,
keysToValues: MetadataKeyValuePair[],
): Promise => requestUpdateMetadata(category, 'category', keysToValues);
diff --git a/src/util/readerSettings.ts b/src/util/readerSettings.ts
index d3f05cc8..bfd61325 100644
--- a/src/util/readerSettings.ts
+++ b/src/util/readerSettings.ts
@@ -6,7 +6,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
-import { Metadata, IReaderSettings, MetadataKeyValuePair, GqlMetaHolder } from '@/typings';
+import { Metadata, IReaderSettings, MetadataKeyValuePair, GqlMetaHolder, TManga } from '@/typings';
import requestManager from '@/lib/requests/RequestManager.ts';
import {
convertFromGqlMeta,
@@ -14,7 +14,7 @@ import {
requestUpdateMangaMetadata,
requestUpdateServerMetadata,
} from '@/util/metadata';
-import { MangaType, MetaType } from '@/lib/graphql/generated/graphql.ts';
+import { MetaType } from '@/lib/graphql/generated/graphql.ts';
type UndefinedReaderSettings = {
[setting in keyof IReaderSettings]: IReaderSettings[setting] | undefined;
@@ -103,7 +103,7 @@ export const checkAndHandleMissingStoredReaderSettings = async (
}
if (metadataHolderType === 'manga') {
- await requestUpdateMangaMetadata(metadataHolder as MangaType, settingsToUpdate);
+ await requestUpdateMangaMetadata(metadataHolder as TManga, settingsToUpdate);
return;
}