From c7ad16e9f6352cb146b17d05acc7ad33023570ec Mon Sep 17 00:00:00 2001 From: peterino2 Date: Mon, 2 Feb 2026 20:17:40 -0800 Subject: [PATCH] redesing of frontend --- musicroom.db | Bin 32768 -> 32768 bytes public/app.js | 46 ++++++++++++++++++++++++++ public/index.html | 65 ++++++++++++++++++++++-------------- public/styles.css | 82 +++++++++++++++++++++++++++------------------- server.ts | 24 ++++++++++++-- 5 files changed, 157 insertions(+), 60 deletions(-) diff --git a/musicroom.db b/musicroom.db index 51bad83a6d572447dda26e84c1e3ac10e1c54380..4fd95794fd2c39d0cb71d61ee53b18a18ce82ef3 100644 GIT binary patch delta 1164 zcma)5O=}ZD7|zyeHreh>ks{Rkv3|BeXS1_2vmYp;NKqQoYHR&O>dx*=T@0pL1@+RT zh$jz~oWw&f(u<(ffZ$c>Nfdf32p&B92NVQ%TZ4@t^ftWDGtWHl^S)E7b<}DdbA8Ir zr#nt6I~T9NfZH|wM+V*p-@!6?3!Z}-5MT%tL682Uxu^S!KGUmZGX-7k%uU`C(|0F` z9T03`5!a`ed-H9OWJF*u;Hyxs4YHW@g&)wketWrBZHFRDa?GOy`rMmsgQVoH8d|m+ z*QZvRwOx;tZ5lkDff7D|EATj+hfDAc9D`4q-Nr%Km@nqXTlTcAn+nRB)#aL*vK zP3)L9WhSPq-mkX=9l^cGi#Q5H&qdUAF!C95kZ>Z3sT&dzIr&8J+&_Xd?SeyHtAew; z4^Z0?0k>V`T0TdVMjqlM5oA0F0-tc#ckNs}`yp|7d%0YF7*{Gmk(rh;5TCtKy(Nwq zC(n)>YiDC*%)oTQF)Hy*VU&X~EnF%XC#I%mD&nHxrTA{qv67xl%#4B3>GS0?hu6rb zM0m4WFfNEY({c4y5mVDLiBYcdxFU*}4PxpUV}T6r#EAe+u2a*-w&}a3gX>4MwQiIH zwoh0nu|SR#0#TWS?qL=p(GysVQX2AzS!&YGaJp%YXT#AImoeYOmfwiIOt#-b-(@t4&z~5C#tm01pcfG!I=5h7Yd~*s~!Z_YMRo P162W&u}dVgGhfXhEUGY~ diff --git a/public/app.js b/public/app.js index 633ee1f..4232185 100644 --- a/public/app.js +++ b/public/app.js @@ -16,6 +16,7 @@ let currentIndex = 0; let currentUser = null; let serverStatus = null; + let library = []; let prefetchController = null; let loadingSegments = new Set(); let trackCaches = new Map(); // Map of filename -> Set of cached segment indices @@ -453,6 +454,10 @@ function renderPlaylist() { const container = $("#playlist"); container.innerHTML = ""; + if (playlist.length === 0) { + container.innerHTML = '
Playlist empty
'; + return; + } playlist.forEach((track, i) => { const div = document.createElement("div"); div.className = "track" + (i === currentIndex ? " active" : ""); @@ -486,6 +491,46 @@ }); } + function renderLibrary() { + const container = $("#library"); + container.innerHTML = ""; + if (library.length === 0) { + container.innerHTML = '
No tracks discovered
'; + return; + } + library.forEach((track) => { + const div = document.createElement("div"); + div.className = "track"; + const title = track.title?.trim() || track.filename.replace(/\.[^.]+$/, ""); + div.innerHTML = `${title}${fmt(track.duration)}`; + div.onclick = async () => { + // In local mode, play directly from library + if (!synced) { + currentFilename = track.filename; + serverTrackDuration = track.duration; + $("#track-title").textContent = title; + loadingSegments.clear(); + const cachedUrl = await loadTrackBlob(track.filename); + audio.src = cachedUrl || getTrackUrl(track.filename); + audio.currentTime = 0; + localTimestamp = 0; + audio.play(); + } + }; + container.appendChild(div); + }); + } + + async function loadLibrary() { + try { + const res = await fetch("/api/library"); + library = await res.json(); + renderLibrary(); + } catch (e) { + console.warn("Failed to load library"); + } + } + async function handleUpdate(data) { if (!data.track) { $("#track-title").textContent = "No tracks"; @@ -820,6 +865,7 @@ // Initialize Promise.all([initStorage(), loadServerStatus()]).then(() => { + loadLibrary(); loadCurrentUser().then(() => { if (currentUser) loadStreams(); }); diff --git a/public/index.html b/public/index.html index d8cb8ea..8651708 100644 --- a/public/index.html +++ b/public/index.html @@ -35,36 +35,53 @@
-
-