This commit is contained in:
2026-09-12 21:55:40 +02:00
parent 53055ea5c6
commit 90860b9279
24 changed files with 1958 additions and 45 deletions
+48 -2
View File
@@ -1289,6 +1289,33 @@
}
};
const enforceSidebarRecommendationDistribution = (items) => {
if (!Array.isArray(items) || items.length <= 3) return items;
// Collect indices of personalized recommendations in the first 3 items
const recIndicesInFirst3 = [];
for (let i = 0; i < Math.min(3, items.length); i++) {
if (items[i] && items[i].personalized) recIndicesInFirst3.push(i);
}
// If more than 1 recommendation in first 3, swap extras with non-rec items from index >= 3
if (recIndicesInFirst3.length > 1) {
let nonRecIdx = 3;
for (let r = 1; r < recIndicesInFirst3.length; r++) {
const swapSlot = recIndicesInFirst3[r];
while (nonRecIdx < items.length && items[nonRecIdx] && items[nonRecIdx].personalized) {
nonRecIdx++;
}
if (nonRecIdx < items.length) {
const tmp = items[swapSlot];
items[swapSlot] = items[nonRecIdx];
items[nonRecIdx] = tmp;
nonRecIdx++;
}
}
}
return items;
};
const loadRecommendations = async (silent = false) => {
const container = document.getElementById('sidebar-recommendations-container');
if (!container || recommendationsLoading) return;
@@ -1316,6 +1343,7 @@
const items = data.items || data.videos || [];
if (data.success && items.length > 0) {
enforceSidebarRecommendationDistribution(items);
currentRecommendations = items;
recommendationsLoaded = true;
@@ -1368,7 +1396,7 @@
const affParams = getSessionAffinityParams();
const mime = getCurrentMimeFilter();
const mimeParam = mime ? `&mime=${encodeURIComponent(mime)}` : '';
const res = await fetch(`/api/v2/recommendations?limit=15&mode=${mode}${mimeParam}&exclude_ids=${excludeArr.join(',')}${affParams}`, {
const res = await fetch(`/api/v2/recommendations?limit=15&mode=${mode}${mimeParam}&exclude_ids=${excludeArr.join(',')}&continuation=1${affParams}`, {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
const data = await res.json();
@@ -1877,10 +1905,28 @@
}
const excludeArr = Array.from(excludeSet).slice(-120);
const cards = Array.from(container ? container.querySelectorAll('.sidebar-video-card') : []);
const cardIndex = cards.indexOf(card);
let preferParam = '';
if (cardIndex >= 0 && cardIndex < 3) {
// Keep exactly 1 recommendation in the first 3 cards
const isPersonalized = card.dataset.personalized === 'true';
preferParam = `&prefer_personalized=${isPersonalized ? 'true' : 'false'}`;
} else if (cardIndex >= 3) {
// Ensure recommendations remain sporadic (never consecutive)
const prevCard = cards[cardIndex - 1];
const nextCard = cards[cardIndex + 1];
const prevIsRec = prevCard && prevCard.dataset.personalized === 'true';
const nextIsRec = nextCard && nextCard.dataset.personalized === 'true';
if (prevIsRec || nextIsRec) {
preferParam = '&prefer_personalized=false';
}
}
const affParams = getSessionAffinityParams();
const mime = getCurrentMimeFilter();
const mimeParam = mime ? `&mime=${encodeURIComponent(mime)}` : '';
const res = await fetch(`/api/v2/recommendations?limit=1&mode=${mode}${mimeParam}&exclude_ids=${excludeArr.join(',')}${affParams}`, {
const res = await fetch(`/api/v2/recommendations?limit=1&mode=${mode}${mimeParam}&exclude_ids=${excludeArr.join(',')}${preferParam}${affParams}`, {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
});
const data = await res.json();