import type { DriveFileInfo } from "@/lib/api/types" import { blobForPreview } from "@/lib/api/drive-download" export interface PublicShareView { token: string name: string item_type: "file" | "folder" path: string permissions: number owner_id?: string owner_displayname?: string files?: DriveFileInfo[] file?: DriveFileInfo } /** Label for "Partagé par …" — display name, then local part of owner id, then fallback. */ export function publicShareOwnerLabel(data: Pick): string { const display = data.owner_displayname?.trim() if (display) return display const id = data.owner_id?.trim() if (!id) return "Utilisateur" const at = id.indexOf("@") return at > 0 ? id.slice(0, at) : id } export function publicShareHref(token: string, path = "/"): string { const base = `/drive/s/${encodeURIComponent(token)}` const trimmed = path.replace(/^\/+|\/+$/g, "") if (!trimmed) return base return `${base}/${trimmed.split("/").map(encodeURIComponent).join("/")}` } export function folderPathFromPublicSegments(segments: string[] | undefined): string { if (!segments?.length) return "/" return "/" + segments.map((s) => decodeURIComponent(s)).join("/") } /** Extract NC or Ultidrive public share token from a share URL. */ export function extractShareTokenFromURL(url: string): string | null { const trimmed = url.trim() if (!trimmed) return null try { const parsed = new URL(trimmed, "http://localhost") const match = parsed.pathname.match(/\/index\.php\/s\/([^/]+)/) ?? parsed.pathname.match(/\/drive\/s\/([^/]+)/) ?? parsed.pathname.match(/\/s\/([^/]+)/) return match ? decodeURIComponent(match[1]) : null } catch { return null } } /** Prefer Ultidrive `/drive/s/{token}` URLs (absolute when origin known). */ export function normalizePublicShareURL( url: string, token?: string, origin?: string ): string { const resolvedToken = token?.trim() || extractShareTokenFromURL(url) if (!resolvedToken) return url const href = publicShareHref(resolvedToken) const base = origin ?? (typeof window !== "undefined" ? window.location.origin : "") return base ? `${base.replace(/\/$/, "")}${href}` : href } export function publicShareDownloadApiPath( token: string, filePath: string, password?: string ): string { const parts = filePath .replace(/^\/+/, "") .split("/") .filter(Boolean) .map((seg) => encodeURIComponent(seg)) const base = `/api/v1/drive/public/shares/${encodeURIComponent(token)}/download/${parts.join("/")}` if (!password) return base return `${base}?password=${encodeURIComponent(password)}` } export function publicSharePreviewApiPath( token: string, file: { path: string; name: string }, password?: string, width = 400, height = 300 ): string { const params = new URLSearchParams({ path: publicShareDownloadPath(file), w: String(width), h: String(height), }) if (password) params.set("password", password) return `/api/v1/drive/public/shares/${encodeURIComponent(token)}/preview?${params.toString()}` } export async function fetchPublicShare( token: string, path = "/", password?: string ): Promise { const params = new URLSearchParams() if (path && path !== "/") params.set("path", path) if (password) params.set("password", password) const qs = params.toString() const res = await fetch( `/api/v1/drive/public/shares/${encodeURIComponent(token)}${qs ? `?${qs}` : ""}` ) if (!res.ok) { throw new Error(res.status === 403 ? "password_required" : "share_unavailable") } return (await res.json()) as PublicShareView } export function publicShareDownloadPath(file: { path: string; name: string }): string { const path = (file.path ?? "").trim() || "/" if (path === "/") return "/" if (path.endsWith(`/${file.name}`) || path === `/${file.name}`) return path return `${path.replace(/\/$/, "")}/${file.name}`.replace(/\/+/g, "/") } export async function fetchPublicShareBlob( token: string, file: { path: string; name: string; mime_type?: string }, password?: string ): Promise { const logical = publicShareDownloadPath(file) const res = await fetch(publicShareDownloadApiPath(token, logical, password)) if (!res.ok) { throw new Error("download_failed") } const raw = await res.blob() return blobForPreview(raw, file.mime_type ?? "", file.name) }