import type { QueryClient } from "@tanstack/react-query"; import { qk } from "./queryKeys"; import { api } from "./api"; import { copyText } from "./clipboard"; import { notify } from "./notifications"; // The download queue, the per-card download index, and the storage-usage meter all move together // whenever a job is enqueued, deleted, or its state changes — invalidate them as one unit. export function invalidateDownloads(qc: QueryClient) { qc.invalidateQueries({ queryKey: qk.downloads() }); qc.invalidateQueries({ queryKey: qk.downloadIndex() }); qc.invalidateQueries({ queryKey: qk.downloadUsage() }); } // One-click share (E7 S3 · D2-A): the row's Share button turns "share this" into a single action. // Ensure the job has a public link (minting one on demand — omitting `allow_download` so the backend // D1 default makes it downloadable), copy it to the clipboard, and toast with an "open in new tab" // action. A copy failure still toasts (warning) WITH that action, so the link is never a dead end. // Advanced controls (password, expiry, revoke, share-with-a-user) live in the Share dialog. Returns // the shared URL, or null if link creation failed — so the caller/tests can react to the outcome. export async function quickShareLink( qc: QueryClient, job: { id: number }, t: (key: string) => string, ): Promise { let link; try { const existing = await qc.fetchQuery({ queryKey: qk.downloadLinks(job.id), queryFn: () => api.downloadLinks(job.id), }); link = existing[0]; if (!link) { link = await api.createDownloadLink(job.id, {}); // omit allow_download → backend D1 default (true) qc.setQueryData(qk.downloadLinks(job.id), [link]); } } catch { notify({ level: "error", message: t("downloads.share.linkFailed") }); return null; } const url = window.location.origin + link.url; const action = { label: t("downloads.share.openNewTab"), onClick: () => window.open(url, "_blank", "noopener,noreferrer"), }; notify( (await copyText(url)) ? { level: "success", message: t("downloads.share.linkCopied"), action } : { level: "warning", message: t("downloads.share.copyFailed"), action }, ); return url; }