ultisuite-client/lib/drive/drive-preview.ts
R3D347HR4Y 6ec95262af Add OnlyOffice integration and update project configurations
- Updated .env.example to include configuration for OnlyOffice Document Server.
- Modified the workspace configuration to remove the drive-suite path.
- Adjusted TypeScript environment imports for consistency.
- Enhanced Next.js configuration to disable canvas in Webpack.
- Updated package.json to include new dependencies for OnlyOffice and PDF.js.
- Added global styles for OnlyOffice theme integration in the CSS.
- Created new layout and page components for the Drive feature, including public sharing and editing functionalities.
- Updated metadata handling across various layouts to reflect the new app structure.
2026-06-07 15:49:21 +02:00

155 lines
4.1 KiB
TypeScript

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,
}
}