"use client" import { useCallback, useEffect, useMemo, useState } from "react" import Link from "next/link" import { useQueryClient } from "@tanstack/react-query" import { Button } from "@/components/ui/button" import { ArrowLeft } from "lucide-react" import { UltidrawDocumentEditor } from "@/components/drive/ultidraw-document" import { DocsEditorLoadingShell, useDocsEditorLoadingState, } from "@/components/drive/richtext/docs-editor-loading-shell" import { apiClient } from "@/lib/api/client" import { useDriveFileById, useDriveMutations, useDriveShares } from "@/lib/api/hooks/use-drive-queries" import { useAuthReady } from "@/lib/api/use-auth-ready" import { displayFileBaseName } from "@/lib/drive/display-file-name" import { readDriveEditorReturnTo } from "@/lib/drive/drive-editor-return" import { resolveRenameName } from "@/lib/drive/drive-default-name" import { driveFolderHref } from "@/lib/drive/drive-sidebar-tree" import { resolveDriveEditReturnTo } from "@/lib/drive/drive-url" import { useDriveDocumentTitle } from "@/lib/drive/use-drive-document-title" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { colorForGuestId } from "@/lib/drive/guest-editor-identity" import type { UltidrawSessionResponse } from "@/lib/drive/ultidraw-types" import { useChromeIdentity } from "@/lib/hooks/use-chrome-identity" function fileNameFromPath(filePath: string): string { return filePath.split("/").filter(Boolean).pop() ?? filePath } export function UltidrawEditor({ fileId }: { fileId: string }) { const queryClient = useQueryClient() const identity = useChromeIdentity() const { ready } = useAuthReady() const setSharePath = useDriveUIStore((s) => s.setSharePath) const { data: file, error: fileError, isPending: filePending, isFetching: fileFetching, } = useDriveFileById(fileId) const displayPath = file?.path ?? "" const [session, setSession] = useState(null) const [sessionError, setSessionError] = useState(null) const fileName = file?.name ?? fileNameFromPath(displayPath) const title = displayFileBaseName(fileName) useDriveDocumentTitle(title) const [backHref, setBackHref] = useState("/drive") useEffect(() => { if (!displayPath) return setBackHref( resolveDriveEditReturnTo( null, displayPath, (folderPath) => driveFolderHref("files", folderPath), readDriveEditorReturnTo() ) ) }, [displayPath]) const { data: sharesData } = useDriveShares(displayPath, Boolean(displayPath)) const { rename } = useDriveMutations() const refreshFile = useCallback(async () => { await queryClient.invalidateQueries({ queryKey: ["drive", "file", fileId] }) }, [fileId, queryClient]) useEffect(() => { if (!displayPath) return let cancelled = false setSession(null) setSessionError(null) void (async () => { try { const res = await apiClient.post("/ultidraw/session", { path: displayPath, mode: "edit", }) if (!cancelled) setSession(res) } catch (e) { if (!cancelled) { setSessionError(e instanceof Error ? e.message : "Impossible d'ouvrir le dessin") } } })() return () => { cancelled = true } }, [displayPath]) const handleRename = useCallback( async (input: string) => { if (!displayPath) return const newName = resolveRenameName({ name: fileName, type: "file" }, input) if (displayFileBaseName(fileName) === input.trim()) return await rename.mutateAsync({ path: displayPath, new_name: newName }) await refreshFile() }, [displayPath, fileName, refreshFile, rename] ) const openShare = useCallback(() => { if (displayPath) setSharePath(displayPath) }, [displayPath, setSharePath]) const collabUserName = identity?.name?.trim() || identity?.email || "Utilisateur" const collabUserColor = colorForGuestId(identity?.email ?? collabUserName) const chrome = useMemo( () => ({ title, onRename: handleRename, renameDisabled: rename.isPending, backHref, backLabel: "Drive", showBack: true, shares: sharesData?.shares ?? [], onShareClick: openShare, showShare: true, showAccount: true, }), [title, handleRename, rename.isPending, backHref, sharesData?.shares, openShare] ) const resolvingFile = !ready || filePending || fileFetching const awaitingSession = Boolean(displayPath) && !session && !sessionError const { documentLoading, documentPhase, onDocumentLoadingChange } = useDocsEditorLoadingState( session?.roomId ?? displayPath ?? fileId ) const error = fileError instanceof Error ? fileError.message : sessionError const errorView = error || !file ? (

{error ?? "Dessin introuvable"}

) : null return ( {session && file && !error ? ( ) : null} ) }