import { useCallback, useMemo, useState, type KeyboardEvent } from 'react' import { convertFileSrc } from '@tauri-apps/api/core' import { ArrowSquareOut, FileDashed, ImageSquare, WarningCircle } from '@phosphor-icons/react' import type { VaultEntry } from '../types' import { isImagePreviewEntry, previewFileTypeLabel } from '../utils/filePreview' import { focusNoteListContainer } from '../utils/neighborhoodHistory' import { openLocalFile } from '../utils/url' import { Button } from './ui/button' interface FilePreviewProps { entry: VaultEntry } interface FilePreviewFallbackProps { icon: 'warning' | 'file' title: string description: string onOpenExternal: () => void } function FilePreviewFallback({ icon, title, description, onOpenExternal }: FilePreviewFallbackProps) { const Icon = icon === 'warning' ? WarningCircle : FileDashed return (
) } function FilePreviewHeader({ entry, isImage, fileTypeLabel, onOpenExternal, }: { entry: VaultEntry isImage: boolean fileTypeLabel: string onOpenExternal: () => void }) { const HeaderIcon = isImage ? ImageSquare : FileDashed return (
) } function FilePreviewImage({ entry, imageSrc, onImageError, }: { entry: VaultEntry imageSrc: string onImageError: () => void }) { return (
{entry.title}
) } function shouldRenderImagePreview(isImage: boolean, imageSrc: string | null, imageFailed: boolean): imageSrc is string { return isImage && imageSrc !== null && !imageFailed } function FilePreviewBody({ entry, isImage, imageSrc, imageFailed, onImageError, onOpenExternal, }: { entry: VaultEntry isImage: boolean imageSrc: string | null imageFailed: boolean onImageError: () => void onOpenExternal: () => void }) { if (shouldRenderImagePreview(isImage, imageSrc, imageFailed)) { return } return ( ) } export function FilePreview({ entry }: FilePreviewProps) { const [imageFailed, setImageFailed] = useState(false) const isImage = isImagePreviewEntry(entry) const imageSrc = useMemo(() => (isImage ? convertFileSrc(entry.path) : null), [entry.path, isImage]) const fileTypeLabel = previewFileTypeLabel(entry) const handleImageError = useCallback(() => setImageFailed(true), []) const handleOpenExternal = useCallback(() => { void openLocalFile(entry.path).catch((error) => { console.warn('Failed to open file with default app:', error) }) }, [entry.path]) const handleKeyDown = useCallback((event: KeyboardEvent) => { if (event.key !== 'Escape') return event.preventDefault() focusNoteListContainer(document) }, []) return (
) }