refactor(pins): drop the unused ComfortPinMenu and the comment that described it
Every surface composes the pin row into its object's one action list (E28 C1); the pin-only menu had no caller left. Also un-exports isStandInFocus, which only its own file reads since H1.
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useComfortPin, type PinTarget } from "./comfortPin";
|
||||
import { ContextMenu } from "./ui/ContextMenu";
|
||||
import { type ContextMenuController } from "./ui/useContextMenu";
|
||||
|
||||
// The menu SURFACE for the comfort-shelf pin (E24 S3). Split from `comfortPin.tsx` for the same
|
||||
// reason `ContextMenu.tsx` is split from `useContextMenu.ts`: a file that exports components and
|
||||
// nothing else keeps react-refresh working for every surface that imports it.
|
||||
|
||||
/**
|
||||
* The whole right-click menu for a surface whose only context action is the pin — the card grids and
|
||||
* rails. Render ONE per list, outside the rows (see `ui/ContextMenu`), and spread
|
||||
* `menu.triggerProps` on each row.
|
||||
*
|
||||
* `target` maps the row the user right-clicked to its pin; `title` names it in the confirmation
|
||||
* toast. Both come from the call site because only it knows what its rows are.
|
||||
*/
|
||||
export function ComfortPinMenu<T>({
|
||||
menu,
|
||||
target,
|
||||
title,
|
||||
}: {
|
||||
menu: ContextMenuController<T>;
|
||||
target: (row: T) => PinTarget | null;
|
||||
title: (row: T) => string;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const pin = useComfortPin(menu.open);
|
||||
const row = menu.target;
|
||||
return (
|
||||
<ContextMenu
|
||||
menu={menu}
|
||||
ariaLabel={t("home.pin.menu")}
|
||||
items={row ? pin.item(target(row), title(row)) : []}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -15,13 +15,12 @@ import { type ActionMenuItem } from "./ui/ActionMenu";
|
||||
// shown — a video, a channel, a playlist, a Plex show or movie: you decide something is comfort media
|
||||
// while you are watching it. (Locked decision 3: an episode, a season and a person are not pin kinds,
|
||||
// so their cards and strips carry no pin.) This file is the one place the pin lives; every surface
|
||||
// composes the same `ActionMenuItem` into the menu it already has (`Playlists`, `PlaylistsRail`) or
|
||||
// mounts the `ComfortPinMenu` wrapper when it has none.
|
||||
// composes the same `ActionMenuItem` into its object's ONE action list (E28 C1): the video, Plex and
|
||||
// channel actions (`useVideoActions`, `usePlexCardActions`, `Channels`), the playlist rail and page,
|
||||
// and Home's shelves. There is no pin-only menu any more.
|
||||
//
|
||||
// Feature layer, not `components/ui/`: it speaks a domain API slice, which the platform boundary
|
||||
// (eslint `no-restricted-imports`) forbids a `ui/` primitive from doing. The MENU SURFACE that
|
||||
// renders this item lives in `ComfortPinMenu.tsx` — the same hook/component split, for the same
|
||||
// react-refresh reason, as `useContextMenu.ts` beside `ContextMenu.tsx`.
|
||||
// (eslint `no-restricted-imports`) forbids a `ui/` primitive from doing.
|
||||
|
||||
/** What the API needs to pin something: the kind, and the id the rest of the API already speaks for
|
||||
* that kind (a video id, a channel id, a Plex `rating_key`, a playlist id). Mirrors
|
||||
|
||||
@@ -52,7 +52,7 @@ export function focusNeighbour(el: HTMLElement): boolean {
|
||||
let standIn: HTMLElement | null = null;
|
||||
|
||||
/** Whether `el` holds the focus only because the keeper put it there. */
|
||||
export function isStandInFocus(el: Element | null): boolean {
|
||||
function isStandInFocus(el: Element | null): boolean {
|
||||
return el !== null && el === standIn;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user