import { WebApplication } from '@/UIModels/Application' import { concatenateUint8Arrays } from '@/Utils/ConcatenateUint8Arrays' import { DialogContent, DialogOverlay } from '@reach/dialog' import { SNFile } from '@standardnotes/snjs' import { NoPreviewIllustration } from '@standardnotes/stylekit' import { FunctionComponent } from 'preact' import { useCallback, useEffect, useRef, useState } from 'preact/hooks' import { getFileIconComponent } from '@/Components/AttachedFilesPopover/PopoverFileItem' import { Button } from '@/Components/Button/Button' import { Icon } from '@/Components/Icon' import { FilePreviewInfoPanel } from './FilePreviewInfoPanel' import { isFileTypePreviewable } from './isFilePreviewable' import { PreviewComponent } from './PreviewComponent' type Props = { application: WebApplication file: SNFile onDismiss: () => void } export const FilePreviewModal: FunctionComponent = ({ application, file, onDismiss }) => { const [objectUrl, setObjectUrl] = useState() const [isFilePreviewable, setIsFilePreviewable] = useState(false) const [isLoadingFile, setIsLoadingFile] = useState(false) const [showFileInfoPanel, setShowFileInfoPanel] = useState(false) const closeButtonRef = useRef(null) const getObjectUrl = useCallback(async () => { setIsLoadingFile(true) try { const chunks: Uint8Array[] = [] await application.files.downloadFile(file, async (decryptedChunk: Uint8Array) => { chunks.push(decryptedChunk) }) const finalDecryptedBytes = concatenateUint8Arrays(chunks) setObjectUrl( URL.createObjectURL( new Blob([finalDecryptedBytes], { type: file.mimeType, }), ), ) } catch (error) { console.error(error) } finally { setIsLoadingFile(false) } }, [application.files, file]) useEffect(() => { const isPreviewable = isFileTypePreviewable(file.mimeType) setIsFilePreviewable(isPreviewable) if (!objectUrl && isPreviewable) { getObjectUrl().catch(console.error) } return () => { if (objectUrl) { URL.revokeObjectURL(objectUrl) } } }, [file.mimeType, getObjectUrl, objectUrl]) return (
{getFileIconComponent( application.iconsController.getIconForFileType(file.mimeType), 'w-6 h-6 flex-shrink-0', )}
{file.name}
{objectUrl && ( )}
{objectUrl ? ( ) : isLoadingFile ? (
) : (
This file can't be previewed.
{isFilePreviewable ? ( <>
There was an error loading the file. Try again, or download the file and open it using another application.
) : ( <>
To view this file, download it and open it using another application.
)}
)}
{showFileInfoPanel && }
) }