feat(design): a Plex title's one action list (C1) — the poster's "…", details and the pin in its menu (E28 S3e2)
Every Plex poster list (library, Discover rails, person, show, season, collection, Home's rails) now opens one menu per list from the right-click, the long-press, Shift+F10 and the card's "…": play/open, watched, add to playlist, media info, copy title, the pin (usePlexCardActions + PlexMenu, replacing the pin-only PlexPinMenu). The card keeps its state at rest and shows watched / add to playlist / "…" on its picture on hover (ui/reveal.ts, shared with the video card); on touch the toggles are gone and a 44px "…" sits beside the title, while the watched pill stays. The hover ⓘ left the card; an episode's add button moved from its caption to the hover row. Seasons get their own short menu (open, watched, add, copy), labelled "Open season" (the card's overlay said "Open show"). Related shows are ordinary poster cards now. A collection's admin "Remove" X moved into its menu, still behind the confirmation. The collection grid is two columns on a phone. The unused .reveal-idle rule is gone.
This commit is contained in:
@@ -39,6 +39,7 @@ import SegmentedToggle from "./ui/SegmentedToggle";
|
||||
import { LoadingState, StateMessage } from "./ui/QueryState";
|
||||
import VideoCard from "./VideoCard";
|
||||
import { useVideoActions } from "./useVideoActions";
|
||||
import { usePlexCardActions } from "./usePlexCardActions";
|
||||
import { PlexPosterCard } from "./plexCards";
|
||||
import { useNavigationActions } from "./navigationContext";
|
||||
import { usePlexActions } from "./plexContext";
|
||||
@@ -126,6 +127,21 @@ function Rail({
|
||||
// A video tile's own action list (E28 C1), the same one the feed's menu shows; the rail keeps its
|
||||
// Play row (it resolves `next`) and its shelf rows around it.
|
||||
const videoActions = useVideoActions({ onState, onToggleSave }, menu.open);
|
||||
// A Plex tile's, likewise (its "Media info" row goes where the tile's `onInfo` does).
|
||||
const plexActions = usePlexCardActions(
|
||||
{
|
||||
onOpen: (p) => {
|
||||
const c = cards.find((x) => x.plex === p);
|
||||
if (c) onPlay(c);
|
||||
},
|
||||
onInfo: (p) => {
|
||||
const c = cards.find((x) => x.plex === p);
|
||||
if (c) onInfo(c);
|
||||
},
|
||||
onToggleWatched,
|
||||
},
|
||||
menu.open,
|
||||
);
|
||||
const target = menu.target;
|
||||
const shelfIdx = target?.pin_id != null ? cards.findIndex((c) => c.pin_id === target.pin_id) : -1;
|
||||
const items: ActionMenuItem[] = !target
|
||||
@@ -145,7 +161,11 @@ function Rail({
|
||||
? videoActions
|
||||
.items(target.video, menu.anchor, { pin: false })
|
||||
.map((it, i) => (i === 0 ? { ...it, separatorBefore: true } : it))
|
||||
: []),
|
||||
: target.plex
|
||||
? plexActions
|
||||
.items(target.plex, { play: false, pin: false })
|
||||
.map((it, i) => (i === 0 ? { ...it, separatorBefore: true } : it))
|
||||
: []),
|
||||
...(onMove && target.pin_id != null
|
||||
? [
|
||||
...SHELF_MOVES.map(([to, key, Icon], i) => ({
|
||||
@@ -222,9 +242,11 @@ function Rail({
|
||||
card={c.plex}
|
||||
navIndex={i}
|
||||
onOpen={() => onPlay(c)}
|
||||
onInfo={() => onInfo(c)}
|
||||
onToggleWatched={onToggleWatched}
|
||||
onAdd={plexActions.add}
|
||||
menuProps={menuFor[i]}
|
||||
menuButtonProps={buttonFor[i]}
|
||||
menuOpen={menu.open && menu.target === c}
|
||||
/>
|
||||
) : (
|
||||
<ShelfTile card={c} onPlay={onPlay} menuProps={menu.triggerProps} navIndex={i} />
|
||||
@@ -234,6 +256,7 @@ function Rail({
|
||||
</Carousel>
|
||||
<ContextMenu menu={menu} ariaLabel={ariaLabel} items={items} />
|
||||
{videoActions.panel}
|
||||
{plexActions.panel}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -593,8 +616,9 @@ export default function Home() {
|
||||
[setJumpTo, setPage],
|
||||
);
|
||||
|
||||
// The ⓘ affordance on a Plex tile: the item's own page in the Plex module, exactly where the same
|
||||
// click goes from the Plex grid. A show tile's card click lands there too — a show is not playable.
|
||||
// The "Media info" row of a Plex tile's menu: the item's own page in the Plex module, exactly where
|
||||
// the same row goes from the Plex grid. A show tile's card click lands there too — a show is not
|
||||
// playable.
|
||||
const onInfo = useCallback(
|
||||
(card: DiscoverCard) => {
|
||||
if (!card.plex) return;
|
||||
|
||||
Reference in New Issue
Block a user