fix: playlist panel UX issues

- Phantom playlists: stop pushing locally on create; let PLAYLIST_CREATED
  STOMP event add the entry to avoid the REST/STOMP race that doubled items
- Row click: attach toggle-expand listener on the li instead of the name
  span only; add cursor:pointer to .playlist-list-item
- Input styling: apply surface-3 bg, border, radius, and color to
  .playlist-create-row input and .playlist-rename-form input with focus ring
- Play/pause error toast: apiFetch now skips json() when response has no
  application/json Content-Type (empty 200 body from play/pause endpoints)
This commit is contained in:
2026-05-01 11:02:46 +02:00
parent cc478f99dd
commit 648dbd9ff7
4 changed files with 23 additions and 5 deletions
+17
View File
@@ -1069,6 +1069,14 @@ button:disabled:hover {
font-size: 12px;
padding: 5px 8px;
min-width: 0;
background: var(--color-surface-3);
border: 1px solid var(--color-border);
border-radius: 6px;
color: var(--color-text);
outline: none;
}
.playlist-create-row input:focus {
border-color: var(--color-accent-border);
}
.playlist-list {
@@ -1095,6 +1103,7 @@ button:disabled:hover {
border-radius: 8px;
border: 1px solid transparent;
transition: background 0.12s;
cursor: pointer;
}
.playlist-list-item:hover {
@@ -1171,6 +1180,14 @@ button:disabled:hover {
font-size: 12px;
padding: 4px 7px;
min-width: 0;
background: var(--color-surface-3);
border: 1px solid var(--color-border);
border-radius: 6px;
color: var(--color-text);
outline: none;
}
.playlist-rename-form input:focus {
border-color: var(--color-accent-border);
}
/* Playback controls */
+6 -5
View File
@@ -62,7 +62,8 @@
if (csrfToken && csrfHeader) headers[csrfHeader] = csrfToken;
const response = await fetch(`${apiBase()}${path}`, { ...options, headers });
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
if (response.status === 204) return null;
const ct = response.headers.get("content-type") || "";
if (response.status === 204 || !ct.includes("application/json")) return null;
return response.json();
}
@@ -160,10 +161,10 @@
if (!name) { showToast("Enter a playlist name.", "info"); return; }
try {
const view = await apiFetch("", { method: "POST", body: JSON.stringify({ name }) });
playlists.push(view);
input.value = "";
renderPlaylistList();
expandPlaylist(view.id);
// Don't push locally — the PLAYLIST_CREATED STOMP event will add it.
// Just pre-set the expanded id so it opens as soon as the event renders it.
if (view?.id) expandedPlaylistId = view.id;
} catch {
showToast("Could not create playlist.", "error");
}
@@ -186,11 +187,11 @@
const li = document.createElement("li");
li.className = "playlist-list-item" + (p.id === expandedPlaylistId ? " expanded" : "") + (p.id === activePlaylistId ? " active" : "");
li.dataset.id = p.id;
li.addEventListener("click", () => toggleExpand(p.id));
const nameSpan = document.createElement("span");
nameSpan.className = "playlist-list-name";
nameSpan.textContent = p.name;
nameSpan.addEventListener("click", () => toggleExpand(p.id));
const actions = document.createElement("div");
actions.className = "playlist-list-actions";