From 639d761bef93630e8d73a894875c7d0d4beea617 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Mon, 15 Jun 2026 16:27:28 +0200 Subject: [PATCH] feat(playlists): keep the player queue live across tabs Track the playing item by id instead of a frozen index, deriving the index from the live queue so the N / M counter and prev/next neighbours stay correct when the playlist changes underneath (e.g. an item removed in another tab) without disrupting playback of the current video. Refetch the playlist list/detail on window focus so such changes flow in, updating the player's queue length in near-real-time. --- frontend/src/components/PlayerModal.tsx | 17 ++++++++++++----- frontend/src/components/Playlists.tsx | 9 ++++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/PlayerModal.tsx b/frontend/src/components/PlayerModal.tsx index 508b941..0448c15 100644 --- a/frontend/src/components/PlayerModal.tsx +++ b/frontend/src/components/PlayerModal.tsx @@ -203,8 +203,15 @@ export default function PlayerModal({ }) { const { t } = useTranslation(); const qc = useQueryClient(); - // The active item is queue[index] (falls back to the single opened video). - const [index, setIndex] = useState(startIndex ?? 0); + // Track the playing item by id (not a frozen index) so it survives the queue changing + // under us — e.g. an item removed in another tab. The index is derived from the *live* + // queue, so the N / M counter and prev/next neighbours stay correct without disrupting + // playback of the current video. + const [playingId, setPlayingId] = useState( + queue?.[startIndex ?? 0]?.id ?? video.id + ); + let index = queue ? queue.findIndex((v) => v.id === playingId) : 0; + if (index < 0) index = 0; const active = queue && queue[index] ? queue[index] : video; const hasQueue = !!queue && queue.length > 1; // startAt only applies to the item we opened with; advanced items resume their own pos. @@ -369,7 +376,7 @@ export default function PlayerModal({ autoMarkedRef.current = true; setWatched(true); } - if (queue && index < queue.length - 1) setIndex(index + 1); + if (queue && index < queue.length - 1) setPlayingId(queue[index + 1].id); } }, }, @@ -418,7 +425,7 @@ export default function PlayerModal({ {hasQueue && (