video search UI: show slskd peers/username, live vs demo, errors

- Result meta now adapts to the source: Soulseek shows '👤 uploader · N peers · N
  slots' (real slskd availability); torrent/usenet keep '▲ seeders' (still mock).
- Results header shows a '● live' badge for real slskd searches vs an amber 'demo
  data' badge for the still-mocked sources — so it's never ambiguous again.
- slskd errors ('not configured', network) surface as a clear ⚠ line in the panel.
JS/CSS balance clean.
This commit is contained in:
BoulderBadgeDad 2026-06-19 14:17:45 -07:00
parent 305020f61e
commit 86fde7d62c
2 changed files with 20 additions and 3 deletions

View file

@ -218,12 +218,14 @@
postJSON('/api/video/downloads/search', params).then(function (d) {
_setScanning(triggerRows, false);
if (!resultsEl.isConnected) return;
if (d && d.error) { resultsEl.innerHTML = '<div class="vdl-res-empty vdl-res-err">⚠ ' + esc(d.error) + '</div>'; return; }
var rows = (d && d.results) || [];
if (!rows.length) { resultsEl.innerHTML = '<div class="vdl-res-empty">No matching releases found.</div>'; return; }
var okN = rows.filter(function (r) { return r.accepted; }).length;
var live = d && d.live ? '<span class="vdl-res-live">● live</span>' : '<span class="vdl-res-demo">demo data</span>';
resultsEl.innerHTML =
'<div class="vdl-res-head"><strong>' + rows.length + '</strong> result' + (rows.length === 1 ? '' : 's') +
' · <span class="vdl-res-okn">' + okN + ' meet your profile</span></div>' +
' · <span class="vdl-res-okn">' + okN + ' meet your profile</span>' + live + '</div>' +
rows.map(resultCardHTML).join('');
});
}
@ -237,6 +239,15 @@
return res === '2160p' ? '4k' : res === '1080p' ? '1080' : res === '720p' ? '720' : 'sd';
}
// Availability differs by source: slskd has a peer (uploader); torrent/usenet seeders.
function resAvailHTML(r) {
if (r.username) {
return '<span class="vdl-res-stat vdl-res-seed"><span class="vdl-res-ico">👤</span>' + esc(r.username) +
(r.peers > 1 ? ' · ' + r.peers + ' peers' : '') + (r.slots ? ' · ' + r.slots + ' slots' : '') + '</span>';
}
return '<span class="vdl-res-stat vdl-res-seed">▲ ' + (r.seeders || 0) + ' seeders</span>';
}
// Readable card: a big resolution tile anchors it, a plain-English quality summary
// leads, the raw release name is demoted to a muted one-liner, then size/seeders.
function resultCardHTML(r) {
@ -259,7 +270,7 @@
'<div class="vdl-res-name" title="' + esc(r.title) + '">' + esc(r.title) + '</div>' +
'<div class="vdl-res-meta">' +
'<span class="vdl-res-stat"><span class="vdl-res-ico">💾</span>' + r.size_gb + ' GB</span>' +
'<span class="vdl-res-stat vdl-res-seed">▲ ' + (r.seeders || 0) + ' seeders</span>' +
resAvailHTML(r) +
(r.group ? '<span class="vdl-res-stat vdl-res-grp">' + esc(r.group) + '</span>' : '') +
'</div>' +
'</div>' +

View file

@ -3260,9 +3260,15 @@ body[data-side="video"] #soulsync-toggle { display: none; }
border: 2px solid rgba(255, 255, 255, 0.2); border-top-color: rgb(var(--accent-rgb)); animation: vdlSpin 0.7s linear infinite; }
@keyframes vdlSpin { to { transform: rotate(360deg); } }
.vdl-res-empty { font-size: 12.5px; color: rgba(255, 255, 255, 0.45); padding: 9px 2px; }
.vdl-res-head { font-size: 11.5px; font-weight: 700; color: rgba(255, 255, 255, 0.5); margin: 4px 0 10px; }
.vdl-res-head { display: flex; align-items: center; gap: 8px; font-size: 11.5px; font-weight: 700;
color: rgba(255, 255, 255, 0.5); margin: 4px 0 10px; }
.vdl-res-head strong { color: #fff; }
.vdl-res-okn { color: #8fe7af; }
.vdl-res-live, .vdl-res-demo { margin-left: auto; font-size: 10px; font-weight: 800; padding: 2px 8px; border-radius: 999px;
text-transform: uppercase; letter-spacing: 0.04em; }
.vdl-res-live { background: rgba(108, 211, 145, 0.16); color: #8fe7af; }
.vdl-res-demo { background: rgba(245, 158, 11, 0.14); color: #fbcd7a; }
.vdl-res-err { color: #fbcd7a; }
/* result row: [resolution tile] [body: summary + name + meta] [grab] */
.vdl-res { display: flex; align-items: stretch; gap: 12px; border-radius: 13px;
border: 1px solid rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.035);