import type { DownloadJob } from "./api"; // Which row actions apply to a completed library / shared item — gated on the stored media_kind and // job_kind. A generic uploaded file (media_kind='file') opens in the Files viewer instead of a player, // and has no trim and no details edit. Re-download needs a re-fetchable source, which an edit clip and an upload // both lack (the backend 409s both). A single source for the gate the Library + Shared rows render, // so it's unit-testable instead of buried in JSX conditionals — and the two tabs can't drift apart. const isMediaKind = (job: DownloadJob): boolean => job.asset?.media_kind !== "file"; const hasDuration = (job: DownloadJob): boolean => (job.asset?.duration_s ?? 0) > 0; export interface LibraryRowActions { play: boolean; /** Opens in the Files viewer: a file that is not media (its preview, or the "no preview" card). */ view: boolean; edit: boolean; editDetails: boolean; redownload: boolean; } export function libraryRowActions(job: DownloadJob): LibraryRowActions { const media = isMediaKind(job); return { play: media, view: !media && job.can_download, edit: media && job.can_download && hasDuration(job), editDetails: media, redownload: !job.job_kind || job.job_kind === "download", }; } export interface SharedRowActions { play: boolean; view: boolean; save: boolean; edit: boolean; } export function sharedRowActions(job: DownloadJob): SharedRowActions { const media = isMediaKind(job); // The owner's `can_download` gates save/play/edit on a shared item (it reflects their link ACL). return { play: media && job.can_download, view: !media && job.can_download, save: job.can_download, edit: media && job.can_download && hasDuration(job), }; }