This commit is contained in:
2026-05-25 09:03:58 +02:00
parent 3a436304bd
commit 92cc474ca3
3 changed files with 83 additions and 15 deletions

View File

@@ -12919,6 +12919,12 @@ body.layout-modern .xd-score-wrapper {
min-width: 120px;
}
/* Custom mobile-friendly slider that replaces the native range input */
.nav-xd-custom-slider {
flex: 1;
min-width: 120px;
}
.xd-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;

View File

@@ -4717,6 +4717,8 @@ window.cancelAnimFrame = (function () {
const navXdTier = document.getElementById('nav_xd_tier_label');
const navXdStatus = document.getElementById('nav_xd_status');
const navXdVal = document.getElementById('nav_xd_val');
const navXdSliderContainer = document.getElementById('nav_xd_slider_container');
let navXdCustomFill = null; // set during custom slider init below
const XD_TIERS_NAV = [null,
{ cls: 'xd-tier-1', label: 'xD' },
@@ -4739,14 +4741,12 @@ window.cancelAnimFrame = (function () {
score = +score;
if (navXdVal) navXdVal.textContent = score;
const tier = getNavXdTier(score);
// Update slider track fill
if (navXdInput) {
const pct = Math.round((score / +navXdInput.max) * 100);
const color = XD_TIER_COLORS[tier];
navXdInput.style.setProperty('--xd-fill', color);
navXdInput.style.setProperty('--xd-pct', pct + '%');
// Update custom slider fill colour
if (navXdCustomFill) navXdCustomFill.style.background = color;
if (navXdVal) navXdVal.style.color = color;
}
// Keep hidden native input in sync (save button reads it)
if (navXdInput) navXdInput.value = score;
if (!navXdTier) return;
if (!tier || score <= 0) { navXdTier.style.display = 'none'; return; }
const t = XD_TIERS_NAV[tier];
@@ -4757,7 +4757,68 @@ window.cancelAnimFrame = (function () {
if (navXdInput) {
updateNavXdUI(+navXdInput.value);
navXdInput.addEventListener('input', () => updateNavXdUI(+navXdInput.value));
}
// Custom mobile-friendly slider for xD score
if (navXdInput && navXdSliderContainer) {
const xdMin = 0, xdMax = +navXdInput.max || 100;
const xdContainer = navXdSliderContainer;
xdContainer.style.cssText = 'position:relative;height:28px;flex:1;cursor:pointer;user-select:none;-webkit-user-select:none;touch-action:none;';
const xdTrack = document.createElement('div');
xdTrack.style.cssText = 'position:absolute;left:8px;right:8px;height:4px;background:#333;border-radius:2px;top:50%;transform:translateY(-50%);';
const xdFill = document.createElement('div');
xdFill.style.cssText = 'position:absolute;left:0;height:100%;background:#888;border-radius:2px;pointer-events:none;';
navXdCustomFill = xdFill;
const xdThumb = document.createElement('div');
xdThumb.style.cssText = 'position:absolute;width:18px;height:18px;background:#888;border-radius:50%;top:50%;transform:translate(-50%,-50%);box-shadow:0 0 6px rgba(0,0,0,.6);pointer-events:none;transition:transform .1s;';
const xdSetRatio = (r) => {
xdFill.style.width = (r * 100) + '%';
xdThumb.style.left = `calc(8px + ${r} * (100% - 16px))`;
};
xdSetRatio((+navXdInput.value - xdMin) / (xdMax - xdMin));
xdTrack.appendChild(xdFill);
xdContainer.appendChild(xdTrack);
xdContainer.appendChild(xdThumb);
const xdValueFromClientX = (clientX) => {
const rect = xdTrack.getBoundingClientRect();
const r = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
xdSetRatio(r);
return Math.round(xdMin + r * (xdMax - xdMin));
};
xdContainer.addEventListener('pointerdown', (e) => {
e.preventDefault();
xdContainer.setPointerCapture(e.pointerId);
xdThumb.style.transform = 'translate(-50%,-50%) scale(1.25)';
updateNavXdUI(xdValueFromClientX(e.clientX));
// also tint thumb with current tier colour
xdThumb.style.background = XD_TIER_COLORS[getNavXdTier(+navXdInput.value)];
}, { passive: false });
xdContainer.addEventListener('pointermove', (e) => {
if (!xdContainer.hasPointerCapture(e.pointerId)) return;
const val = xdValueFromClientX(e.clientX);
xdThumb.style.background = XD_TIER_COLORS[getNavXdTier(val)];
updateNavXdUI(val);
});
const xdOnEnd = (e) => {
if (!xdContainer.hasPointerCapture(e.pointerId)) return;
xdContainer.releasePointerCapture(e.pointerId);
xdThumb.style.transform = 'translate(-50%,-50%) scale(1)';
};
xdContainer.addEventListener('pointerup', xdOnEnd);
xdContainer.addEventListener('pointercancel', xdOnEnd);
// Sync thumb colour on init
updateNavXdUI(+navXdInput.value);
xdThumb.style.background = XD_TIER_COLORS[getNavXdTier(+navXdInput.value)];
}
if (navXdSaveBtn && navXdInput) {

View File

@@ -35,7 +35,8 @@
<div class="nav-xd-filter">
<label class="nav-xd-label">{{ t('filter.min_xd_score') }}</label>
<div class="nav-xd-controls">
<input type="range" id="nav_min_xd_score" min="0" max="100" step="1" value="{{ session.min_xd_score || 0 }}" class="xd-slider">
<input type="range" id="nav_min_xd_score" min="0" max="100" step="1" value="{{ session.min_xd_score || 0 }}" class="xd-slider" style="display:none;" aria-hidden="true">
<div id="nav_xd_slider_container" class="nav-xd-custom-slider"></div>
<span id="nav_xd_val" class="xd-slider-val">{{ session.min_xd_score || 0 }}</span>
<span id="nav_xd_tier_label" class="xd-score-badge" style="display:none; font-size: 0.75em;"></span>
</div>