xd score fix
This commit is contained in:
@@ -4727,7 +4727,7 @@ window.cancelAnimFrame = (function () {
|
|||||||
];
|
];
|
||||||
const getNavXdTier = (s) => {
|
const getNavXdTier = (s) => {
|
||||||
s = +s;
|
s = +s;
|
||||||
if (s < 5) return 0;
|
if (s < 1) return 0;
|
||||||
if (s < 200) return 1;
|
if (s < 200) return 1;
|
||||||
if (s < 1000) return 2;
|
if (s < 1000) return 2;
|
||||||
if (s < 100000) return 3;
|
if (s < 100000) return 3;
|
||||||
@@ -4879,7 +4879,7 @@ window.cancelAnimFrame = (function () {
|
|||||||
// 2. Any grid thumbnail indicators for that item (on any page)
|
// 2. Any grid thumbnail indicators for that item (on any page)
|
||||||
const XD_TIER_META = [
|
const XD_TIER_META = [
|
||||||
null,
|
null,
|
||||||
{ cls: 'xd-tier-1', label: 'xD', min: 5 },
|
{ cls: 'xd-tier-1', label: 'xD', min: 1 },
|
||||||
{ cls: 'xd-tier-2', label: 'xDD', min: 200 },
|
{ cls: 'xd-tier-2', label: 'xDD', min: 200 },
|
||||||
{ cls: 'xd-tier-3', label: 'xDDD', min: 1000 },
|
{ cls: 'xd-tier-3', label: 'xDDD', min: 1000 },
|
||||||
{ cls: 'xd-tier-4', label: 'xDDDD', min: 100000 },
|
{ cls: 'xd-tier-4', label: 'xDDDD', min: 100000 },
|
||||||
@@ -4887,7 +4887,7 @@ window.cancelAnimFrame = (function () {
|
|||||||
];
|
];
|
||||||
|
|
||||||
const getXdTierFromScore = (score) => {
|
const getXdTierFromScore = (score) => {
|
||||||
if (score < 5) return 0;
|
if (score < 1) return 0;
|
||||||
if (score < 200) return 1;
|
if (score < 200) return 1;
|
||||||
if (score < 1000) return 2;
|
if (score < 1000) return 2;
|
||||||
if (score < 100000) return 3;
|
if (score < 100000) return 3;
|
||||||
|
|||||||
@@ -1553,24 +1553,13 @@
|
|||||||
const rBadge = slide.querySelector('.scroll-rating[data-item-id]');
|
const rBadge = slide.querySelector('.scroll-rating[data-item-id]');
|
||||||
if (rBadge) {
|
if (rBadge) {
|
||||||
if (window.scrollerIsMod || item.local_id) rBadge.classList.add('can-cycle');
|
if (window.scrollerIsMod || item.local_id) rBadge.classList.add('can-cycle');
|
||||||
rBadge.addEventListener('click', async e => {
|
rBadge.addEventListener('click', e => {
|
||||||
if (Date.now() - speedEndedAt < 200) return; // ignore click if we just ended a speed-hold
|
if (Date.now() - speedEndedAt < 200) return; // ignore click if we just ended a speed-hold
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const slideEl = rBadge.closest('.scroll-slide');
|
const slideEl = rBadge.closest('.scroll-slide');
|
||||||
const id = slideEl?.dataset.localId || rBadge.dataset.itemId;
|
const id = slideEl?.dataset.localId || rBadge.dataset.itemId;
|
||||||
if (!id || isNaN(id)) { showShareToast('Rehost first to change rating'); return; }
|
if (!id || isNaN(id)) { showShareToast('Rehost first to change rating'); return; }
|
||||||
try {
|
cycleRatingOptimistic(rBadge, id, false);
|
||||||
const resp = await fetch(`/api/v2/tags/${id}/cycle-rating`, {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: { 'x-csrf-token': window.scrollerCsrf || '' }
|
|
||||||
});
|
|
||||||
const data = await resp.json();
|
|
||||||
if (data.success) {
|
|
||||||
rBadge.className = `scroll-rating ${data.rating_class}${window.scrollerIsMod ? ' can-cycle' : ''}`;
|
|
||||||
rBadge.textContent = data.rating_label;
|
|
||||||
rBadge.dataset.rating = data.rating_class;
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1932,6 +1921,73 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cycleRatingOptimistic(badge, id, showToast = false) {
|
||||||
|
if (!badge || !id || isNaN(id)) return;
|
||||||
|
|
||||||
|
let currentRating = badge.dataset.rating || '';
|
||||||
|
if (!currentRating) {
|
||||||
|
if (badge.classList.contains('sfw')) currentRating = 'sfw';
|
||||||
|
else if (badge.classList.contains('nsfw')) currentRating = 'nsfw';
|
||||||
|
else if (badge.classList.contains('nsfl')) currentRating = 'nsfl';
|
||||||
|
}
|
||||||
|
|
||||||
|
let nextRating = 'sfw';
|
||||||
|
if (currentRating === 'sfw') nextRating = 'nsfw';
|
||||||
|
else if (currentRating === 'nsfw') nextRating = 'nsfl';
|
||||||
|
|
||||||
|
const mapping = {
|
||||||
|
sfw: { label: 'SFW', cls: 'sfw', toast: '🛡 SFW' },
|
||||||
|
nsfw: { label: 'NSFW', cls: 'nsfw', toast: '🔥 NSFW' },
|
||||||
|
nsfl: { label: 'NSFL', cls: 'nsfl', toast: '💀 NSFL' }
|
||||||
|
};
|
||||||
|
|
||||||
|
const info = mapping[nextRating];
|
||||||
|
|
||||||
|
const oldClassName = badge.className;
|
||||||
|
const oldTextContent = badge.textContent;
|
||||||
|
const oldDatasetRating = badge.dataset.rating;
|
||||||
|
|
||||||
|
// Track active request ID to ignore out-of-order race conditions on rapid keypresses
|
||||||
|
const reqId = (badge._lastCycleReqId || 0) + 1;
|
||||||
|
badge._lastCycleReqId = reqId;
|
||||||
|
|
||||||
|
// Optimistically apply new state
|
||||||
|
badge.className = `scroll-rating ${info.cls}${window.scrollerIsMod ? ' can-cycle' : ''}`;
|
||||||
|
badge.textContent = info.label;
|
||||||
|
badge.dataset.rating = info.cls;
|
||||||
|
|
||||||
|
if (showToast) {
|
||||||
|
showShareToast(info.toast);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`/api/v2/tags/${id}/cycle-rating`, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'x-csrf-token': window.scrollerCsrf || '' }
|
||||||
|
})
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(data => {
|
||||||
|
if (badge._lastCycleReqId !== reqId) return; // ignore stale responses
|
||||||
|
if (!data.success) {
|
||||||
|
revert();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Verify we match actual server result
|
||||||
|
badge.className = `scroll-rating ${data.rating_class}${window.scrollerIsMod ? ' can-cycle' : ''}`;
|
||||||
|
badge.textContent = data.rating_label;
|
||||||
|
badge.dataset.rating = data.rating_class;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
if (badge._lastCycleReqId !== reqId) return; // ignore stale responses
|
||||||
|
revert();
|
||||||
|
});
|
||||||
|
|
||||||
|
function revert() {
|
||||||
|
badge.className = oldClassName;
|
||||||
|
badge.textContent = oldTextContent;
|
||||||
|
badge.dataset.rating = oldDatasetRating;
|
||||||
|
showShareToast('⚠️ Failed to update rating');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function reloadFeed() {
|
function reloadFeed() {
|
||||||
clearCache();
|
clearCache();
|
||||||
@@ -3143,26 +3199,12 @@
|
|||||||
else if (e.key === 'p' || e.key === 'P') {
|
else if (e.key === 'p' || e.key === 'P') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (!currentSlide || !window.scrollerLoggedIn) return;
|
if (!currentSlide || !window.scrollerLoggedIn) return;
|
||||||
const itemId = currentSlide.dataset.id;
|
const itemId = currentSlide.dataset.localId || currentSlide.dataset.id;
|
||||||
if (!itemId) return;
|
if (!itemId) return;
|
||||||
fetch(`/api/v2/tags/${itemId}/cycle-rating`, {
|
|
||||||
method: 'PUT',
|
|
||||||
headers: { 'x-csrf-token': window.scrollerCsrf || '' }
|
|
||||||
})
|
|
||||||
.then(r => r.json())
|
|
||||||
.then(data => {
|
|
||||||
if (!data.success) return;
|
|
||||||
// Update the badge on the slide immediately
|
|
||||||
const badge = currentSlide.querySelector('.scroll-rating[data-item-id]');
|
const badge = currentSlide.querySelector('.scroll-rating[data-item-id]');
|
||||||
if (badge) {
|
if (badge) {
|
||||||
badge.className = `scroll-rating ${data.rating_class}${window.scrollerIsMod ? ' can-cycle' : ''}`;
|
cycleRatingOptimistic(badge, itemId, true);
|
||||||
badge.textContent = data.rating_label;
|
|
||||||
badge.dataset.rating = data.rating_class;
|
|
||||||
}
|
}
|
||||||
const labels = { sfw: '🛡 SFW', nsfw: '🔥 NSFW', nsfl: '💀 NSFL' };
|
|
||||||
showShareToast(labels[data.rating_class] ?? data.rating_label);
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
}
|
}
|
||||||
else if (e.key === 'l' || e.key === 'L') { e.preventDefault(); if (currentSlide) toggleFav(currentSlide); }
|
else if (e.key === 'l' || e.key === 'L') { e.preventDefault(); if (currentSlide) toggleFav(currentSlide); }
|
||||||
else if (e.key === 'i' || e.key === 'I') { e.preventDefault(); if (currentSlide) openTagBar(currentSlide.dataset.id); }
|
else if (e.key === 'i' || e.key === 'I') { e.preventDefault(); if (currentSlide) openTagBar(currentSlide.dataset.id); }
|
||||||
|
|||||||
@@ -1346,7 +1346,7 @@
|
|||||||
|
|
||||||
const getXdTier = (score) => {
|
const getXdTier = (score) => {
|
||||||
score = +score;
|
score = +score;
|
||||||
if (score < 5) return 0;
|
if (score < 1) return 0;
|
||||||
if (score < 200) return 1;
|
if (score < 200) return 1;
|
||||||
if (score < 1000) return 2;
|
if (score < 1000) return 2;
|
||||||
if (score < 100000) return 3;
|
if (score < 100000) return 3;
|
||||||
|
|||||||
@@ -86,11 +86,11 @@ const computeXdScore = (comments) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const xdScoreMeta = (score) => {
|
const xdScoreMeta = (score) => {
|
||||||
if (score < 5) return { tier: 0, label: '' };
|
if (score < 1) return { tier: 0, label: '' };
|
||||||
if (score < 200) return { tier: 1, label: 'xD' };
|
if (score < 200) return { tier: 1, label: 'xD' };
|
||||||
if (score < 1000) return { tier: 2, label: 'xDD' };
|
if (score < 1000) return { tier: 2, label: 'xDD' };
|
||||||
if (score < 100000) return { tier: 3, label: 'xDDD' };
|
if (score < 100000) return { tier: 3, label: 'xDDD' };
|
||||||
if (score < 200000000) return { tier: 4, label: 'xDDDD' };
|
if (score < 20000000) return { tier: 4, label: 'xDDDD' };
|
||||||
return { tier: 5, label: 'xDDDDD+' };
|
return { tier: 5, label: 'xDDDDD+' };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user