Replace "useCategorySelect" with "GlobalDialogManager"
This commit is contained in:
@@ -37,8 +37,8 @@ import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
|||||||
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
import { getErrorMessage } from '@/lib/HelperFunctions.ts';
|
||||||
|
|
||||||
type BaseProps = {
|
type BaseProps = {
|
||||||
open: boolean;
|
onCancel: () => void;
|
||||||
onClose: (didUpdateCategories: boolean, addToCategories?: number[], removeFromCategories?: number[]) => void;
|
onConfirm: (selectedCategories: { addToCategories?: number[]; removeFromCategories?: number[] }) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SingleMangaModeProps = {
|
type SingleMangaModeProps = {
|
||||||
@@ -94,7 +94,7 @@ const getCategoryCheckedState = (
|
|||||||
export function CategorySelect(props: CategorySelectProps) {
|
export function CategorySelect(props: CategorySelectProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const { open, onClose, mangaId, mangaIds: passedMangaIds, addToLibrary = false } = props;
|
const { onCancel, onConfirm, mangaId, mangaIds: passedMangaIds, addToLibrary = false } = props;
|
||||||
|
|
||||||
const isSingleSelectionMode = mangaId !== undefined;
|
const isSingleSelectionMode = mangaId !== undefined;
|
||||||
const mangaIds = passedMangaIds ?? [mangaId];
|
const mangaIds = passedMangaIds ?? [mangaId];
|
||||||
@@ -137,7 +137,7 @@ export function CategorySelect(props: CategorySelectProps) {
|
|||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
setSelectionForKey('categoriesToAdd', mangaCategoryIds);
|
setSelectionForKey('categoriesToAdd', mangaCategoryIds);
|
||||||
setSelectionForKey('categoriesToRemove', []);
|
setSelectionForKey('categoriesToRemove', []);
|
||||||
onClose(false);
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
@@ -148,7 +148,10 @@ export function CategorySelect(props: CategorySelectProps) {
|
|||||||
? mangaCategoryIds.filter((categoryId) => !categoriesToAdd.includes(categoryId))
|
? mangaCategoryIds.filter((categoryId) => !categoriesToAdd.includes(categoryId))
|
||||||
: categoriesToRemove;
|
: categoriesToRemove;
|
||||||
|
|
||||||
onClose(true, addToCategories, removeFromCategories);
|
onConfirm({
|
||||||
|
addToCategories,
|
||||||
|
removeFromCategories,
|
||||||
|
});
|
||||||
|
|
||||||
if (doNotShowAddToLibraryDialogAgain) {
|
if (doNotShowAddToLibraryDialogAgain) {
|
||||||
updateMetadataServerSettings('showAddToLibraryCategorySelectDialog', false).catch((e) =>
|
updateMetadataServerSettings('showAddToLibraryCategorySelectDialog', false).catch((e) =>
|
||||||
@@ -183,7 +186,7 @@ export function CategorySelect(props: CategorySelectProps) {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
maxWidth="xs"
|
maxWidth="xs"
|
||||||
open={open}
|
open
|
||||||
onClose={handleCancel}
|
onClose={handleCancel}
|
||||||
>
|
>
|
||||||
<DialogTitle>{t('category.title.set_categories')}</DialogTitle>
|
<DialogTitle>{t('category.title.set_categories')}</DialogTitle>
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 { useMemo, useState } from 'react';
|
|
||||||
import { CategorySelect, CategorySelectProps } from '@/features/category/components/CategorySelect.tsx';
|
|
||||||
|
|
||||||
export const useCategorySelect = ({
|
|
||||||
mangaId,
|
|
||||||
mangaIds,
|
|
||||||
onClose,
|
|
||||||
addToLibrary,
|
|
||||||
}: Omit<CategorySelectProps, 'open' | 'onClose'> & Pick<Partial<CategorySelectProps>, 'onClose'>) => {
|
|
||||||
const [isCategorySelectOpen, setIsCategorySelectOpen] = useState(false);
|
|
||||||
|
|
||||||
const CategorySelectComponent = useMemo(() => {
|
|
||||||
if (!isCategorySelectOpen) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CategorySelect
|
|
||||||
open={isCategorySelectOpen}
|
|
||||||
onClose={(...args) => {
|
|
||||||
setIsCategorySelectOpen(false);
|
|
||||||
onClose?.(...args);
|
|
||||||
}}
|
|
||||||
mangaId={mangaId!} // either mangaId or mangaIds is undefined, however, ts is not able to infer it correctly and raises an error
|
|
||||||
mangaIds={mangaIds as undefined}
|
|
||||||
addToLibrary={addToLibrary}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}, [mangaId, mangaIds, addToLibrary, onClose, isCategorySelectOpen]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
openCategorySelect: setIsCategorySelectOpen,
|
|
||||||
CategorySelectComponent,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -29,17 +29,16 @@ import {
|
|||||||
} from '@/base/components/menu/Menu.utils.ts';
|
} from '@/base/components/menu/Menu.utils.ts';
|
||||||
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
import { defaultPromiseErrorHandler } from '@/lib/DefaultPromiseErrorHandler.ts';
|
||||||
import { TrackManga } from '@/features/tracker/components/TrackManga.tsx';
|
import { TrackManga } from '@/features/tracker/components/TrackManga.tsx';
|
||||||
import { useCategorySelect } from '@/features/category/hooks/useCategorySelect.tsx';
|
|
||||||
import { ChaptersDownloadActionMenuItems } from '@/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx';
|
import { ChaptersDownloadActionMenuItems } from '@/features/chapter/components/actions/ChaptersDownloadActionMenuItems.tsx';
|
||||||
import { NestedMenuItem } from '@/base/components/menu/NestedMenuItem.tsx';
|
import { NestedMenuItem } from '@/base/components/menu/NestedMenuItem.tsx';
|
||||||
import { MangaChapterStatFieldsFragment, MangaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MangaChapterStatFieldsFragment, MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { MangaAction, MangaDownloadInfo, MangaIdInfo, MangaUnreadInfo } from '@/features/manga/Manga.types.ts';
|
import { MangaAction, MangaDownloadInfo, MangaIdInfo, MangaUnreadInfo } from '@/features/manga/Manga.types.ts';
|
||||||
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 { GlobalDialogManager } from '@/base/global-dialog/GlobalDialogManager.tsx';
|
||||||
|
import { CategorySelect } from '@/features/category/components/CategorySelect.tsx';
|
||||||
|
|
||||||
const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const;
|
type BaseProps = { onClose: () => void; setHideMenu: (hide: boolean) => void };
|
||||||
|
|
||||||
type BaseProps = { onClose: (selectionModeState: boolean) => void; setHideMenu: (hide: boolean) => void };
|
|
||||||
|
|
||||||
export type SingleModeProps = {
|
export type SingleModeProps = {
|
||||||
manga: Pick<MangaType, 'id' | 'title' | 'sourceId'> & MangaDownloadInfo & MangaUnreadInfo;
|
manga: Pick<MangaType, 'id' | 'title' | 'sourceId'> & MangaDownloadInfo & MangaUnreadInfo;
|
||||||
@@ -77,16 +76,9 @@ export const MangaActionMenuItems = ({
|
|||||||
const hasUnreadChapters = !!manga?.unreadCount;
|
const hasUnreadChapters = !!manga?.unreadCount;
|
||||||
const hasReadChapters = !!manga && manga.unreadCount !== manga.chapters.totalCount;
|
const hasReadChapters = !!manga && manga.unreadCount !== manga.chapters.totalCount;
|
||||||
|
|
||||||
const { openCategorySelect, CategorySelectComponent } = useCategorySelect({
|
|
||||||
mangaId: manga?.id,
|
|
||||||
mangaIds: passedSelectedMangas ? Mangas.getIds(selectedMangas) : undefined,
|
|
||||||
onClose: () => onClose(true),
|
|
||||||
addToLibrary: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleSelect = () => {
|
const handleSelect = () => {
|
||||||
handleSelection?.(manga.id, true);
|
handleSelection?.(manga.id, true);
|
||||||
onClose(true);
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const performAction = (action: MangaAction, mangas: MangaIdInfo[]) => {
|
const performAction = (action: MangaAction, mangas: MangaIdInfo[]) => {
|
||||||
@@ -94,7 +86,7 @@ export const MangaActionMenuItems = ({
|
|||||||
wasManuallyMarkedAsRead: true,
|
wasManuallyMarkedAsRead: true,
|
||||||
}).catch(defaultPromiseErrorHandler(`MangaActionMenuItems:performAction(${action})`));
|
}).catch(defaultPromiseErrorHandler(`MangaActionMenuItems:performAction(${action})`));
|
||||||
|
|
||||||
onClose(!ACTION_DISABLES_SELECTION_MODE.includes(action));
|
onClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
const { downloadableMangas, downloadedMangas, unreadMangas, readMangas } = useMemo(
|
const { downloadableMangas, downloadedMangas, unreadMangas, readMangas } = useMemo(
|
||||||
@@ -127,7 +119,7 @@ export const MangaActionMenuItems = ({
|
|||||||
>
|
>
|
||||||
<ChaptersDownloadActionMenuItems
|
<ChaptersDownloadActionMenuItems
|
||||||
mangaIds={isSingleMode ? [manga.id] : Mangas.getIds(selectedMangas)}
|
mangaIds={isSingleMode ? [manga.id] : Mangas.getIds(selectedMangas)}
|
||||||
closeMenu={() => onClose(true)}
|
closeMenu={onClose}
|
||||||
/>
|
/>
|
||||||
</NestedMenuItem>
|
</NestedMenuItem>
|
||||||
)}
|
)}
|
||||||
@@ -176,8 +168,13 @@ export const MangaActionMenuItems = ({
|
|||||||
)}
|
)}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openCategorySelect(true);
|
GlobalDialogManager.show(CategorySelect, {
|
||||||
|
mangaId: manga?.id,
|
||||||
|
mangaIds: passedSelectedMangas ? Mangas.getIds(selectedMangas) : undefined,
|
||||||
|
addToLibrary: false,
|
||||||
|
});
|
||||||
setHideMenu(true);
|
setHideMenu(true);
|
||||||
|
onClose();
|
||||||
}}
|
}}
|
||||||
Icon={Label}
|
Icon={Label}
|
||||||
title={getMenuItemTitle('change_categories', selectedMangas.length)}
|
title={getMenuItemTitle('change_categories', selectedMangas.length)}
|
||||||
@@ -187,7 +184,6 @@ export const MangaActionMenuItems = ({
|
|||||||
Icon={FavoriteBorderIcon}
|
Icon={FavoriteBorderIcon}
|
||||||
title={getMenuItemTitle('remove_from_library', selectedMangas.length)}
|
title={getMenuItemTitle('remove_from_library', selectedMangas.length)}
|
||||||
/>
|
/>
|
||||||
{CategorySelectComponent}
|
|
||||||
{isTrackDialogOpen && (
|
{isTrackDialogOpen && (
|
||||||
<Dialog
|
<Dialog
|
||||||
open
|
open
|
||||||
@@ -196,7 +192,7 @@ export const MangaActionMenuItems = ({
|
|||||||
scroll="paper"
|
scroll="paper"
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setIsTrackDialogOpen(false);
|
setIsTrackDialogOpen(false);
|
||||||
onClose(true);
|
onClose();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TrackManga manga={manga!} />
|
<TrackManga manga={manga!} />
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ import SyncAltIcon from '@mui/icons-material/SyncAlt';
|
|||||||
import { useTheme } from '@mui/material/styles';
|
import { useTheme } from '@mui/material/styles';
|
||||||
import useMediaQuery from '@mui/material/useMediaQuery';
|
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||||
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
import { CustomTooltip } from '@/base/components/CustomTooltip.tsx';
|
||||||
import { useCategorySelect } from '@/features/category/hooks/useCategorySelect.tsx';
|
|
||||||
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MangaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
import { AppRoutes } from '@/base/AppRoute.constants.ts';
|
||||||
|
import { GlobalDialogManager } from '@/base/global-dialog/GlobalDialogManager.tsx';
|
||||||
|
import { CategorySelect } from '@/features/category/components/CategorySelect.tsx';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
manga: Pick<MangaType, 'id' | 'inLibrary' | 'sourceId' | 'title'>;
|
manga: Pick<MangaType, 'id' | 'inLibrary' | 'sourceId' | 'title'>;
|
||||||
@@ -43,9 +44,9 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
|||||||
setAnchorEl(null);
|
setAnchorEl(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { openCategorySelect, CategorySelectComponent } = useCategorySelect({
|
const openCategorySelection = () => {
|
||||||
mangaId: manga.id,
|
GlobalDialogManager.show(CategorySelect, { mangaId: manga.id });
|
||||||
});
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -82,7 +83,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
|||||||
<CustomTooltip title={t('manga.label.edit_categories')}>
|
<CustomTooltip title={t('manga.label.edit_categories')}>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openCategorySelect(true);
|
openCategorySelection();
|
||||||
}}
|
}}
|
||||||
color="inherit"
|
color="inherit"
|
||||||
>
|
>
|
||||||
@@ -142,7 +143,7 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
key="categories"
|
key="categories"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openCategorySelect(true);
|
openCategorySelection();
|
||||||
handleClose();
|
handleClose();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -155,8 +156,6 @@ export const MangaToolbarMenu = ({ manga, onRefresh, refreshing }: IProps) => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{CategorySelectComponent}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -49,10 +49,7 @@ export const MangaCard = memo((props: MangaCardProps) => {
|
|||||||
settings: { showContinueReadingButton },
|
settings: { showContinueReadingButton },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const { CategorySelectComponent, updateLibraryState, isInLibrary } = useManageMangaLibraryState(
|
const { updateLibraryState, isInLibrary } = useManageMangaLibraryState(manga, mode === 'source');
|
||||||
manga,
|
|
||||||
mode === 'source',
|
|
||||||
);
|
|
||||||
|
|
||||||
const mangaLinkTo = getMangaLinkTo(mode, manga.id, manga.sourceId, manga.title);
|
const mangaLinkTo = getMangaLinkTo(mode, manga.id, manga.sourceId, manga.title);
|
||||||
|
|
||||||
@@ -158,7 +155,6 @@ export const MangaCard = memo((props: MangaCardProps) => {
|
|||||||
)}
|
)}
|
||||||
</Menu>
|
</Menu>
|
||||||
)}
|
)}
|
||||||
{CategorySelectComponent}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</PopupState>
|
</PopupState>
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ export const MangaDetails = ({
|
|||||||
}
|
}
|
||||||
}, [manga.source]);
|
}, [manga.source]);
|
||||||
|
|
||||||
const { CategorySelectComponent, updateLibraryState } = useManageMangaLibraryState(manga);
|
const { updateLibraryState } = useManageMangaLibraryState(manga);
|
||||||
|
|
||||||
const copyTitle = async () => {
|
const copyTitle = async () => {
|
||||||
try {
|
try {
|
||||||
@@ -239,59 +239,56 @@ export const MangaDetails = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<DetailsWrapper>
|
||||||
<DetailsWrapper>
|
<TopContentWrapper url={Mangas.getThumbnailUrl(manga)} mangaThumbnailBackdrop={mangaThumbnailBackdrop}>
|
||||||
<TopContentWrapper url={Mangas.getThumbnailUrl(manga)} mangaThumbnailBackdrop={mangaThumbnailBackdrop}>
|
<ThumbnailMetadataWrapper>
|
||||||
<ThumbnailMetadataWrapper>
|
<Thumbnail manga={manga} mangaDynamicColorSchemes={mangaDynamicColorSchemes} />
|
||||||
<Thumbnail manga={manga} mangaDynamicColorSchemes={mangaDynamicColorSchemes} />
|
<MetadataContainer>
|
||||||
<MetadataContainer>
|
<Stack sx={{ flexDirection: 'row', gap: 1, alignItems: 'flex-start', mb: 1 }}>
|
||||||
<Stack sx={{ flexDirection: 'row', gap: 1, alignItems: 'flex-start', mb: 1 }}>
|
<SearchLink query={manga.title} sourceId={manga.sourceId} mode="source.global-search">
|
||||||
<SearchLink query={manga.title} sourceId={manga.sourceId} mode="source.global-search">
|
<Typography variant="h5" component="h2" sx={{ wordBreak: 'break-word' }}>
|
||||||
<Typography variant="h5" component="h2" sx={{ wordBreak: 'break-word' }}>
|
{manga.title}
|
||||||
{manga.title}
|
</Typography>
|
||||||
</Typography>
|
</SearchLink>
|
||||||
</SearchLink>
|
<CustomTooltip title={t('global.button.copy')}>
|
||||||
<CustomTooltip title={t('global.button.copy')}>
|
<IconButton onClick={copyTitle} color="inherit">
|
||||||
<IconButton onClick={copyTitle} color="inherit">
|
<ContentCopyIcon fontSize="small" />
|
||||||
<ContentCopyIcon fontSize="small" />
|
</IconButton>
|
||||||
</IconButton>
|
</CustomTooltip>
|
||||||
</CustomTooltip>
|
</Stack>
|
||||||
</Stack>
|
{manga.author && (
|
||||||
{manga.author && (
|
|
||||||
<Metadata
|
|
||||||
title={t('manga.label.author')}
|
|
||||||
value={valuesToJoinedSearchLinks(Mangas.getAuthors(manga), manga.source?.id, mode)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{manga.artist && (
|
|
||||||
<Metadata
|
|
||||||
title={t('manga.label.artist')}
|
|
||||||
value={valuesToJoinedSearchLinks(Mangas.getArtists(manga), manga.source?.id, mode)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<Metadata
|
<Metadata
|
||||||
title={t('manga.label.status')}
|
title={t('manga.label.author')}
|
||||||
value={t(MANGA_STATUS_TO_TRANSLATION[manga.status])}
|
value={valuesToJoinedSearchLinks(Mangas.getAuthors(manga), manga.source?.id, mode)}
|
||||||
/>
|
/>
|
||||||
<Metadata title={t('source.title_one')} value={getSourceName(manga.source)} />
|
)}
|
||||||
</MetadataContainer>
|
{manga.artist && (
|
||||||
</ThumbnailMetadataWrapper>
|
<Metadata
|
||||||
<MangaButtonsContainer>
|
title={t('manga.label.artist')}
|
||||||
<CustomButton
|
value={valuesToJoinedSearchLinks(Mangas.getArtists(manga), manga.source?.id, mode)}
|
||||||
size="medium"
|
/>
|
||||||
onClick={updateLibraryState}
|
)}
|
||||||
variant={manga.inLibrary ? 'contained' : 'outlined'}
|
<Metadata
|
||||||
>
|
title={t('manga.label.status')}
|
||||||
{manga.inLibrary ? <FavoriteIcon /> : <FavoriteBorderIcon />}
|
value={t(MANGA_STATUS_TO_TRANSLATION[manga.status])}
|
||||||
{manga.inLibrary ? t('manga.button.in_library') : t('manga.button.add_to_library')}
|
/>
|
||||||
</CustomButton>
|
<Metadata title={t('source.title_one')} value={getSourceName(manga.source)} />
|
||||||
<TrackMangaButton manga={manga} />
|
</MetadataContainer>
|
||||||
<OpenSourceButton url={manga.realUrl} />
|
</ThumbnailMetadataWrapper>
|
||||||
</MangaButtonsContainer>
|
<MangaButtonsContainer>
|
||||||
</TopContentWrapper>
|
<CustomButton
|
||||||
<DescriptionGenre manga={manga} mode={mode} />
|
size="medium"
|
||||||
</DetailsWrapper>
|
onClick={updateLibraryState}
|
||||||
{CategorySelectComponent}
|
variant={manga.inLibrary ? 'contained' : 'outlined'}
|
||||||
</>
|
>
|
||||||
|
{manga.inLibrary ? <FavoriteIcon /> : <FavoriteBorderIcon />}
|
||||||
|
{manga.inLibrary ? t('manga.button.in_library') : t('manga.button.add_to_library')}
|
||||||
|
</CustomButton>
|
||||||
|
<TrackMangaButton manga={manga} />
|
||||||
|
<OpenSourceButton url={manga.realUrl} />
|
||||||
|
</MangaButtonsContainer>
|
||||||
|
</TopContentWrapper>
|
||||||
|
<DescriptionGenre manga={manga} mode={mode} />
|
||||||
|
</DetailsWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import { useCallback, useState } from 'react';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import gql from 'graphql-tag';
|
import gql from 'graphql-tag';
|
||||||
import { useCategorySelect } from '@/features/category/hooks/useCategorySelect.tsx';
|
|
||||||
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
import { requestManager } from '@/lib/requests/RequestManager.ts';
|
||||||
import { makeToast } from '@/base/utils/Toast.ts';
|
import { makeToast } from '@/base/utils/Toast.ts';
|
||||||
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
import { getMetadataServerSettings } from '@/features/settings/services/ServerSettingsMetadata.ts';
|
||||||
@@ -22,6 +21,7 @@ import { GET_CATEGORIES_BASE } from '@/lib/graphql/queries/CategoryQuery.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 { GlobalDialogManager } from '@/base/global-dialog/GlobalDialogManager.tsx';
|
import { GlobalDialogManager } from '@/base/global-dialog/GlobalDialogManager.tsx';
|
||||||
|
import { CategorySelect } from '@/features/category/components/CategorySelect';
|
||||||
|
|
||||||
export const useManageMangaLibraryState = (
|
export const useManageMangaLibraryState = (
|
||||||
manga: Pick<MangaType, 'id' | 'title'> & Partial<Pick<MangaType, 'inLibrary'>>,
|
manga: Pick<MangaType, 'id' | 'title'> & Partial<Pick<MangaType, 'inLibrary'>>,
|
||||||
@@ -33,11 +33,7 @@ export const useManageMangaLibraryState = (
|
|||||||
const [isInLibrary, setIsInLibrary] = useState(!!manga.inLibrary);
|
const [isInLibrary, setIsInLibrary] = useState(!!manga.inLibrary);
|
||||||
|
|
||||||
const addToLibrary = useCallback(
|
const addToLibrary = useCallback(
|
||||||
(didSubmit: boolean, addToCategories: number[] = [], removeFromCategories: number[] = []) => {
|
(addToCategories: number[] = [], removeFromCategories: number[] = []) => {
|
||||||
if (!didSubmit) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestManager
|
requestManager
|
||||||
.updateManga(manga.id, {
|
.updateManga(manga.id, {
|
||||||
updateManga: { inLibrary: true },
|
updateManga: { inLibrary: true },
|
||||||
@@ -67,12 +63,6 @@ export const useManageMangaLibraryState = (
|
|||||||
setIsInLibrary(false);
|
setIsInLibrary(false);
|
||||||
}, [manga.id, confirmRemoval]);
|
}, [manga.id, confirmRemoval]);
|
||||||
|
|
||||||
const { openCategorySelect, CategorySelectComponent } = useCategorySelect({
|
|
||||||
mangaId: manga.id,
|
|
||||||
addToLibrary: true,
|
|
||||||
onClose: addToLibrary,
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateLibraryState = useCallback(() => {
|
const updateLibraryState = useCallback(() => {
|
||||||
const update = async () => {
|
const update = async () => {
|
||||||
if (isInLibrary) {
|
if (isInLibrary) {
|
||||||
@@ -144,18 +134,26 @@ export const useManageMangaLibraryState = (
|
|||||||
|
|
||||||
const showCategorySelectDialog = showAddToLibraryCategorySelectDialog && !!userCreatedCategories.length;
|
const showCategorySelectDialog = showAddToLibraryCategorySelectDialog && !!userCreatedCategories.length;
|
||||||
if (!showCategorySelectDialog) {
|
if (!showCategorySelectDialog) {
|
||||||
addToLibrary(true, Categories.getIds(Categories.getDefaults(userCreatedCategories!)));
|
addToLibrary(Categories.getIds(Categories.getDefaults(userCreatedCategories!)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openCategorySelect(true);
|
const { addToCategories, removeFromCategories } = await GlobalDialogManager.show(
|
||||||
|
`manga-library-state-add-categories-${manga.id}`,
|
||||||
|
CategorySelect,
|
||||||
|
{
|
||||||
|
mangaId: manga.id,
|
||||||
|
addToLibrary: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
addToLibrary(addToCategories, removeFromCategories);
|
||||||
};
|
};
|
||||||
|
|
||||||
update().catch(defaultPromiseErrorHandler('useManageMangaLibraryState::updateLibraryState'));
|
update().catch(defaultPromiseErrorHandler('useManageMangaLibraryState::updateLibraryState'));
|
||||||
}, [isInLibrary, removeFromLibrary, addToLibrary]);
|
}, [isInLibrary, removeFromLibrary, addToLibrary]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
CategorySelectComponent,
|
|
||||||
updateLibraryState,
|
updateLibraryState,
|
||||||
/**
|
/**
|
||||||
* In case of browsing the source, the data has to be fetched via a mutation.
|
* In case of browsing the source, the data has to be fetched via a mutation.
|
||||||
|
|||||||
@@ -28,22 +28,15 @@ export const ReaderLibraryButton = memo(() => {
|
|||||||
const { inLibrary } = manga ?? ACTION_FALLBACK_MANGA;
|
const { inLibrary } = manga ?? ACTION_FALLBACK_MANGA;
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { CategorySelectComponent, updateLibraryState } = useManageMangaLibraryState(
|
const { updateLibraryState } = useManageMangaLibraryState(manga ?? ACTION_FALLBACK_MANGA, true);
|
||||||
manga ?? ACTION_FALLBACK_MANGA,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<CustomTooltip
|
||||||
<CustomTooltip
|
title={inLibrary ? t('manga.action.library.remove.label.action') : t('manga.button.add_to_library')}
|
||||||
title={inLibrary ? t('manga.action.library.remove.label.action') : t('manga.button.add_to_library')}
|
>
|
||||||
>
|
<IconButton onClick={updateLibraryState} color="inherit">
|
||||||
<IconButton onClick={updateLibraryState} color="inherit">
|
{inLibrary ? <FavoriteIcon /> : <FavoriteBorderIcon />}
|
||||||
{inLibrary ? <FavoriteIcon /> : <FavoriteBorderIcon />}
|
</IconButton>
|
||||||
</IconButton>
|
</CustomTooltip>
|
||||||
</CustomTooltip>
|
|
||||||
|
|
||||||
{CategorySelectComponent}
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user