ultisuite-client/lib/drive/docs-graphic-draw-import.ts
R3D347HR4Y 303b2b1074
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
wow
2026-06-11 01:22:40 +02:00

86 lines
2.7 KiB
TypeScript

import { apiClient } from "@/lib/api/client"
import { fetchDrivePreviewBlob } from "@/lib/api/drive-download"
import type { DriveFileInfo } from "@/lib/api/types"
export async function resolveDriveDrawFileId(file: DriveFileInfo): Promise<string> {
let fileId = file.file_id
if (!fileId) {
const info = await apiClient.get<DriveFileInfo>(
`/drive/files/info${file.path.startsWith("/") ? file.path : `/${file.path}`}`
)
fileId = info.file_id
}
if (!fileId) {
throw new Error("Identifiant du dessin introuvable")
}
return String(fileId)
}
function readSvgDimensions(svg: SVGSVGElement): { width: number; height: number } {
const viewBox = svg.getAttribute("viewBox")
if (viewBox) {
const parts = viewBox.split(/\s+/).map(Number)
if (parts.length === 4 && parts.every((n) => Number.isFinite(n))) {
return {
width: Math.max(24, Math.round(parts[2])),
height: Math.max(24, Math.round(parts[3])),
}
}
}
const width = Number(svg.getAttribute("width"))
const height = Number(svg.getAttribute("height"))
if (Number.isFinite(width) && Number.isFinite(height) && width > 0 && height > 0) {
return { width: Math.round(width), height: Math.round(height) }
}
return { width: 320, height: 240 }
}
/** Load an UltiDraw file from Drive and build embedded graphic attrs. */
export async function importExcalidrawFromDriveFile(file: DriveFileInfo): Promise<{
drawScene: string
src: string
width: number
height: number
drawDriveFileId: string
alt: string
}> {
const blob = await fetchDrivePreviewBlob(file)
const text = await blob.text()
const data = JSON.parse(text) as {
elements?: Parameters<
Awaited<typeof import("@excalidraw/excalidraw")>["restoreElements"]
>[0]
appState?: Record<string, unknown>
files?: Record<string, unknown>
}
const { restoreElements, restoreAppState, exportToSvg, serializeAsJSON } = await import(
"@excalidraw/excalidraw"
)
const elements = restoreElements(data.elements ?? [], null)
const appState = restoreAppState(data.appState ?? {}, null)
const files = (data.files ?? {}) as import("@excalidraw/excalidraw/types").BinaryFiles
const drawScene = serializeAsJSON(elements, appState, files, "local")
const svg = await exportToSvg({
elements,
appState,
files,
skipInliningFonts: true,
})
const svgString = new XMLSerializer().serializeToString(svg)
const src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`
const { width, height } = readSvgDimensions(svg)
const drawDriveFileId = await resolveDriveDrawFileId(file)
return {
drawScene,
src,
width,
height,
drawDriveFileId,
alt: file.name,
}
}