fix: watch-mode Next/autoplay follow one true ring, honor Fresh toggle
Every forward path through the ring now uses a single selector: chooseNextInRing() = freshMode ? getNextUnwatchedItem() : getNextItem() Next button, autoplay countdown, DJ crossfade target, preload, and countdown-play-now all route through it. Previously, Next button hardcoded skipToNextUnwatched() regardless of Fresh toggle — user would see offset +1 in sidebar but land on a farther unwatched item. navigateToNext and completeDjFadeout now sync ringPosition via indexOf(target) instead of blindly advancing by +direction — necessary when Fresh mode jumps past watched items.
This commit is contained in:
parent
206ff49e68
commit
b09d1fc739
1 changed files with 28 additions and 14 deletions
|
|
@ -1218,15 +1218,20 @@
|
||||||
fetchAndNavigate(ringProductIds[idx]);
|
fetchAndNavigate(ringProductIds[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function skipToNextUnwatched() {
|
// One true selector — every forward path (Next button, autoplay, preload)
|
||||||
|
// walks our ring the same way. Fresh toggle controls watched-skip.
|
||||||
|
function chooseNextInRing() {
|
||||||
|
return freshMode ? getNextUnwatchedItem() : getNextItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
function skipToNext() {
|
||||||
if (djCrossfadeActive) cancelDjCrossfade();
|
if (djCrossfadeActive) cancelDjCrossfade();
|
||||||
cancelCountdown();
|
cancelCountdown();
|
||||||
if (staticTimer) { clearTimeout(staticTimer); staticTimer = null; }
|
if (staticTimer) { clearTimeout(staticTimer); staticTimer = null; }
|
||||||
|
|
||||||
var item = getNextUnwatchedItem();
|
var item = chooseNextInRing();
|
||||||
if (!item || !item.id) return;
|
if (!item || !item.id) return;
|
||||||
|
|
||||||
// Advance ring position to the target item
|
|
||||||
var idx = ringProductIds.indexOf(item.id);
|
var idx = ringProductIds.indexOf(item.id);
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
ringPosition = idx;
|
ringPosition = idx;
|
||||||
|
|
@ -1264,7 +1269,7 @@
|
||||||
if (!autoplayEnabled) return;
|
if (!autoplayEnabled) return;
|
||||||
if (!activeMedia) return;
|
if (!activeMedia) return;
|
||||||
|
|
||||||
var next = getNextItem();
|
var next = chooseNextInRing();
|
||||||
if (!next || !next.id) return;
|
if (!next || !next.id) return;
|
||||||
|
|
||||||
// Need preloaded data for the next item
|
// Need preloaded data for the next item
|
||||||
|
|
@ -1450,13 +1455,18 @@
|
||||||
djCrossfadeData = null;
|
djCrossfadeData = null;
|
||||||
cancelCountdown();
|
cancelCountdown();
|
||||||
|
|
||||||
// Pop queue or advance ring
|
// Pop queue or sync ring position to target
|
||||||
if (queue.length > 0 && queue[0].id === data.product_id) {
|
if (queue.length > 0 && queue[0].id === data.product_id) {
|
||||||
queue.shift();
|
queue.shift();
|
||||||
saveQueue();
|
saveQueue();
|
||||||
renderQueue();
|
renderQueue();
|
||||||
} else if (ringProductIds.length) {
|
} else if (ringProductIds.length) {
|
||||||
ringPosition = (ringPosition + ringDirection + ringProductIds.length) % ringProductIds.length;
|
var idx = ringProductIds.indexOf(data.product_id);
|
||||||
|
if (idx !== -1) {
|
||||||
|
ringPosition = idx;
|
||||||
|
} else {
|
||||||
|
ringPosition = (ringPosition + ringDirection + ringProductIds.length) % ringProductIds.length;
|
||||||
|
}
|
||||||
saveRingState();
|
saveRingState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1499,7 +1509,7 @@
|
||||||
if (!autoplayEnabled) return;
|
if (!autoplayEnabled) return;
|
||||||
if (djCrossfadeActive) return;
|
if (djCrossfadeActive) return;
|
||||||
|
|
||||||
var next = getNextItem();
|
var next = chooseNextInRing();
|
||||||
if (!next) return;
|
if (!next) return;
|
||||||
|
|
||||||
showCountdownOverlay(next);
|
showCountdownOverlay(next);
|
||||||
|
|
@ -1565,12 +1575,16 @@
|
||||||
queue.shift();
|
queue.shift();
|
||||||
saveQueue();
|
saveQueue();
|
||||||
renderQueue();
|
renderQueue();
|
||||||
} else {
|
} else if (ringProductIds.length) {
|
||||||
// Advance ring position
|
// Sync ring position to target's actual index — honors Fresh-mode
|
||||||
if (ringProductIds.length) {
|
// jumps past watched items (which can be farther than +direction).
|
||||||
|
var idx = ringProductIds.indexOf(productId);
|
||||||
|
if (idx !== -1) {
|
||||||
|
ringPosition = idx;
|
||||||
|
} else {
|
||||||
ringPosition = (ringPosition + ringDirection + ringProductIds.length) % ringProductIds.length;
|
ringPosition = (ringPosition + ringDirection + ringProductIds.length) % ringProductIds.length;
|
||||||
saveRingState();
|
|
||||||
}
|
}
|
||||||
|
saveRingState();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preloadedData && preloadedData.product_id === productId) {
|
if (preloadedData && preloadedData.product_id === productId) {
|
||||||
|
|
@ -1593,7 +1607,7 @@
|
||||||
|
|
||||||
// --- Phase 1: fetch next item JSON (fast, no media download) ---
|
// --- Phase 1: fetch next item JSON (fast, no media download) ---
|
||||||
function preloadNext() {
|
function preloadNext() {
|
||||||
var next = getNextItem();
|
var next = chooseNextInRing();
|
||||||
if (!next || !next.id) return;
|
if (!next || !next.id) return;
|
||||||
|
|
||||||
// Idempotent: skip if already preloading or preloaded this item
|
// Idempotent: skip if already preloading or preloaded this item
|
||||||
|
|
@ -1866,7 +1880,7 @@
|
||||||
|
|
||||||
if (e.target.id === 'skip-next-btn' || e.target.closest('#skip-next-btn')) {
|
if (e.target.id === 'skip-next-btn' || e.target.closest('#skip-next-btn')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
skipToNextUnwatched();
|
skipToNext();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1888,7 +1902,7 @@
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cancelCountdown();
|
cancelCountdown();
|
||||||
var next = getNextItem();
|
var next = chooseNextInRing();
|
||||||
if (next) navigateToNext(next);
|
if (next) navigateToNext(next);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue