Use stable array/object constants
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import type { Ref } from 'react';
|
import type { Ref } from 'react';
|
||||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
|
import { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
@@ -61,7 +62,7 @@ export const SpinnerImage = ({ ref, ...props }: SpinnerImageProps) => {
|
|||||||
alt,
|
alt,
|
||||||
onLoad,
|
onLoad,
|
||||||
onError,
|
onError,
|
||||||
spinnerStyle: { small, ...spinnerStyle } = {},
|
spinnerStyle: { small, ...spinnerStyle } = STABLE_EMPTY_OBJECT,
|
||||||
imgStyle,
|
imgStyle,
|
||||||
hideImgStyle,
|
hideImgStyle,
|
||||||
priority,
|
priority,
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ import Box from '@mui/material/Box';
|
|||||||
import type { CircularProgressProps } from '@mui/material/CircularProgress';
|
import type { CircularProgressProps } from '@mui/material/CircularProgress';
|
||||||
import CircularProgress from '@mui/material/CircularProgress';
|
import CircularProgress from '@mui/material/CircularProgress';
|
||||||
import Typography from '@mui/material/Typography';
|
import Typography from '@mui/material/Typography';
|
||||||
|
import { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const Progress = ({
|
export const Progress = ({
|
||||||
progress,
|
progress,
|
||||||
showText = true,
|
showText = true,
|
||||||
progressProps = {},
|
progressProps = STABLE_EMPTY_OBJECT,
|
||||||
}: {
|
}: {
|
||||||
progress: number;
|
progress: number;
|
||||||
showText?: boolean;
|
showText?: boolean;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
* with a few changes to fix a bug on mobile devices where opening the sub menu immediately triggered the on click of the underlying menu item
|
* with a few changes to fix a bug on mobile devices where opening the sub menu immediately triggered the on click of the underlying menu item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
import type { MenuProps as MuiMenuProps } from '@mui/material/Menu';
|
import type { MenuProps as MuiMenuProps } from '@mui/material/Menu';
|
||||||
import Menu from '@mui/material/Menu';
|
import Menu from '@mui/material/Menu';
|
||||||
import type { MenuItemProps as MuiMenuItemProps } from '@mui/material/MenuItem';
|
import type { MenuItemProps as MuiMenuItemProps } from '@mui/material/MenuItem';
|
||||||
@@ -64,7 +65,7 @@ export const NestedMenuItem = ({ ref, ...props }: NestedMenuItemProps) => {
|
|||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
tabIndex: tabIndexProp,
|
tabIndex: tabIndexProp,
|
||||||
ContainerProps: ContainerPropsProp = {},
|
ContainerProps: ContainerPropsProp = STABLE_EMPTY_OBJECT,
|
||||||
MenuProps,
|
MenuProps,
|
||||||
...MenuItemProps
|
...MenuItemProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import type { RefObject } from 'react';
|
import type { RefObject } from 'react';
|
||||||
import { useLayoutEffect, useState } from 'react';
|
import { useLayoutEffect, useState } from 'react';
|
||||||
|
import { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const useIntersectionObserver = (
|
export const useIntersectionObserver = (
|
||||||
ref: RefObject<HTMLElement | null> | HTMLElement | undefined | null,
|
ref: RefObject<HTMLElement | null> | HTMLElement | undefined | null,
|
||||||
@@ -17,7 +18,7 @@ export const useIntersectionObserver = (
|
|||||||
root,
|
root,
|
||||||
rootMargin,
|
rootMargin,
|
||||||
threshold,
|
threshold,
|
||||||
}: IntersectionObserverInit & { ignoreInitialObserve?: boolean } = {},
|
}: IntersectionObserverInit & { ignoreInitialObserve?: boolean } = STABLE_EMPTY_OBJECT,
|
||||||
): (() => void) => {
|
): (() => void) => {
|
||||||
const [disconnect, setDisconnect] = useState<() => void>(() => {});
|
const [disconnect, setDisconnect] = useState<() => void>(() => {});
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
|||||||
import { makeToast } from '@/base/utils/Toast.ts';
|
import { makeToast } from '@/base/utils/Toast.ts';
|
||||||
import { ChapterListCard } from '@/features/chapter/components/cards/ChapterListCard.tsx';
|
import { ChapterListCard } from '@/features/chapter/components/cards/ChapterListCard.tsx';
|
||||||
import { VirtuosoPersisted } from '@/lib/virtuoso/Component/VirtuosoPersisted.tsx';
|
import { VirtuosoPersisted } from '@/lib/virtuoso/Component/VirtuosoPersisted.tsx';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
type ChapterListHeaderProps = {
|
type ChapterListHeaderProps = {
|
||||||
scrollbarWidth: number;
|
scrollbarWidth: number;
|
||||||
@@ -140,7 +141,7 @@ export const ChapterList = ({
|
|||||||
manga.id,
|
manga.id,
|
||||||
{ notifyOnNetworkStatusChange: true },
|
{ notifyOnNetworkStatusChange: true },
|
||||||
);
|
);
|
||||||
const chapters = useMemo(() => chaptersData?.chapters.nodes ?? [], [chaptersData?.chapters.nodes]);
|
const chapters = chaptersData?.chapters.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const visibleChapters = useMemo(() => filterAndSortChapters(chapters, options), [chapters, options]);
|
const visibleChapters = useMemo(() => filterAndSortChapters(chapters, options), [chapters, options]);
|
||||||
const visibleChapterIds = useMemo(() => Chapters.getIds(visibleChapters), [visibleChapters]);
|
const visibleChapterIds = useMemo(() => Chapters.getIds(visibleChapters), [visibleChapters]);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* 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 { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
import CheckBoxOutlineBlank from '@mui/icons-material/CheckBoxOutlineBlank';
|
import CheckBoxOutlineBlank from '@mui/icons-material/CheckBoxOutlineBlank';
|
||||||
import Delete from '@mui/icons-material/Delete';
|
import Delete from '@mui/icons-material/Delete';
|
||||||
import Download from '@mui/icons-material/Download';
|
import Download from '@mui/icons-material/Download';
|
||||||
@@ -71,7 +72,7 @@ export const ChapterActionMenuItems = ({
|
|||||||
chapter,
|
chapter,
|
||||||
handleSelection,
|
handleSelection,
|
||||||
canBeDownloaded = false,
|
canBeDownloaded = false,
|
||||||
selectedChapters = [],
|
selectedChapters = STABLE_EMPTY_ARRAY,
|
||||||
onClose,
|
onClose,
|
||||||
selectable = true,
|
selectable = true,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
|||||||
import { useAppAction } from '@/features/navigation-bar/hooks/useAppAction.ts';
|
import { useAppAction } from '@/features/navigation-bar/hooks/useAppAction.ts';
|
||||||
import type { ChapterDownloadStatus } from '@/features/chapter/Chapter.types.ts';
|
import type { ChapterDownloadStatus } from '@/features/chapter/Chapter.types.ts';
|
||||||
import { VirtuosoPersisted } from '@/lib/virtuoso/Component/VirtuosoPersisted.tsx';
|
import { VirtuosoPersisted } from '@/lib/virtuoso/Component/VirtuosoPersisted.tsx';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const DownloadQueue: React.FC = () => {
|
export const DownloadQueue: React.FC = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@@ -49,7 +50,7 @@ export const DownloadQueue: React.FC = () => {
|
|||||||
} = requestManager.useGetDownloadStatus({ notifyOnNetworkStatusChange: true });
|
} = requestManager.useGetDownloadStatus({ notifyOnNetworkStatusChange: true });
|
||||||
const downloaderData = downloadStatusData?.downloadStatus;
|
const downloaderData = downloadStatusData?.downloadStatus;
|
||||||
|
|
||||||
const queue = downloaderData?.queue ?? [];
|
const queue = downloaderData?.queue ?? STABLE_EMPTY_ARRAY;
|
||||||
const status = downloaderData?.state ?? DownloaderState.Started;
|
const status = downloaderData?.state ?? DownloaderState.Started;
|
||||||
const isQueueEmpty = !queue.length;
|
const isQueueEmpty = !queue.length;
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { AppbarSearch } from '@/base/components/AppbarSearch.tsx';
|
|||||||
import { useDebounce } from '@/base/hooks/useDebounce.ts';
|
import { useDebounce } from '@/base/hooks/useDebounce.ts';
|
||||||
import type { MangaCardProps } from '@/features/manga/Manga.types.ts';
|
import type { MangaCardProps } from '@/features/manga/Manga.types.ts';
|
||||||
import { EmptyView } from '@/base/components/feedback/EmptyView.tsx';
|
import { EmptyView } from '@/base/components/feedback/EmptyView.tsx';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
import { LoadingPlaceholder } from '@/base/components/feedback/LoadingPlaceholder.tsx';
|
||||||
import { BaseMangaGrid } from '@/features/manga/components/BaseMangaGrid.tsx';
|
import { BaseMangaGrid } from '@/features/manga/components/BaseMangaGrid.tsx';
|
||||||
@@ -254,7 +255,7 @@ export const SearchAll: React.FC = () => {
|
|||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const { data, loading, error, refetch } = requestManager.useGetSourceList({ notifyOnNetworkStatusChange: true });
|
const { data, loading, error, refetch } = requestManager.useGetSourceList({ notifyOnNetworkStatusChange: true });
|
||||||
const sources = useMemo(() => data?.sources.nodes ?? [], [data?.sources.nodes]);
|
const sources = data?.sources.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const [sourceToLoadingStateMap, setSourceToLoadingStateMap] = useState<SourceToLoadingStateMap>(new Map());
|
const [sourceToLoadingStateMap, setSourceToLoadingStateMap] = useState<SourceToLoadingStateMap>(new Map());
|
||||||
const debouncedSourceToLoadingStateMap = useDebounce(sourceToLoadingStateMap, 500);
|
const debouncedSourceToLoadingStateMap = useDebounce(sourceToLoadingStateMap, 500);
|
||||||
@@ -304,7 +305,7 @@ export const SearchAll: React.FC = () => {
|
|||||||
selectedLanguages={shownLangs}
|
selectedLanguages={shownLangs}
|
||||||
setSelectedLanguages={setShownLangs}
|
setSelectedLanguages={setShownLangs}
|
||||||
languages={sourceLanguages}
|
languages={sourceLanguages}
|
||||||
sources={sources ?? []}
|
sources={sources}
|
||||||
/>
|
/>
|
||||||
</>,
|
</>,
|
||||||
[shownLangs, setShownLangs, sourceLanguages, sources],
|
[shownLangs, setShownLangs, sourceLanguages, sources],
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
|||||||
import { ChapterHistoryCard } from '@/features/history/components/ChapterHistoryCard.tsx';
|
import { ChapterHistoryCard } from '@/features/history/components/ChapterHistoryCard.tsx';
|
||||||
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
||||||
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const History: React.FC = () => {
|
export const History: React.FC = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@@ -39,7 +40,7 @@ export const History: React.FC = () => {
|
|||||||
});
|
});
|
||||||
const hasNextPage = !!chapterHistoryData?.chapters.pageInfo.hasNextPage;
|
const hasNextPage = !!chapterHistoryData?.chapters.pageInfo.hasNextPage;
|
||||||
const endCursor = chapterHistoryData?.chapters.pageInfo.endCursor;
|
const endCursor = chapterHistoryData?.chapters.pageInfo.endCursor;
|
||||||
const readEntries = chapterHistoryData?.chapters.nodes ?? [];
|
const readEntries = chapterHistoryData?.chapters.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
const groupedHistory = useMemo(
|
const groupedHistory = useMemo(
|
||||||
() => Object.entries(Chapters.groupByDate(readEntries, 'lastReadAt')),
|
() => Object.entries(Chapters.groupByDate(readEntries, 'lastReadAt')),
|
||||||
[readEntries],
|
[readEntries],
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
|||||||
import { useAppAction } from '@/features/navigation-bar/hooks/useAppAction.ts';
|
import { useAppAction } from '@/features/navigation-bar/hooks/useAppAction.ts';
|
||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
import { SearchParam } from '@/base/Base.types.ts';
|
import { SearchParam } from '@/base/Base.types.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
const TitleWithSizeTag = styled('span')({
|
const TitleWithSizeTag = styled('span')({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@@ -82,7 +83,7 @@ export function Library() {
|
|||||||
const tabsData = categoriesResponse?.categories.nodes.filter(
|
const tabsData = categoriesResponse?.categories.nodes.filter(
|
||||||
(category) => category.id !== 0 || (category.id === 0 && category.mangas.totalCount),
|
(category) => category.id !== 0 || (category.id === 0 && category.mangas.totalCount),
|
||||||
);
|
);
|
||||||
const tabs = tabsData ?? [];
|
const tabs = tabsData ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const librarySizeResponse = requestManager.useGetMangas<
|
const librarySizeResponse = requestManager.useGetMangas<
|
||||||
GetLibraryMangaCountQuery,
|
GetLibraryMangaCountQuery,
|
||||||
@@ -102,7 +103,7 @@ export function Library() {
|
|||||||
loading: mangaLoading,
|
loading: mangaLoading,
|
||||||
refetch: refetchCategoryMangas,
|
refetch: refetchCategoryMangas,
|
||||||
} = requestManager.useGetCategoryMangas(activeTab?.id, { skip: !activeTab, notifyOnNetworkStatusChange: true });
|
} = requestManager.useGetCategoryMangas(activeTab?.id, { skip: !activeTab, notifyOnNetworkStatusChange: true });
|
||||||
const categoryMangas = categoryMangaResponse?.mangas.nodes ?? [];
|
const categoryMangas = categoryMangaResponse?.mangas.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
const {
|
const {
|
||||||
visibleMangas: mangas,
|
visibleMangas: mangas,
|
||||||
showFilteredOutMessage,
|
showFilteredOutMessage,
|
||||||
@@ -127,6 +128,7 @@ export function Library() {
|
|||||||
} = useSelectableCollection<MangaType['id'], string>(mangas.length, {
|
} = useSelectableCollection<MangaType['id'], string>(mangas.length, {
|
||||||
itemIds: mangaIds,
|
itemIds: mangaIds,
|
||||||
currentKey: activeTab?.id.toString(),
|
currentKey: activeTab?.id.toString(),
|
||||||
|
initialState: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleSelect: typeof handleSelection = useCallback(
|
const handleSelect: typeof handleSelection = useCallback(
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import type { MangaAction, MangaDownloadInfo, MangaIdInfo, MangaUnreadInfo } fro
|
|||||||
import { MANGA_ACTION_TO_TRANSLATION } from '@/features/manga/Manga.constants.ts';
|
import { MANGA_ACTION_TO_TRANSLATION } from '@/features/manga/Manga.constants.ts';
|
||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
import { CategorySelect } from '@/features/category/components/CategorySelect.tsx';
|
import { CategorySelect } from '@/features/category/components/CategorySelect.tsx';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
type BaseProps = { onClose: () => void; setHideMenu: (hide: boolean) => void };
|
type BaseProps = { onClose: () => void; setHideMenu: (hide: boolean) => void };
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ export const MangaActionMenuItems = ({
|
|||||||
const [isTrackDialogOpen, setIsTrackDialogOpen] = useState(false);
|
const [isTrackDialogOpen, setIsTrackDialogOpen] = useState(false);
|
||||||
|
|
||||||
const isSingleMode = !!manga;
|
const isSingleMode = !!manga;
|
||||||
const selectedMangas = passedSelectedMangas ?? [];
|
const selectedMangas = passedSelectedMangas ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const getMenuItemTitle = createGetMenuItemTitle(isSingleMode, MANGA_ACTION_TO_TRANSLATION);
|
const getMenuItemTitle = createGetMenuItemTitle(isSingleMode, MANGA_ACTION_TO_TRANSLATION);
|
||||||
const shouldShowMenuItem = createShouldShowMenuItem(isSingleMode);
|
const shouldShowMenuItem = createShouldShowMenuItem(isSingleMode);
|
||||||
|
|||||||
@@ -9,8 +9,9 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
||||||
import type { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
import type { NavbarContextType } from '@/features/navigation-bar/NavigationBar.types.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const useAppAction = (action: NavbarContextType['action'], dependencies: any[] = []) => {
|
export const useAppAction = (action: NavbarContextType['action'], dependencies: any[] = STABLE_EMPTY_ARRAY) => {
|
||||||
const { setAction } = useNavBarContext();
|
const { setAction } = useNavBarContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* 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 { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import MenuItem from '@mui/material/MenuItem';
|
import MenuItem from '@mui/material/MenuItem';
|
||||||
@@ -32,7 +33,7 @@ const BaseReaderNavBarDesktopChapterNavigation = ({
|
|||||||
currentChapterNumber,
|
currentChapterNumber,
|
||||||
previousChapter,
|
previousChapter,
|
||||||
nextChapter,
|
nextChapter,
|
||||||
chapters = [],
|
chapters = STABLE_EMPTY_ARRAY,
|
||||||
readerThemeDirection,
|
readerThemeDirection,
|
||||||
}: {
|
}: {
|
||||||
currentChapterId: ChapterIdInfo['id'] | undefined;
|
currentChapterId: ChapterIdInfo['id'] | undefined;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
* 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 { STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
import FilterListIcon from '@mui/icons-material/FilterList';
|
import FilterListIcon from '@mui/icons-material/FilterList';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
import Stack from '@mui/material/Stack';
|
import Stack from '@mui/material/Stack';
|
||||||
@@ -159,7 +160,7 @@ export function Options({ sourceFilter, group, updateFilterValue, update }: IFil
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function SourceOptions({
|
export function SourceOptions({
|
||||||
savedSearches = {},
|
savedSearches = STABLE_EMPTY_OBJECT,
|
||||||
selectSavedSearch,
|
selectSavedSearch,
|
||||||
updateSavedSearches,
|
updateSavedSearches,
|
||||||
sourceFilter,
|
sourceFilter,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ import { GridLayout, SearchParam } from '@/base/Base.types';
|
|||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { Sources } from '@/features/source/services/Sources.ts';
|
import { Sources } from '@/features/source/services/Sources.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY, STABLE_EMPTY_OBJECT } from '@/base/Base.constants.ts';
|
||||||
import { useAppTitleAndAction } from '@/features/navigation-bar/hooks/useAppTitleAndAction.ts';
|
import { useAppTitleAndAction } from '@/features/navigation-bar/hooks/useAppTitleAndAction.ts';
|
||||||
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
||||||
import { VirtuosoUtil } from '@/lib/virtuoso/Virtuoso.util.tsx';
|
import { VirtuosoUtil } from '@/lib/virtuoso/Virtuoso.util.tsx';
|
||||||
@@ -219,7 +220,7 @@ export function SourceMangas() {
|
|||||||
useLocation<{
|
useLocation<{
|
||||||
contentType: SourceContentType;
|
contentType: SourceContentType;
|
||||||
clearCache: boolean;
|
clearCache: boolean;
|
||||||
}>().state ?? {};
|
}>().state ?? STABLE_EMPTY_OBJECT;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
settings: { hideLibraryEntries },
|
settings: { hideLibraryEntries },
|
||||||
@@ -288,7 +289,7 @@ export function SourceMangas() {
|
|||||||
{ data, error, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage },
|
{ data, error, isLoading: loading, size: lastPageNum, abortRequest, filteredOutAllItemsOfFetchedPage },
|
||||||
] = useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries);
|
] = useSourceManga(sourceId, contentType, query, filtersToApply, 1, hideLibraryEntries);
|
||||||
currentAbortRequest.current = abortRequest;
|
currentAbortRequest.current = abortRequest;
|
||||||
const mangas = data?.fetchSourceManga?.mangas ?? [];
|
const mangas = data?.fetchSourceManga?.mangas ?? STABLE_EMPTY_ARRAY;
|
||||||
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
|
const hasNextPage = !!data?.fetchSourceManga?.hasNextPage;
|
||||||
const isLoading = loading || (filteredOutAllItemsOfFetchedPage && hasNextPage);
|
const isLoading = loading || (filteredOutAllItemsOfFetchedPage && hasNextPage);
|
||||||
const { data: sourceData } = requestManager.useGetSource<GetSourceBrowseQuery, GetSourceBrowseQueryVariables>(
|
const { data: sourceData } = requestManager.useGetSource<GetSourceBrowseQuery, GetSourceBrowseQueryVariables>(
|
||||||
@@ -297,7 +298,7 @@ export function SourceMangas() {
|
|||||||
);
|
);
|
||||||
const source = sourceData?.source;
|
const source = sourceData?.source;
|
||||||
|
|
||||||
const filters = source?.filters ?? [];
|
const filters = source?.filters ?? STABLE_EMPTY_ARRAY;
|
||||||
const { savedSearches = {} } = useGetSourceMetadata(source ?? DEFAULT_SOURCE);
|
const { savedSearches = {} } = useGetSourceMetadata(source ?? DEFAULT_SOURCE);
|
||||||
const updateSourceMetadata = createUpdateSourceMetadata<'savedSearches'>(source ?? { id: '-1' }, (e) =>
|
const updateSourceMetadata = createUpdateSourceMetadata<'savedSearches'>(source ?? { id: '-1' }, (e) =>
|
||||||
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)),
|
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { makeToast } from '@/base/utils/Toast.ts';
|
|||||||
import type { PreferenceProps } from '@/features/source/Source.types.ts';
|
import type { PreferenceProps } from '@/features/source/Source.types.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
function getPrefComponent(type: string) {
|
function getPrefComponent(type: string) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -58,7 +59,7 @@ export function SourceConfigure() {
|
|||||||
>(GET_SOURCE_SETTINGS, sourceId, {
|
>(GET_SOURCE_SETTINGS, sourceId, {
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
});
|
});
|
||||||
const sourcePreferences = data?.source.preferences ?? [];
|
const sourcePreferences = data?.source.preferences ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const updateValue =
|
const updateValue =
|
||||||
(position: number): PreferenceProps['updateValue'] =>
|
(position: number): PreferenceProps['updateValue'] =>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import type { MangaIdInfo } from '@/features/manga/Manga.types.ts';
|
|||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { EmptyView } from '@/base/components/feedback/EmptyView.tsx';
|
import { EmptyView } from '@/base/components/feedback/EmptyView.tsx';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracker?: number): TrackerMode => {
|
const getTrackerMode = (id: number, trackersInUse: number[], searchModeForTracker?: number): TrackerMode => {
|
||||||
if (id === searchModeForTracker) {
|
if (id === searchModeForTracker) {
|
||||||
@@ -46,13 +47,13 @@ export const TrackManga = ({ manga }: { manga: MangaIdInfo & Pick<MangaType, 'ti
|
|||||||
const trackerList = requestManager.useGetTrackerList<GetTrackersBindQuery>(GET_TRACKERS_BIND, {
|
const trackerList = requestManager.useGetTrackerList<GetTrackersBindQuery>(GET_TRACKERS_BIND, {
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
});
|
});
|
||||||
const trackers = trackerList.data?.trackers.nodes ?? [];
|
const trackers = trackerList.data?.trackers.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const mangaTrackRecordsList = requestManager.useGetManga<GetMangaTrackRecordsQuery>(
|
const mangaTrackRecordsList = requestManager.useGetManga<GetMangaTrackRecordsQuery>(
|
||||||
GET_MANGA_TRACK_RECORDS,
|
GET_MANGA_TRACK_RECORDS,
|
||||||
manga.id,
|
manga.id,
|
||||||
);
|
);
|
||||||
const mangaTrackRecords = mangaTrackRecordsList.data?.manga.trackRecords.nodes ?? [];
|
const mangaTrackRecords = mangaTrackRecordsList.data?.manga.trackRecords.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const loggedInTrackers = Trackers.getLoggedIn(trackers);
|
const loggedInTrackers = Trackers.getLoggedIn(trackers);
|
||||||
const trackersInUse = Trackers.getLoggedIn(Trackers.getTrackers(mangaTrackRecords, trackers));
|
const trackersInUse = Trackers.getLoggedIn(Trackers.getTrackers(mangaTrackRecords, trackers));
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import type { GetTrackersSettingsQuery } from '@/lib/graphql/generated/graphql.t
|
|||||||
import type { MetadataTrackingSettings } from '@/features/tracker/Tracker.types.ts';
|
import type { MetadataTrackingSettings } from '@/features/tracker/Tracker.types.ts';
|
||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
import { useAppTitle } from '@/features/navigation-bar/hooks/useAppTitle.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const TrackingSettings = () => {
|
export const TrackingSettings = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@@ -50,7 +51,7 @@ export const TrackingSettings = () => {
|
|||||||
} = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS, {
|
} = requestManager.useGetTrackerList<GetTrackersSettingsQuery>(GET_TRACKERS_SETTINGS, {
|
||||||
notifyOnNetworkStatusChange: true,
|
notifyOnNetworkStatusChange: true,
|
||||||
});
|
});
|
||||||
const trackers = data?.trackers.nodes ?? [];
|
const trackers = data?.trackers.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
|
|
||||||
const loading = areMetadataServerSettingsLoading || areTrackersLoading;
|
const loading = areMetadataServerSettingsLoading || areTrackersLoading;
|
||||||
const error = metadataServerSettingsError ?? trackersError;
|
const error = metadataServerSettingsError ?? trackersError;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import { useNavBarContext } from '@/features/navigation-bar/NavbarContext.tsx';
|
|||||||
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
import { Chapters } from '@/features/chapter/services/Chapters.ts';
|
||||||
import { useAppTitleAndAction } from '@/features/navigation-bar/hooks/useAppTitleAndAction.ts';
|
import { useAppTitleAndAction } from '@/features/navigation-bar/hooks/useAppTitleAndAction.ts';
|
||||||
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/lib/virtuoso/Virtuoso.constants.ts';
|
import { GROUPED_VIRTUOSO_Z_INDEX } from '@/lib/virtuoso/Virtuoso.constants.ts';
|
||||||
|
import { STABLE_EMPTY_ARRAY } from '@/base/Base.constants.ts';
|
||||||
|
|
||||||
export const Updates: React.FC = () => {
|
export const Updates: React.FC = () => {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
@@ -42,7 +43,7 @@ export const Updates: React.FC = () => {
|
|||||||
});
|
});
|
||||||
const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage;
|
const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage;
|
||||||
const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;
|
const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;
|
||||||
const updateEntries = chapterUpdateData?.chapters.nodes ?? [];
|
const updateEntries = chapterUpdateData?.chapters.nodes ?? STABLE_EMPTY_ARRAY;
|
||||||
const groupedUpdates = useMemo(
|
const groupedUpdates = useMemo(
|
||||||
() => Object.entries(Chapters.groupByDate(updateEntries, 'fetchedAt')),
|
() => Object.entries(Chapters.groupByDate(updateEntries, 'fetchedAt')),
|
||||||
[updateEntries],
|
[updateEntries],
|
||||||
|
|||||||
Reference in New Issue
Block a user