Show album covers on request queue

This commit is contained in:
pleb 2026-04-13 14:24:19 -07:00
parent a6629f8e95
commit 86830adc47
5 changed files with 63 additions and 23 deletions

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg width="48" height="48" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"> <svg width="48" height="48" version="1.1" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
<rect fill="#111111" width="48" height="48"/> <rect fill="#111111" width="48" height="48"/>
<path fill="#ffffff" d="m21.225 29.383c-0.09826-0.28968-0.22135-0.65379-0.3125-1.1086-0.09115-0.45481-0.13672-0.90394-0.13672-1.3474 0-0.69359 0.15625-1.319 0.46875-1.8761 0.32552-0.56852 0.72266-1.0972 1.1914-1.5862 0.48177-0.48892 0.99609-0.96079 1.543-1.4156 0.5599-0.45481 1.0742-0.89826 1.543-1.3303 0.48177-0.43207 0.87891-0.88688 1.1914-1.3644 0.32552-0.47755 0.48828-1.1434 0.48828-1.7944 0-0.58594-0.11719-1.0937-0.35156-1.5234-0.23438-0.44271-0.5599-0.80729-0.97656-1.0937-0.40364-0.29948-0.8724-0.52083-1.4062-0.66406-0.52083-0.14323-1.0807-0.21484-1.6797-0.21484-1.9401 0-3.7484 0.9081-5.5469 2.5977-0.56753 0.53317-1.5583-3.5623 0-4.5117 2.113-1.2875 4.349-1.875 6.6406-1.875 1.0547 0 2.0508 0.13672 2.9883 0.41016 0.9375 0.27344 1.7578 0.67708 2.4609 1.2109 0.70312 0.53386 1.2565 1.1979 1.6602 1.9922s0.60547 1.7187 0.60547 2.7734c0 1.0026-0.16927 1.9936-0.50781 2.6758-0.33854 0.68222-0.76823 1.3133-1.2891 1.8932-0.50781 0.56852-1.0612 1.0745-1.6602 1.5179-0.58594 0.44344-1.1393 0.88688-1.6602 1.3303-0.50781 0.44344-0.93099 0.90394-1.2695 1.3815-0.33854 0.47755-0.50781 1.0063-0.50781 1.5862 0 0.48892 0.07162 0.93236 0.21484 1.3303 0.14323 0.39796 0.29303 0.73083 0.42969 1.0063 0.31581 0.63652-3.8048 0.93258-4.1211-2e-6zm2.2266 8.3427c-0.74219 0-1.3997-0.25391-1.9727-0.76172-0.54688-0.49479-0.82031-1.1068-0.82031-1.8359 0-0.74219 0.27344-1.3542 0.82031-1.8359 0.5599-0.52083 1.2174-0.78125 1.9727-0.78125 0.74219 0 1.3932 0.26042 1.9531 0.78125 0.54688 0.48177 0.82031 1.0938 0.82031 1.8359 0 0.72917-0.27344 1.3411-0.82031 1.8359-0.57292 0.50781-1.224 0.76172-1.9531 0.76172z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 190 B

View File

@ -99,7 +99,8 @@ body.loading #requestOverlay {
#requestList { #requestList {
margin: 0; margin: 0;
padding-left: 2.2rem; padding: 0;
list-style: none;
font-size: 1.5rem; font-size: 1.5rem;
line-height: 1.25; line-height: 1.25;
} }
@ -122,7 +123,20 @@ body.loading #requestOverlay {
} }
.request-item { .request-item {
display: list-item; display: flex;
align-items: center;
gap: 0.5rem;
flex-wrap: wrap;
min-width: 0;
}
.request-cover {
width: 2em;
height: 2em;
flex-shrink: 0;
object-fit: cover;
border-radius: 0.15em;
vertical-align: middle;
} }
.request-title { .request-title {

View File

@ -46,7 +46,7 @@
</div> </div>
<div id="requestOverlay" aria-live="polite"> <div id="requestOverlay" aria-live="polite">
<div id="requestHeader">Song requests</div> <div id="requestHeader">Song requests</div>
<ol id="requestList"></ol> <ul id="requestList"></ul>
<div id="requestEmpty">No pending requests</div> <div id="requestEmpty">No pending requests</div>
</div> </div>
</div> </div>

View File

@ -680,7 +680,7 @@ var debugBsrExampleIndex = 0;
var requestListEl = must("requestList"); var requestListEl = must("requestList");
var requestOverlayEl = must("requestOverlay"); var requestOverlayEl = must("requestOverlay");
var requestEmptyEl = must("requestEmpty"); var requestEmptyEl = must("requestEmpty");
var requestTitleCache = /* @__PURE__ */ new Map(); var requestBeatSaverCache = /* @__PURE__ */ new Map();
var requestTitleMisses = /* @__PURE__ */ new Set(); var requestTitleMisses = /* @__PURE__ */ new Set();
function loadChatRequestJson() { function loadChatRequestJson() {
const base = new URL("ChatRequest.json", location.href); const base = new URL("ChatRequest.json", location.href);
@ -700,10 +700,12 @@ function requesterLine(item) {
].filter(Boolean); ].filter(Boolean);
return parts.length ? parts.join(" ") : item.rqn || ""; return parts.length ? parts.join(" ") : item.rqn || "";
} }
async function enrichRequestTitle(key, titleEl) { async function enrichRequestFromBeatSaver(key, titleEl, coverEl) {
if (requestTitleMisses.has(key)) return; if (requestTitleMisses.has(key)) return;
if (requestTitleCache.has(key)) { const cached = requestBeatSaverCache.get(key);
titleEl.textContent = requestTitleCache.get(key) ?? ""; if (cached) {
titleEl.textContent = cached.title;
coverEl.src = cached.coverUrl || "images/unknown.svg";
return; return;
} }
try { try {
@ -713,12 +715,19 @@ async function enrichRequestTitle(key, titleEl) {
return; return;
} }
const name = map.metadata?.songName ?? map.name; const name = map.metadata?.songName ?? map.name;
if (name && typeof name === "string") { const title2 = name && typeof name === "string" ? name : "";
requestTitleCache.set(key, name); if (!title2) {
titleEl.textContent = name; requestTitleMisses.add(key);
return; return;
} }
requestTitleMisses.add(key); const rawCover = map.versions?.[0]?.coverURL?.trim();
const coverUrl = rawCover && /^https?:\/\//i.test(rawCover) ? rawCover : "";
requestBeatSaverCache.set(key, {
title: title2,
coverUrl
});
titleEl.textContent = title2;
if (coverUrl) coverEl.src = coverUrl;
} catch { } catch {
requestTitleMisses.add(key); requestTitleMisses.add(key);
} }
@ -729,6 +738,12 @@ function renderRequestList(items) {
for (const item of items) { for (const item of items) {
const li = document.createElement("li"); const li = document.createElement("li");
li.className = "request-item"; li.className = "request-item";
const coverEl = document.createElement("img");
coverEl.className = "request-cover";
coverEl.src = "images/unknown.svg";
coverEl.alt = "";
coverEl.decoding = "async";
li.appendChild(coverEl);
const titleEl = document.createElement("span"); const titleEl = document.createElement("span");
titleEl.className = "request-title"; titleEl.className = "request-title";
titleEl.textContent = `!bsr ${item.key}`; titleEl.textContent = `!bsr ${item.key}`;
@ -741,7 +756,7 @@ function renderRequestList(items) {
li.appendChild(meta); li.appendChild(meta);
} }
requestListEl.appendChild(li); requestListEl.appendChild(li);
void enrichRequestTitle(item.key, titleEl); void enrichRequestFromBeatSaver(item.key, titleEl, coverEl);
} }
} }
async function loadRequestQueue() { async function loadRequestQueue() {

View File

@ -567,10 +567,10 @@ const DEBUG_BSR_EXAMPLE_IDS = [
] as const; ] as const;
let debugBsrExampleIndex = 0; let debugBsrExampleIndex = 0;
const requestListEl = must<HTMLOListElement>("requestList"); const requestListEl = must<HTMLUListElement>("requestList");
const requestOverlayEl = must<HTMLElement>("requestOverlay"); const requestOverlayEl = must<HTMLElement>("requestOverlay");
const requestEmptyEl = must<HTMLElement>("requestEmpty"); const requestEmptyEl = must<HTMLElement>("requestEmpty");
const requestTitleCache = new Map<string, string>(); const requestBeatSaverCache = new Map<string, { title: string; coverUrl: string }>();
const requestTitleMisses = new Set<string>(); const requestTitleMisses = new Set<string>();
function loadChatRequestJson() { function loadChatRequestJson() {
@ -588,10 +588,12 @@ function requesterLine(item: ChatRequestEntry) {
return parts.length ? parts.join(" ") : item.rqn || ""; return parts.length ? parts.join(" ") : item.rqn || "";
} }
async function enrichRequestTitle(key: string, titleEl: HTMLElement) { async function enrichRequestFromBeatSaver(key: string, titleEl: HTMLElement, coverEl: HTMLImageElement) {
if (requestTitleMisses.has(key)) return; if (requestTitleMisses.has(key)) return;
if (requestTitleCache.has(key)) { const cached = requestBeatSaverCache.get(key);
titleEl.textContent = requestTitleCache.get(key) ?? ""; if (cached) {
titleEl.textContent = cached.title;
coverEl.src = cached.coverUrl || "images/unknown.svg";
return; return;
} }
try { try {
@ -601,12 +603,16 @@ async function enrichRequestTitle(key: string, titleEl: HTMLElement) {
return; return;
} }
const name = map.metadata?.songName ?? map.name; const name = map.metadata?.songName ?? map.name;
if (name && typeof name === "string") { const title = name && typeof name === "string" ? name : "";
requestTitleCache.set(key, name); if (!title) {
titleEl.textContent = name; requestTitleMisses.add(key);
return; return;
} }
requestTitleMisses.add(key); const rawCover = map.versions?.[0]?.coverURL?.trim();
const coverUrl = rawCover && /^https?:\/\//i.test(rawCover) ? rawCover : "";
requestBeatSaverCache.set(key, { title, coverUrl });
titleEl.textContent = title;
if (coverUrl) coverEl.src = coverUrl;
} catch { } catch {
requestTitleMisses.add(key); requestTitleMisses.add(key);
} }
@ -618,6 +624,12 @@ function renderRequestList(items: ChatRequestEntry[]) {
for (const item of items) { for (const item of items) {
const li = document.createElement("li"); const li = document.createElement("li");
li.className = "request-item"; li.className = "request-item";
const coverEl = document.createElement("img");
coverEl.className = "request-cover";
coverEl.src = "images/unknown.svg";
coverEl.alt = "";
coverEl.decoding = "async";
li.appendChild(coverEl);
const titleEl = document.createElement("span"); const titleEl = document.createElement("span");
titleEl.className = "request-title"; titleEl.className = "request-title";
titleEl.textContent = `!bsr ${item.key}`; titleEl.textContent = `!bsr ${item.key}`;
@ -630,7 +642,7 @@ function renderRequestList(items: ChatRequestEntry[]) {
li.appendChild(meta); li.appendChild(meta);
} }
requestListEl.appendChild(li); requestListEl.appendChild(li);
void enrichRequestTitle(item.key, titleEl); void enrichRequestFromBeatSaver(item.key, titleEl, coverEl);
} }
} }