Make progress bar cursor draggable
Deploy HEOS panel / deploy (push) Successful in 26s

This commit is contained in:
2026-09-16 23:19:08 +02:00
parent 51dff45b54
commit ec684b7803
12 changed files with 319 additions and 29 deletions
+38 -4
View File
@@ -105,7 +105,7 @@ svg { width: 22px; height: 22px; fill: currentColor; }
margin: 0; min-width: 0;
font-size: 17px; font-weight: 600;
}
.card-head h2 .room-icon { flex: 0 0 auto; height: 20px; width: auto; fill: currentColor; color: var(--muted); }
.card-head h2 .room-icon { flex: 0 0 auto; height: 20px; width: auto; fill: currentColor; }
.card-head h2 .room-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pill {
@@ -138,7 +138,8 @@ svg { width: 22px; height: 22px; fill: currentColor; }
block, when nothing is playing. Muted throughout, so it never competes
with the volume meter below it; the cursor only shows once a position is
actually known (an AVR input or a stream with no duration never gets one). */
.progress { position: relative; height: 3px; border-radius: 999px; background: #0c111b; }
.progress { display: flex; align-items: center; gap: 10px; }
.progress-line { position: relative; flex: 1; height: 3px; border-radius: 999px; background: #0c111b; }
.progress-fill {
display: block; height: 100%; width: calc(var(--progress, 0) * 1%);
border-radius: 999px; background: var(--muted);
@@ -153,7 +154,40 @@ svg { width: 22px; height: 22px; fill: currentColor; }
transform: translateY(-50%);
transition: left .12s ease-out;
}
.progress.known .progress-cursor { display: block; }
/* Elapsed rides above the cursor and remaining below it, all three centred
on one axis, and the total waits at the end of the line. Near either end a
label stops half its own width (--half, measured in app.js) short of it,
so it never hangs off the card. */
.progress-time,
.progress-total {
display: none;
font-size: 12px; line-height: 1; color: var(--muted);
font-variant-numeric: tabular-nums; white-space: nowrap;
}
.progress-time {
position: absolute;
left: clamp(var(--half, 0px), calc(var(--progress, 0) * 1%), calc(100% - var(--half, 0px)));
transform: translateX(-50%);
transition: left .12s ease-out;
}
.progress-time.elapsed { bottom: 9px; }
.progress-time.remaining { top: 9px; }
.progress.known { padding: 16px 0; } /* room for the labels above and below the cursor */
.progress.known .progress-cursor,
.progress.known .progress-time,
.progress.known .progress-total { display: block; }
/* Where the player can seek, the cursor and both times are one handle, with
a thumb-sized grip around a 7px dot. pan-y leaves a vertical swipe to the
page, so scrolling past never seeks; only a sideways drag is ours. Held,
it lights up and follows the finger without easing after it. */
.progress.seekable .progress-cursor,
.progress.seekable .progress-time { cursor: grab; touch-action: pan-y; }
.progress.seekable .progress-cursor::before { content: ''; position: absolute; inset: -16px -14px; }
.progress.dragging .progress-cursor,
.progress.dragging .progress-time { transition: none; cursor: grabbing; }
.progress.dragging .progress-cursor { background: var(--ink); transform: translateY(-50%) scale(1.6); }
.progress.dragging .progress-time { color: var(--ink); }
/* --- volume ---------------------------------------------------------- */
.volume { display: flex; align-items: center; gap: 14px; }
@@ -262,7 +296,7 @@ svg { width: 22px; height: 22px; fill: currentColor; }
/* --- source card ------------------------------------------------------ */
.source-button {
display: flex; align-items: center; gap: 12px;
width: 100%; min-height: 64px;
width: 100%; min-height: 50px;
padding: 10px 14px;
border-radius: 16px;
background: var(--raised);