import { useTranslation } from "react-i18next"; import { Copy, Link2 } from "lucide-react"; import { copyText } from "../lib/clipboard"; import { notify } from "../lib/notifications"; import { type ActionMenuItem } from "./ui/ActionMenu"; // "Copy title" and "Copy link", the two rows every object's menu ends its middle group with // (DESIGN.md C1, "Text stays selectable"): on touch the long-press belongs to the context menu, so the text a // finger cannot select is copied from here. One builder, so every object says it the same way and // the clipboard write always runs inside the gesture (`inGesture`, which Safari insists on). // // A feature file, not `ui/`: it speaks the app's notifications. type Named = "title" | "name"; export function useCopyItems() { const { t } = useTranslation(); const copy = (text: string, done: string) => { void copyText(text).then((ok) => notify( ok ? { level: "success", message: done } : { level: "error", message: t("common.copy.failed") }, ), ); }; /** The rows for one object. `text` is its title (a video, a show) or its name (a channel, a * playlist); a row whose value is missing is left out rather than copying an empty string. */ return ( text: string | null | undefined, link: string | null | undefined, named: Named = "title", ): ActionMenuItem[] => [ ...(text ? [ { id: "copy-text", label: t(named === "title" ? "common.copy.title" : "common.copy.name"), icon: , inGesture: true, onSelect: () => copy(text, t("common.copy.done")), }, ] : []), ...(link ? [ { id: "copy-link", label: t("common.copy.link"), icon: , inGesture: true, onSelect: () => copy(link, t("common.copy.linkDone")), }, ] : []), ]; }