feat(plex): player HTPC polish — Stop button, keyboard help, time-remaining + clock, scroll-restore
- Explicit Stop button (stops playback + returns to the library). - Keyboard cheat-sheet overlay toggled with 'H' (movie hides the episode-nav row). - Backspace = stop & back to feed (HTPC-remote convention); closes the help first. - Time-remaining readout beside the seek bar + a live wall clock in the top bar (both fade with the controls). - PlexBrowse restores the grid scroll position when returning from the player, so Back lands on the same card instead of the top of the library. - New plex.player i18n keys (stop/help/keys.*) in en/hu/de.
This commit is contained in:
parent
4993298838
commit
38c4bee869
7 changed files with 165 additions and 7 deletions
|
|
@ -1,4 +1,4 @@
|
|||
import { lazy, Suspense, useEffect, useRef, type CSSProperties } from "react";
|
||||
import { lazy, Suspense, useEffect, useLayoutEffect, useRef, type CSSProperties } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useInfiniteQuery, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { ArrowLeft, CheckCircle2, Play } from "lucide-react";
|
||||
|
|
@ -34,6 +34,19 @@ export default function PlexBrowse({ q, library, show, sort }: Props) {
|
|||
const dq = useDebounced(q.trim(), 350);
|
||||
const sub = useHistorySubview<Sub>({ kind: "grid" });
|
||||
|
||||
// Opening a show/player replaces the grid entirely (the component returns early below), so the
|
||||
// scroll container resets to the top. Remember where the grid was scrolled when leaving it, and
|
||||
// restore it when we come back — so the browser/mouse Back from the player lands on the same card
|
||||
// instead of the top of the library. The scroller is App's <main> (the page's overflow-y-auto).
|
||||
const scrollRef = useRef(0);
|
||||
const scroller = () => document.querySelector("main");
|
||||
useLayoutEffect(() => {
|
||||
if (sub.view.kind === "grid" && scrollRef.current) {
|
||||
const el = scroller();
|
||||
if (el) el.scrollTop = scrollRef.current;
|
||||
}
|
||||
}, [sub.view.kind]);
|
||||
|
||||
const browseQ = useInfiniteQuery({
|
||||
queryKey: ["plex-browse", library, dq, sort, show],
|
||||
enabled: !!library && sub.view.kind === "grid",
|
||||
|
|
@ -66,6 +79,7 @@ export default function PlexBrowse({ q, library, show, sort }: Props) {
|
|||
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
|
||||
|
||||
function onCard(card: PlexCard) {
|
||||
scrollRef.current = scroller()?.scrollTop ?? 0; // remember grid position for the trip back
|
||||
if (card.type === "show") sub.open({ kind: "show", id: card.id });
|
||||
else sub.open({ kind: "player", id: card.id });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue