/* * 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 BookmarkIcon from '@mui/icons-material/Bookmark'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import CardActionArea from '@mui/material/CardActionArea'; import Checkbox from '@mui/material/Checkbox'; import Stack from '@mui/material/Stack'; import Card from '@mui/material/Card'; import CardContent from '@mui/material/CardContent'; import IconButton from '@mui/material/IconButton'; import { useTheme } from '@mui/material/styles'; import React, { memo, MouseEvent, TouchEvent, useRef } from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import PopupState, { bindMenu, bindTrigger } from 'material-ui-popup-state'; import { useLongPress } from 'use-long-press'; import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { getDateString } from '@/util/DateHelper.ts'; import { DownloadStateIndicator } from '@/modules/core/components/DownloadStateIndicator.tsx'; import { ChapterType } from '@/lib/graphql/generated/graphql.ts'; import { ChapterActionMenuItems } from '@/modules/chapter/components/actions/ChapterActionMenuItems.tsx'; import { Menu } from '@/modules/core/components/menu/Menu.tsx'; import { ChapterBookmarkInfo, ChapterDownloadInfo, ChapterIdInfo, ChapterMangaInfo, ChapterNumberInfo, ChapterReadInfo, Chapters, ChapterScanlatorInfo, } from '@/modules/chapter/services/Chapters.ts'; import { applyStyles } from '@/modules/core/utils/ApplyStyles.ts'; import { ChapterCardMetadata } from '@/modules/chapter/components/cards/ChapterCardMetadata.tsx'; import { MUIUtil } from '@/lib/mui/MUI.util.ts'; type TChapter = ChapterIdInfo & ChapterMangaInfo & ChapterDownloadInfo & ChapterReadInfo & ChapterBookmarkInfo & ChapterNumberInfo & ChapterScanlatorInfo & Pick; interface IProps { mode?: 'manga.page' | 'reader'; chapter: TChapter; showChapterNumber: boolean; onSelect: (id: number, selected: boolean, isShiftKey?: boolean) => void; selected: boolean | null; selectable?: boolean; isActiveChapter?: boolean; // reader } export const ChapterCard = memo((props: IProps) => { const { t } = useTranslation(); const theme = useTheme(); const menuButtonRef = useRef(null); const { mode = 'manga.page', chapter, showChapterNumber, onSelect, selected, selectable = true, isActiveChapter = false, } = props; const isSelecting = selected !== null; const { isDownloaded } = chapter; const handleClick = (event: MouseEvent | TouchEvent) => { if (!isSelecting) return; event.preventDefault(); event.stopPropagation(); onSelect(chapter.id, !selected, event.shiftKey); }; const handleClickOpenMenu = ( event: React.MouseEvent | React.TouchEvent, openMenu?: (e: React.SyntheticEvent) => void, ) => { event.stopPropagation(); event.preventDefault(); openMenu?.(event); }; const longPressBind = useLongPress((event, { context: openMenu }) => { if (!isSelecting && !!menuButtonRef.current) { handleClickOpenMenu(event, () => (openMenu as (event: Element) => void)?.(menuButtonRef.current!)); return; } // eslint-disable-next-line no-param-reassign event.shiftKey = true; handleClick(event); }); return ( {(popupState) => ( handleClick(e)} {...longPressBind(popupState.open)} > ) } slotProps={{ title: { variant: 'h6', component: 'h3', sx: applyStyles(mode === 'reader' && isActiveChapter, { color: theme.palette.primary.contrastText, }), }, secondaryText: { sx: applyStyles(mode === 'reader' && isActiveChapter, { color: theme.palette.primary.contrastText, }), }, ternaryText: { sx: applyStyles(mode === 'reader' && isActiveChapter, { color: theme.palette.primary.contrastText, }), }, }} /> {selected === null ? ( handleClickOpenMenu(e), })} aria-label="more" sx={{ color: 'inherit', ...applyStyles(mode === 'reader' && isActiveChapter, { color: 'primary.contrastText', }), }} > ) : ( )} {!isSelecting && popupState.isOpen && ( {(onClose) => ( onSelect(chapter.id, true)} canBeDownloaded={Chapters.isDownloadable(chapter)} selectable={selectable} /> )} )} )} ); });