Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced turbopack alias for canvas in next.config.mjs. - Updated package.json scripts for development and branding tasks. - Added new dependencies for Tiptap extensions. - Implemented new demo layouts for agenda, contacts, drive, and mail applications. - Enhanced globals.css for improved theming and splash screen animations. - Added OAuth callback handling for drive mounts. - Updated layout components to integrate new demo shells and improve structure.
88 lines
3.2 KiB
TypeScript
88 lines
3.2 KiB
TypeScript
"use client"
|
|
|
|
import { useQuery } from "@tanstack/react-query"
|
|
import { fetchDrivePreviewBlob, fetchDriveServerPreview, blobForPreview } from "@/lib/api/drive-download"
|
|
import { commitPreviewBlobUrl } from "@/lib/api/preview-blob-url"
|
|
import { useAuthReady } from "@/lib/api/use-auth-ready"
|
|
import type { DriveFileInfo } from "@/lib/api/types"
|
|
import { DEMO_DRIVE_QUERY_ROOT } from "@/lib/demo/demo-drive-bootstrap"
|
|
import { resolveDemoDrivePreview } from "@/lib/demo/demo-drive-preview"
|
|
import { useIsDemoDrive } from "@/lib/demo/demo-drive-context"
|
|
import { drivePreviewKind, driveServerThumbnail } from "@/lib/drive/drive-preview"
|
|
|
|
export type DriveThumbDisplay = "image" | "video"
|
|
|
|
export type DrivePreviewThumb = {
|
|
url: string
|
|
display: DriveThumbDisplay
|
|
}
|
|
|
|
export function useDrivePreviewThumb(file: DriveFileInfo, enabled: boolean) {
|
|
const { ready, authenticated } = useAuthReady()
|
|
const isDemoDrive = useIsDemoDrive()
|
|
const clientKind = drivePreviewKind(file)
|
|
const canPreview =
|
|
file.type === "file" &&
|
|
clientKind !== "audio" &&
|
|
(driveServerThumbnail(file) || clientKind !== null)
|
|
|
|
return useQuery({
|
|
queryKey: isDemoDrive
|
|
? [...DEMO_DRIVE_QUERY_ROOT, "preview-thumb", file.path, file.etag]
|
|
: ["drive", "preview-thumb", file.path, file.etag],
|
|
enabled: ready && authenticated && enabled && canPreview,
|
|
queryFn: async ({ client, queryKey }): Promise<DrivePreviewThumb> => {
|
|
const previous = client.getQueryData<DrivePreviewThumb>(queryKey)
|
|
|
|
if (isDemoDrive) {
|
|
const resolved = resolveDemoDrivePreview(file, { width: 400, height: 300 })
|
|
if (!resolved || resolved.type === "text") {
|
|
throw new Error("preview unavailable")
|
|
}
|
|
if (resolved.type === "svg") {
|
|
const blob = new Blob([resolved.markup], { type: "image/svg+xml" })
|
|
return commitPreviewBlobUrl(previous, {
|
|
url: URL.createObjectURL(blob),
|
|
display: "image",
|
|
})
|
|
}
|
|
return { url: resolved.url, display: resolved.display }
|
|
}
|
|
|
|
if (driveServerThumbnail(file)) {
|
|
try {
|
|
const raw = await fetchDriveServerPreview(file, 400, 300)
|
|
const blob = blobForPreview(raw, file.mime_type ?? "", file.name)
|
|
return commitPreviewBlobUrl(previous, {
|
|
url: URL.createObjectURL(blob),
|
|
display: "image",
|
|
})
|
|
} catch (err) {
|
|
// PDF / bureautique : pas de repli client (<img> ne lit pas le binaire).
|
|
if (!clientKind || clientKind === "audio" || clientKind === "pdf") {
|
|
throw err
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!clientKind || clientKind === "audio" || clientKind === "pdf") {
|
|
throw new Error("preview unavailable")
|
|
}
|
|
|
|
const blob = await fetchDrivePreviewBlob({
|
|
path: file.path,
|
|
name: file.name,
|
|
mime_type: file.mime_type ?? "",
|
|
})
|
|
const previewBlob = blobForPreview(blob, file.mime_type ?? "", file.name)
|
|
return commitPreviewBlobUrl(previous, {
|
|
url: URL.createObjectURL(previewBlob),
|
|
display: clientKind === "video" ? "video" : "image",
|
|
})
|
|
},
|
|
staleTime: 5 * 60_000,
|
|
gcTime: 10 * 60_000,
|
|
retry: 1,
|
|
})
|
|
}
|