import type { DriveFileInfo } from "@/lib/api/types" import { isOnlyOfficeFile } from "@/lib/drive/onlyoffice-formats" export type DrivePreviewKind = "image" | "video" | "audio" | "pdf" | "text" const IMAGE_EXT = new Set([ "jpg", "jpeg", "png", "gif", "webp", "svg", "bmp", "avif", "heic", "heif", "ico", "tif", "tiff", "apng", "jfif", ]) const VIDEO_EXT = new Set(["mp4", "webm", "mov", "mkv", "ogv", "m4v", "3gp", "avi"]) const AUDIO_EXT = new Set(["mp3", "wav", "ogg", "flac", "m4a", "aac", "opus", "weba", "aiff", "mid", "midi"]) const TEXT_EXT = new Set([ "md", "markdown", "txt", "json", "yaml", "yml", "log", "ini", "conf", "cfg", "env", ]) function isTextMime(mime: string): boolean { if (!mime.startsWith("text/")) return false if (mime.includes("html") || mime.includes("calendar")) return false return true } function fileExt(name: string): string { return name.split(".").pop()?.toLowerCase() ?? "" } export function isSvgFile(file: { name: string; mime_type?: string }): boolean { const mime = (file.mime_type ?? "").toLowerCase() return mime === "image/svg+xml" || mime === "application/svg+xml" || fileExt(file.name) === "svg" } /** Formats the browser renders from the original file — skip Nextcloud raster preview. */ export function driveClientNativePreview(file: { name: string mime_type?: string type?: string }): boolean { if (file.type === "directory") return false const kind = drivePreviewKind(file) if (!kind) return false if (kind === "video" || kind === "audio" || kind === "pdf" || kind === "text") return true if (kind === "image" && isSvgFile(file)) return true return false } export function isOfficeFormat(file: { name: string; mime_type?: string }): boolean { return isOnlyOfficeFile(file) } /** Open in OnlyOffice when supported, except native preview types (image, video, PDF). */ export function shouldOpenInOnlyOffice(file: { name: string mime_type?: string type?: string }): boolean { if (file.type === "directory") return false if (drivePreviewKind(file)) return false return isOfficeFormat(file) } export function drivePreviewKind(file: { name: string mime_type?: string }): DrivePreviewKind | null { const mime = (file.mime_type ?? "").toLowerCase() if (mime.startsWith("image/") || mime === "application/svg+xml") return "image" if (mime.startsWith("video/")) return "video" if (mime.startsWith("audio/")) return "audio" if (mime === "application/pdf") return "pdf" if (isTextMime(mime)) return "text" if (mime === "application/json" || mime === "application/x-yaml") return "text" const ext = fileExt(file.name) if (IMAGE_EXT.has(ext)) return "image" if (VIDEO_EXT.has(ext)) return "video" if (AUDIO_EXT.has(ext)) return "audio" if (ext === "pdf") return "pdf" if (TEXT_EXT.has(ext)) return "text" return null } /** Files that can use Nextcloud server-side preview thumbnails. */ export function driveServerThumbnail(file: { name: string; mime_type?: string; type?: string }): boolean { if (file.type === "directory") return false if (isOfficeFormat(file)) return true const kind = drivePreviewKind(file) if (kind === "pdf") return true if (kind === "image" && !isSvgFile(file)) return true return false } export function isPreviewNavigable(file: { name: string mime_type?: string type?: string }): boolean { return file.type !== "directory" && drivePreviewKind(file) !== null } export function previewTargetToFileInfo(target: { path: string name: string mime_type: string is_favorite: boolean }): DriveFileInfo { return { path: target.path, name: target.name, type: "file", size: 0, mime_type: target.mime_type, last_modified: "", etag: "", is_favorite: target.is_favorite, } } export function toPreviewTarget(file: { path: string name: string mime_type?: string is_favorite?: boolean }): { path: string; name: string; mime_type: string; is_favorite: boolean } { return { path: file.path, name: file.name, mime_type: file.mime_type ?? "", is_favorite: file.is_favorite ?? false, } }