feat(design): a library row keeps Share (the link copy) in sight, ahead of save (E28 S3e3)

The owner's call: sharing a download's link is the library's main errand, more
important than saving the file, so it does not hide in the row's "…". Manage
sharing stays in the menu. The "…" tests press as a mouse, so a stray long-press
timer no longer fires after teardown.
This commit is contained in:
2026-09-26 07:21:21 +02:00
parent 2df60fbf07
commit 9c91eb5d22
7 changed files with 54 additions and 23 deletions
+19 -10
View File
@@ -28,7 +28,8 @@ import { menuGroups } from "./ui/menuGroups";
// A download's ONE action list (E28 C1): the row's "…", its right-click, long-press and Shift+F10,
// on the queue, the library and the shared tab. The row keeps its primary action (play; pause /
// resume / retry in the queue), the save link and its state (the error and its details) in sight;
// the rest — the editors, sharing, re-download, the copies and the destructive rows — lives here.
// a library row also keeps Share (the link copy) in sight, ahead of save. The rest — the editors,
// managing the shares, re-download, the copies and the destructive rows — lives here.
export type DownloadTab = "queue" | "done" | "shared";
export type JobOp = "pause" | "resume" | "cancel" | "delete" | "redownload";
@@ -165,7 +166,19 @@ export function useDownloadActions({
// Row actions gated on the stored media_kind + job_kind (see downloadActions).
const a = libraryRowActions(job);
return menuGroups(
[...(a.play ? [play(job)] : []), save(job)],
// The row's own buttons first, in the row's order: sharing the link is the library's main
// errand, ahead of saving the file.
[
...(a.play ? [play(job)] : []),
{
id: "share",
label: t("downloads.actions.share"),
icon: icon(Share2),
disabled: sharingId !== null,
onSelect: () => void quickShare(job),
},
save(job),
],
[
...(a.edit ? [edit(job)] : []),
...(a.editDetails
@@ -196,13 +209,6 @@ export function useDownloadActions({
: []),
],
[
{
id: "share",
label: t("downloads.actions.share"),
icon: icon(Share2),
disabled: sharingId !== null,
onSelect: () => void quickShare(job),
},
{
id: "share-manage",
label: t("downloads.actions.shareManage"),
@@ -261,5 +267,8 @@ export function useDownloadActions({
/** The queue's visible primary action and the error dialog's Retry. */
const run = (job: DownloadJob, op: JobOp) => act.mutate({ id: job.id, op });
return { items, run };
/** The library row's visible Share: the same one-click link copy as its menu row. */
const share = (job: DownloadJob) => void quickShare(job);
return { items, run, share };
}