"use client"; import * as React from "react"; import { AnimatePresence, motion } from "framer-motion"; import { IconCheck, IconCloudUpload, IconExternalLink, IconFile, IconFileTypePdf, IconPhoto, IconX } from "@tabler/icons-react"; import type { ColineFilePreview, ColineUploadedFile } from "@colineapp/sdk/v2"; import { cn } from "../lib/utils"; import { staggerDelay, transitions } from "../lib/motion"; import { useColine } from "../provider"; import { Button } from "./button"; import { Spinner } from "./spinner"; function FileTypeIcon({ mimeType }: { mimeType: string | null | undefined }) { if (mimeType?.startsWith("image/")) return ; if (mimeType === "application/pdf") return ; return ; } /** * Any readable workspace file, previewed: images and video inline, other * files as a card that opens them in Coline. Uses the viewer's access; * apps preview each other's files without integrations. */ export function FilePreview({ fileId, variant = "card", className, }: { fileId: string; variant?: "inline" | "card" | "full"; className?: string; }) { const coline = useColine(); // Keyed by file so a new fileId shows the skeleton, not the last file. const [loaded, setLoaded] = React.useState<{ fileId: string; preview: ColineFilePreview | null; error: string | null } | null>( null, ); React.useEffect(() => { let cancelled = false; coline.files .preview(fileId) .then((result) => { if (!cancelled) setLoaded({ fileId, preview: result, error: null }); }) .catch((cause: unknown) => { if (!cancelled) setLoaded({ fileId, preview: null, error: cause instanceof Error ? cause.message : String(cause) }); }); return () => { cancelled = true; }; }, [coline, fileId]); const current = loaded?.fileId === fileId ? loaded : null; const preview = current?.preview ?? null; const error = current?.error ?? null; const open = () => void coline.navigation.openFile(fileId); if (error) { return (
Preview unavailable
); } if (!preview) { return
; } const media = preview.media; if (variant !== "inline" && media?.mimeType?.startsWith("image/")) { return ( {preview.name} {preview.name} ); } if (variant !== "inline" && media?.mimeType?.startsWith("video/")) { return (