Track recently played items, filter from Up Next for 4 hours

Stores played product IDs + timestamps in localStorage. Items played
within the last 4 hours are hidden from Up Next sidebar and skipped
by getNextItem(). Queue items always play (user-explicit). Cleans
stale entries on page load.
This commit is contained in:
russell@unturf.com 2026-02-08 14:17:07 -05:00
parent da465868e3
commit c00c33754c

View file

@ -46,6 +46,50 @@
if (savedQueue) queue = JSON.parse(savedQueue);
} catch (e) {}
// --- Recently played tracking (localStorage) ---
var RECENTLY_PLAYED_COOLDOWN = 4 * 60 * 60 * 1000; // 4 hours
var recentlyPlayed = {};
try {
var savedRecent = localStorage.getItem('watchRecentlyPlayed');
if (savedRecent) recentlyPlayed = JSON.parse(savedRecent);
} catch (e) {}
function cleanRecentlyPlayed() {
var now = Date.now();
var changed = false;
for (var id in recentlyPlayed) {
if (now - recentlyPlayed[id] > RECENTLY_PLAYED_COOLDOWN) {
delete recentlyPlayed[id];
changed = true;
}
}
if (changed) saveRecentlyPlayed();
}
function saveRecentlyPlayed() {
try { localStorage.setItem('watchRecentlyPlayed', JSON.stringify(recentlyPlayed)); } catch (e) {}
}
function markPlayed(productId) {
if (!productId) return;
recentlyPlayed[productId] = Date.now();
saveRecentlyPlayed();
}
function isRecentlyPlayed(productId) {
if (!recentlyPlayed[productId]) return false;
return (Date.now() - recentlyPlayed[productId]) < RECENTLY_PLAYED_COOLDOWN;
}
// Clean stale entries on load
cleanRecentlyPlayed();
// Mark current item as played
var initialProductEl = document.querySelector('[data-watch-product-id]');
if (initialProductEl) {
markPlayed(initialProductEl.getAttribute('data-watch-product-id'));
}
// --- Autoplay with sound (for video/audio) ---
if (activeMedia) {
var playPromise = activeMedia.play();
@ -338,6 +382,7 @@
// --- Update page content (title, description, related, URL) ---
function updatePageContent(data) {
markPlayed(data.product_id);
document.title = data.title;
var h1 = document.querySelector('.product-images h1');
@ -389,9 +434,13 @@
}
var html = headerHtml;
related.forEach(function(item, i) {
var visibleIndex = 0;
related.forEach(function(item) {
var played = isRecentlyPlayed(item.id);
if (played) return; // skip recently played
visibleIndex++;
html += '<div class="related-content-row">';
html += '<span class="related-content-index">' + (i + 1) + '</span>';
html += '<span class="related-content-index">' + visibleIndex + '</span>';
html += '<a href="' + item.url + '" class="related-content-item" data-watch-id="' + item.id + '">';
if (item.thumbnail_url) {
html += '<img src="' + item.thumbnail_url + '" />';
@ -433,15 +482,21 @@
// --- Countdown timer ---
function getNextItem() {
// Queue items always play (user explicitly added them)
if (queue.length > 0) return queue[0];
var firstRelated = document.querySelector('.related-content-item[data-watch-id]');
if (firstRelated) {
return {
id: firstRelated.getAttribute('data-watch-id'),
title: firstRelated.querySelector('span') ? firstRelated.querySelector('span').textContent : '',
thumbnail_url: firstRelated.querySelector('img') ? firstRelated.querySelector('img').src : null,
url: firstRelated.getAttribute('href')
};
// Find first related item that hasn't been recently played
var allRelated = document.querySelectorAll('.related-content-item[data-watch-id]');
for (var i = 0; i < allRelated.length; i++) {
var el = allRelated[i];
var id = el.getAttribute('data-watch-id');
if (!isRecentlyPlayed(id)) {
return {
id: id,
title: el.querySelector('span') ? el.querySelector('span').textContent : '',
thumbnail_url: el.querySelector('img') ? el.querySelector('img').src : null,
url: el.getAttribute('href')
};
}
}
return null;
}
@ -637,6 +692,23 @@
);
}
// Filter recently played from server-rendered related content
function filterRecentlyPlayedFromDOM() {
var rows = document.querySelectorAll('.related-content-row');
var visibleIndex = 0;
for (var i = 0; i < rows.length; i++) {
var link = rows[i].querySelector('.related-content-item[data-watch-id]');
if (link && isRecentlyPlayed(link.getAttribute('data-watch-id'))) {
rows[i].style.display = 'none';
} else {
visibleIndex++;
var indexEl = rows[i].querySelector('.related-content-index');
if (indexEl) indexEl.textContent = visibleIndex;
}
}
}
filterRecentlyPlayedFromDOM();
renderQueue();
preloadNext();
})();