summaryrefslogtreecommitdiff
path: root/web/js/player.js
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-30 23:16:11 +0300
committerPaul Buetow <paul@buetow.org>2026-04-30 23:16:11 +0300
commitc866dc4c539d72134ea690c7c44318a58ec27fd2 (patch)
tree25dbd7b1ba868ea3c8ee9f99beab48b37c16d2db /web/js/player.js
parentcfbffc5e8911f0f4bdd63c0fcf4953372a990ac0 (diff)
mobile: responsive layout, touch-friendly progress bar, collapsible filters
- Add mobile breakpoints (860px/520px) with compact header, full-width sidebar overlay, flexible search bar, and adaptive toolbar. - Player now spans full width on mobile and has reduced stage height. - Progress bar gains touch-drag support (touchstart/move/end) for mobile seeking. - Collapse advanced filters (tags/duration/filesize) behind a 'Filters' toggle to keep the default toolbar KISS. Only type and favorites remain always visible.
Diffstat (limited to 'web/js/player.js')
-rw-r--r--web/js/player.js23
1 files changed, 19 insertions, 4 deletions
diff --git a/web/js/player.js b/web/js/player.js
index ed3e8bf..b61be08 100644
--- a/web/js/player.js
+++ b/web/js/player.js
@@ -68,13 +68,28 @@ export function initPlayer() {
});
let seeking = false;
- e.track?.addEventListener('click', (ev) => {
+ const seekToFraction = (frac) => {
const m = currentMediaElement();
if (!m || !m.duration) return;
- const r = e.track.getBoundingClientRect();
- const frac = (ev.clientX - r.left) / r.width;
m.currentTime = Math.max(0, Math.min(1, frac)) * m.duration;
- });
+ };
+ const handlePointer = (ev) => {
+ const r = e.track.getBoundingClientRect();
+ const clientX = ev.touches ? ev.touches[0].clientX : ev.clientX;
+ return (clientX - r.left) / r.width;
+ };
+ e.track?.addEventListener('click', (ev) => seekToFraction(handlePointer(ev)));
+ e.track?.addEventListener('touchstart', (ev) => {
+ seeking = true;
+ ev.preventDefault();
+ seekToFraction(handlePointer(ev));
+ }, { passive: false });
+ e.track?.addEventListener('touchmove', (ev) => {
+ if (!seeking) return;
+ ev.preventDefault();
+ seekToFraction(handlePointer(ev));
+ }, { passive: false });
+ e.track?.addEventListener('touchend', () => { seeking = false; });
e.track?.addEventListener('keydown', (ev) => {
const m = currentMediaElement();
if (!m || !m.duration) return;