Player: seek hover tooltip on the Now Playing progress bar
The mockup had a seek tooltip (timestamp tracks the cursor over the progress bar) but it was never ported to the real player. Added it: mousemove computes the hovered fraction -> formatTime(duration*frac), positions the tip, shows on hover / hides on leave. Guarded when no duration. Frontend-only; JS + CSS clean.
This commit is contained in:
parent
bf2a2ca928
commit
112ecbb24f
3 changed files with 28 additions and 0 deletions
|
|
@ -7068,6 +7068,7 @@
|
||||||
<div class="np-progress-fill" id="np-progress-fill"></div>
|
<div class="np-progress-fill" id="np-progress-fill"></div>
|
||||||
</div>
|
</div>
|
||||||
<input type="range" class="np-progress-bar" id="np-progress-bar" min="0" max="100" value="0" step="0.1">
|
<input type="range" class="np-progress-bar" id="np-progress-bar" min="0" max="100" value="0" step="0.1">
|
||||||
|
<div class="np-seek-tip" id="np-seek-tip">0:00</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="np-time-display">
|
<div class="np-time-display">
|
||||||
<span class="np-current-time" id="np-current-time">0:00</span>
|
<span class="np-current-time" id="np-current-time">0:00</span>
|
||||||
|
|
|
||||||
|
|
@ -1537,6 +1537,23 @@ function initExpandedPlayer() {
|
||||||
npProgressBar.addEventListener('mousedown', () => { npProgressBar.dataset.seeking = 'true'; });
|
npProgressBar.addEventListener('mousedown', () => { npProgressBar.dataset.seeking = 'true'; });
|
||||||
npProgressBar.addEventListener('mouseup', () => { delete npProgressBar.dataset.seeking; });
|
npProgressBar.addEventListener('mouseup', () => { delete npProgressBar.dataset.seeking; });
|
||||||
|
|
||||||
|
// Seek hover tooltip — shows the timestamp the cursor is over.
|
||||||
|
const npSeekTip = document.getElementById('np-seek-tip');
|
||||||
|
if (npSeekTip) {
|
||||||
|
npProgressBar.addEventListener('mousemove', (e) => {
|
||||||
|
if (!audioPlayer || !isFinite(audioPlayer.duration) || audioPlayer.duration <= 0) {
|
||||||
|
npSeekTip.classList.remove('visible');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rect = npProgressBar.getBoundingClientRect();
|
||||||
|
const frac = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
|
||||||
|
npSeekTip.textContent = formatTime(frac * audioPlayer.duration);
|
||||||
|
npSeekTip.style.left = (frac * 100) + '%';
|
||||||
|
npSeekTip.classList.add('visible');
|
||||||
|
});
|
||||||
|
npProgressBar.addEventListener('mouseleave', () => npSeekTip.classList.remove('visible'));
|
||||||
|
}
|
||||||
|
|
||||||
// Progress bar (touch)
|
// Progress bar (touch)
|
||||||
npProgressBar.addEventListener('touchstart', () => { npProgressBar.dataset.seeking = 'true'; }, { passive: true });
|
npProgressBar.addEventListener('touchstart', () => { npProgressBar.dataset.seeking = 'true'; }, { passive: true });
|
||||||
npProgressBar.addEventListener('touchmove', (e) => {
|
npProgressBar.addEventListener('touchmove', (e) => {
|
||||||
|
|
|
||||||
|
|
@ -48705,6 +48705,16 @@ textarea.enhanced-meta-field-input {
|
||||||
.np-progress-bar-container:hover .np-progress-fill { box-shadow: 0 0 12px rgba(var(--accent-rgb),0.6) !important; }
|
.np-progress-bar-container:hover .np-progress-fill { box-shadow: 0 0 12px rgba(var(--accent-rgb),0.6) !important; }
|
||||||
.np-time-display { font-variant-numeric: tabular-nums !important; }
|
.np-time-display { font-variant-numeric: tabular-nums !important; }
|
||||||
|
|
||||||
|
/* Seek hover tooltip — timestamp under the cursor on the progress bar. */
|
||||||
|
.np-progress-bar-container { position: relative; }
|
||||||
|
.np-seek-tip {
|
||||||
|
position: absolute; bottom: 150%; transform: translateX(-50%);
|
||||||
|
background: #000; color: #fff; font-size: 11px; font-variant-numeric: tabular-nums;
|
||||||
|
padding: 3px 7px; border-radius: 6px; white-space: nowrap; pointer-events: none;
|
||||||
|
opacity: 0; transition: opacity 0.12s ease; box-shadow: 0 4px 12px rgba(0,0,0,0.5); z-index: 5;
|
||||||
|
}
|
||||||
|
.np-seek-tip.visible { opacity: 1; }
|
||||||
|
|
||||||
/* ── Transport: dominant gradient play button ── */
|
/* ── Transport: dominant gradient play button ── */
|
||||||
.np-controls-row { gap: 24px !important; }
|
.np-controls-row { gap: 24px !important; }
|
||||||
.np-btn {
|
.np-btn {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue