fix(plex): player marker-skip reset, lang-switch reload, tracks wheel, sidebar badge clamp
- PP1: reset cancelledMarkerRef on item change — a cancelled intro/credits auto-skip on one episode suppressed a same-offset marker on the next (auto-skip silently dead for the rest of a binge). - PP2: loadSession no longer depends on the i18n `t` (read via a ref). A mid-playback language switch rebuilt loadSession → re-ran the detail effect → reloaded the session from the STALE saved resume position, losing live progress. - PP3: tracks (audio/subtitle) menu now stopPropagation on wheel, like the gear menu — scrolling the list no longer changes volume. - PS1: collapsed PlexSidebar filter badge clamps to "9+" (was a raw count), matching the feed Sidebar.
This commit is contained in:
parent
97088d5393
commit
f90c12beaa
2 changed files with 19 additions and 6 deletions
|
|
@ -172,6 +172,12 @@ function fmt(t: number): string {
|
|||
|
||||
export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
||||
const { t } = useTranslation();
|
||||
// `t` changes identity on a language switch. loadSession only uses it for error strings, so read it
|
||||
// through a ref — keeping it OUT of loadSession's deps. Otherwise a mid-playback language change
|
||||
// rebuilt loadSession → re-ran the detail effect → reloaded the session from the STALE saved resume
|
||||
// position (losing live progress). See the detail effect's deps.
|
||||
const tRef = useRef(t);
|
||||
tRef.current = t;
|
||||
const qc = useQueryClient();
|
||||
const [id, setId] = useState(itemId);
|
||||
const detailQ = useQuery({ queryKey: ["plex-item", id], queryFn: () => api.plexItem(id) });
|
||||
|
|
@ -284,10 +290,10 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
|||
// needs full transcoding (a later phase).
|
||||
setLoadError(
|
||||
e?.status === 501
|
||||
? t("plex.player.errTranscode")
|
||||
? tRef.current("plex.player.errTranscode")
|
||||
: e?.status === 404
|
||||
? t("plex.player.errNotFound")
|
||||
: t("plex.player.errGeneric"),
|
||||
? tRef.current("plex.player.errNotFound")
|
||||
: tRef.current("plex.player.errGeneric"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -339,7 +345,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
|||
// A fatal HLS error (e.g. the remux session died / the file became unreadable) would
|
||||
// otherwise leave the spinner up forever — surface it instead.
|
||||
hls.on(Hls.Events.ERROR, (_e, data) => {
|
||||
if (data.fatal) setLoadError(t("plex.player.errGeneric"));
|
||||
if (data.fatal) setLoadError(tRef.current("plex.player.errGeneric"));
|
||||
});
|
||||
} else {
|
||||
// direct file (or Safari native HLS)
|
||||
|
|
@ -354,7 +360,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
|||
video.addEventListener("loadedmetadata", onMeta);
|
||||
}
|
||||
},
|
||||
[id, t],
|
||||
[id], // NOT `t` — see tRef above (a language switch must not rebuild this / reload the session).
|
||||
);
|
||||
|
||||
// Start playback when the detail arrives (resume from the saved position unless already watched).
|
||||
|
|
@ -841,6 +847,12 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
|||
const [skipProgress, setSkipProgress] = useState<number | null>(null);
|
||||
skipProgressRef.current = skipProgress;
|
||||
const cancelledMarkerRef = useRef<string | null>(null);
|
||||
// Forget a cancelled-skip when the item changes: the ref holds a `${type}-${start_s}` key, and a
|
||||
// marker at the same offset on the NEXT episode would otherwise be suppressed by a cancel made on
|
||||
// the previous one (auto-skip silently dead for the rest of a binge).
|
||||
useEffect(() => {
|
||||
cancelledMarkerRef.current = null;
|
||||
}, [id]);
|
||||
// The running countdown interval, so cancelAutoSkip can actually STOP it — clearing skipProgress
|
||||
// alone left the interval ticking, which re-set the progress ~100ms later and skipped anyway.
|
||||
const skipTimerRef = useRef<number | null>(null);
|
||||
|
|
@ -1212,6 +1224,7 @@ export default function PlexPlayer({ itemId, onClose, queue }: Props) {
|
|||
<div
|
||||
ref={tracksRef}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onWheel={(e) => e.stopPropagation()}
|
||||
className="glass-menu absolute bottom-full right-0 mb-2 w-56 max-h-[60vh] overflow-auto rounded-xl p-2 text-sm text-white shadow-2xl"
|
||||
>
|
||||
{detail.audio_streams.length > 1 && (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue