import React, { useCallback, useMemo, useState, } from 'react'; import { HasObjectId, IAttachment } from '@growi/core'; import { useSWRxAttachments } from '~/stores/attachment'; import { useIsGuestUser } from '~/stores/context'; import { useSWRxCurrentPage, useCurrentPageId } from '~/stores/page'; import { DeleteAttachmentModal } from './PageAttachment/DeleteAttachmentModal'; import { PageAttachmentList } from './PageAttachment/PageAttachmentList'; import PaginationWrapper from './PaginationWrapper'; // Utility const checkIfFileInUse = (markdown: string, attachment): boolean => { return markdown.indexOf(attachment._id) >= 0; }; const PageAttachment = (): JSX.Element => { const { data: currentPage } = useSWRxCurrentPage(); const markdown = currentPage?.revision.body; // Static SWRs const { data: pageId } = useCurrentPageId(); const { data: isGuestUser } = useIsGuestUser(); // States const [pageNumber, setPageNumber] = useState(1); const [attachmentToDelete, setAttachmentToDelete] = useState<(IAttachment & HasObjectId) | null>(null); const [deleting, setDeleting] = useState(false); const [deleteError, setDeleteError] = useState(''); // SWRs const { data: dataAttachments, remove } = useSWRxAttachments(pageId, pageNumber); // Custom hooks const inUseAttachmentsMap: { [id: string]: boolean } | undefined = useMemo(() => { if (markdown == null || dataAttachments == null) { return undefined; } const attachmentEntries = dataAttachments.attachments .map((attachment) => { return [attachment._id, checkIfFileInUse(markdown, attachment)]; }); return Object.fromEntries(attachmentEntries); }, [dataAttachments, markdown]); // Methods const onChangePageHandler = useCallback((newPageNumber: number) => { setPageNumber(newPageNumber); }, []); const onAttachmentDeleteClicked = useCallback((attachment) => { setAttachmentToDelete(attachment); }, []); const onAttachmentDeleteClickedConfirmHandler = useCallback(async(attachment: IAttachment & HasObjectId) => { setDeleting(true); try { await remove({ attachment_id: attachment._id }); setAttachmentToDelete(null); setDeleting(false); } catch { setDeleteError('Something went wrong.'); setDeleting(false); } }, [remove]); const onToggleHandler = useCallback(() => { setAttachmentToDelete(null); setDeleteError(''); }, []); // Renderers const renderPageAttachmentList = useCallback(() => { if (dataAttachments == null || inUseAttachmentsMap == null) { return (