import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import { Book } from '@/types/book'; import { BookMetadata } from '@/libs/document'; import { useEnv } from '@/context/EnvContext'; import { useSettingsStore } from '@/store/settingsStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useMetadataEdit } from './useMetadataEdit'; import { DeleteAction } from '@/types/system'; import Alert from '@/components/Alert'; import Dialog from '@/components/Dialog'; import Spinner from '@/components/Spinner'; import BookDetailView from './BookDetailView'; import BookDetailEdit from './BookDetailEdit'; import SourceSelector from './SourceSelector'; interface BookDetailModalProps { book: Book; isOpen: boolean; onClose: () => void; handleBookDownload?: (book: Book, redownload?: boolean) => void; handleBookUpload?: (book: Book) => void; handleBookDelete?: (book: Book) => void; handleBookDeleteCloudBackup?: (book: Book) => void; handleBookDeleteLocalCopy?: (book: Book) => void; handleBookMetadataUpdate?: (book: Book, updatedMetadata: BookMetadata) => void; } interface DeleteConfig { title: string; message: string; handler?: (book: Book) => void; } const BookDetailModal: React.FC = ({ book, isOpen, onClose, handleBookDownload, handleBookUpload, handleBookDelete, handleBookDeleteCloudBackup, handleBookDeleteLocalCopy, handleBookMetadataUpdate, }) => { const _ = useTranslation(); const [loading, setLoading] = useState(false); const [activeDeleteAction, setActiveDeleteAction] = useState(null); const [editMode, setEditMode] = useState(false); const [bookMeta, setBookMeta] = useState(null); const [fileSize, setFileSize] = useState(null); const { envConfig } = useEnv(); const { settings } = useSettingsStore(); // Initialize metadata edit hook const { editedMeta, fieldSources, lockedFields, fieldErrors, searchLoading, showSourceSelection, availableSources, handleFieldChange, handleToggleFieldLock, handleLockAll, handleUnlockAll, handleAutoRetrieve, handleSourceSelection, handleCloseSourceSelection, resetToOriginal, } = useMetadataEdit(bookMeta); const deleteConfigs: Record = { both: { title: _('Confirm Deletion'), message: _('Are you sure to delete the selected book?'), handler: handleBookDelete, }, cloud: { title: _('Confirm Deletion'), message: _('Are you sure to delete the cloud backup of the selected book?'), handler: handleBookDeleteCloudBackup, }, local: { title: _('Confirm Deletion'), message: _('Are you sure to delete the local copy of the selected book?'), handler: handleBookDeleteLocalCopy, }, }; useEffect(() => { const loadingTimeout = setTimeout(() => setLoading(true), 300); const fetchBookDetails = async () => { const appService = await envConfig.getAppService(); try { const details = book.metadata || (await appService.fetchBookDetails(book, settings)); setBookMeta(details); const size = await appService.getBookFileSize(book); setFileSize(size); } finally { if (loadingTimeout) clearTimeout(loadingTimeout); setLoading(false); } }; fetchBookDetails(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [book]); const handleClose = () => { setBookMeta(null); setEditMode(false); setActiveDeleteAction(null); onClose(); }; const handleEditMetadata = () => { setEditMode(true); }; const handleCancelEdit = () => { resetToOriginal(); setEditMode(false); }; const handleSaveMetadata = () => { if (editedMeta && handleBookMetadataUpdate) { setBookMeta({ ...editedMeta }); handleBookMetadataUpdate(book, editedMeta); setEditMode(false); } }; const handleDeleteAction = (action: DeleteAction) => { setActiveDeleteAction(action); }; const confirmDeleteAction = async () => { if (!activeDeleteAction) return; const config = deleteConfigs[activeDeleteAction]; handleClose(); if (config.handler) { config.handler(book); } }; const cancelDeleteAction = () => { setActiveDeleteAction(null); }; const handleDelete = () => handleDeleteAction('both'); const handleDeleteCloudBackup = () => handleDeleteAction('cloud'); const handleDeleteLocalCopy = () => handleDeleteAction('local'); const handleRedownload = async () => { handleClose(); if (handleBookDownload) { handleBookDownload(book, true); } }; const handleReupload = async () => { handleClose(); if (handleBookUpload) { handleBookUpload(book); } }; const currentDeleteConfig = activeDeleteAction ? deleteConfigs[activeDeleteAction] : null; if (!bookMeta) return ( loading && (
) ); return ( <>
{editMode ? ( ) : ( )}
{/* Source Selection Modal */} {activeDeleteAction && currentDeleteConfig && (
)}
); }; export default BookDetailModal;