/* * 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 CheckBoxOutlineBlank from '@mui/icons-material/CheckBoxOutlineBlank'; import Delete from '@mui/icons-material/Delete'; import Download from '@mui/icons-material/Download'; import RemoveDone from '@mui/icons-material/RemoveDone'; import Done from '@mui/icons-material/Done'; import { useTranslation } from 'react-i18next'; import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder'; import Label from '@mui/icons-material/Label'; import { useMemo, useState } from 'react'; import { TManga } from '@/typings.ts'; import { actionToTranslationKey, MangaAction, MangaDownloadInfo, Mangas, MangaUnreadInfo } from '@/lib/data/Mangas.ts'; import { SelectableCollectionReturnType } from '@/components/collection/useSelectableCollection.ts'; import { CategorySelect } from '@/components/navbar/action/CategorySelect.tsx'; import { MenuItem } from '@/components/menu/MenuItem.tsx'; import { createGetMenuItemTitle, createIsMenuItemDisabled, createShouldShowMenuItem } from '@/components/menu/util.ts'; const ACTION_DISABLES_SELECTION_MODE: MangaAction[] = ['remove_from_library'] as const; type BaseProps = { onClose: (selectionModeState: boolean) => void; setHideMenu: (hide: boolean) => void }; export type SingleModeProps = { manga: Pick & MangaDownloadInfo & MangaUnreadInfo; handleSelection?: SelectableCollectionReturnType['handleSelection']; }; type SelectModeProps = { selectedMangas: TManga[]; }; type Props = | (BaseProps & SingleModeProps & PropertiesNever) | (BaseProps & PropertiesNever & SelectModeProps); export const MangaActionMenuItems = ({ manga, handleSelection, selectedMangas = [], onClose, setHideMenu }: Props) => { const { t } = useTranslation(); const [isCategorySelectOpen, setIsCategorySelectOpen] = useState(false); const isSingleMode = !!manga; const getMenuItemTitle = createGetMenuItemTitle(isSingleMode, actionToTranslationKey); const shouldShowMenuItem = createShouldShowMenuItem(isSingleMode); const isMenuItemDisabled = createIsMenuItemDisabled(isSingleMode); const isFullyDownloaded = !!manga && manga.downloadCount === manga.chapters.totalCount; const hasDownloadedChapters = !!manga?.downloadCount; const hasUnreadChapters = !!manga?.unreadCount; const hasReadChapters = !!manga && manga.unreadCount !== manga.chapters.totalCount; const handleSelect = () => { handleSelection?.(manga.id, true); onClose(true); }; const performAction = (action: MangaAction, mangas: TManga[]) => { Mangas.performAction(action, manga ? [manga.id] : Mangas.getIds(mangas), { wasManuallyMarkedAsRead: true, }).catch(() => {}); onClose(!ACTION_DISABLES_SELECTION_MODE.includes(action)); }; const { downloadableMangas, downloadedMangas, unreadMangas, readMangas } = useMemo( () => ({ downloadableMangas: [ ...Mangas.getNotDownloaded(selectedMangas), ...Mangas.getPartiallyDownloaded(selectedMangas), ], downloadedMangas: [ ...Mangas.getPartiallyDownloaded(selectedMangas), ...Mangas.getFullyDownloaded(selectedMangas), ], unreadMangas: [...Mangas.getUnread(selectedMangas), ...Mangas.getPartiallyRead(selectedMangas)], readMangas: [...Mangas.getPartiallyRead(selectedMangas), ...Mangas.getFullyRead(selectedMangas)], }), [selectedMangas], ); return ( <> {!!handleSelection && isSingleMode && ( )} {shouldShowMenuItem(!isFullyDownloaded) && ( performAction('download', downloadableMangas)} title={getMenuItemTitle('download', downloadableMangas.length)} /> )} {shouldShowMenuItem(hasDownloadedChapters) && ( performAction('delete', downloadedMangas)} title={getMenuItemTitle('delete', downloadedMangas.length)} /> )} {shouldShowMenuItem(hasUnreadChapters) && ( performAction('mark_as_read', unreadMangas)} title={getMenuItemTitle('mark_as_read', unreadMangas.length)} /> )} {shouldShowMenuItem(hasReadChapters) && ( performAction('mark_as_unread', readMangas)} title={getMenuItemTitle('mark_as_unread', readMangas.length)} /> )} { setIsCategorySelectOpen(true); setHideMenu(true); }} Icon={Label} title={getMenuItemTitle('change_categories', selectedMangas.length)} /> performAction('remove_from_library', selectedMangas)} Icon={FavoriteBorderIcon} title={getMenuItemTitle('remove_from_library', selectedMangas.length)} /> {isCategorySelectOpen && ( { setIsCategorySelectOpen(false); onClose(true); }} mangaId={manga?.id as undefined} // either mangaId or mangaIds is undefined, however, ts is not able to infer it correctly and raises an error mangaIds={Mangas.getIds(selectedMangas)} /> )} ); };