feat(downloads): gate library row actions by media_kind (E7 S5b)
Surface the S5a media_kind discriminator in the library UI. A generic uploaded file (media_kind='file') is download+share only — no player and no timeline to trim, so Play/Edit/Edit-details are media-only; it shows a neutral file glyph instead of an (always-empty) thumbnail and no duration chip (container/size still read). The "Shared with me" tab's file row is gated the same way. Re-download is now hidden for edit clips and uploads too (neither has a re-fetchable source — the backend already rejects both with 409), removing a latent click-to-409 on edit rows. FE-only: the serializer already emits media_kind (S5a). Adds media_kind to the DownloadAsset type and "upload" to the job_kind union; DOM tests cover the file-row presentation (glyph, no img, no duration).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState, type ReactNode } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { CalendarClock, Copy, Link2, Scissors } from "lucide-react";
|
||||
import { CalendarClock, Copy, File, Link2, Scissors } from "lucide-react";
|
||||
import clsx from "clsx";
|
||||
import { qk } from "../lib/queryKeys";
|
||||
import { useLiveQuery } from "../lib/useLiveQuery";
|
||||
@@ -69,6 +69,15 @@ function Thumb({ job }: { job: DownloadJob }) {
|
||||
// On load failure (a genuinely missing poster file) fall back to the remote source thumbnail.
|
||||
const [src, setSrc] = useState(primary);
|
||||
useEffect(() => setSrc(primary), [primary]);
|
||||
// A generic uploaded file (media_kind='file') has no video frame to poster — it's a document/
|
||||
// archive, not playable media. Show a neutral file glyph instead of an (always-empty) thumbnail.
|
||||
if (job.asset?.media_kind === "file") {
|
||||
return (
|
||||
<div className="w-28 aspect-video shrink-0 rounded-lg overflow-hidden bg-surface border border-border flex items-center justify-center text-muted">
|
||||
<File className="w-8 h-8" aria-hidden="true" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div className="w-28 aspect-video shrink-0 rounded-lg overflow-hidden bg-surface border border-border">
|
||||
{src ? (
|
||||
|
||||
Reference in New Issue
Block a user