ui: add media type chip group to streams header (Movies/Shows/Music/Live)
Purple-accented chips, ordered Movies → Shows → Music → Live, with per-index shade variation matching the other chip groups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
f0f136f28a
commit
52cc6b4721
@@ -756,9 +756,11 @@ mark { background: #5d4037; color: #ffcc80; border-radius: 2px; }
|
||||
.vv-device-sep { color: #2a2a2a; font-size: 12px; margin: 0 2px; user-select: none; }
|
||||
/* shared chip geometry */
|
||||
.vv-device-chip,
|
||||
.vv-chip-device, .vv-chip-res, .vv-chip-codec {
|
||||
.vv-chip-device, .vv-chip-res, .vv-chip-codec, .vv-chip-mtype {
|
||||
font-size: 10px; padding: 1px 7px; border-radius: 10px;
|
||||
white-space: nowrap; border: 1px solid; }
|
||||
/* media type — purple */
|
||||
.vv-chip-mtype { color: #9a6abf; background: #1a0d2e; border-color: #3a1e55; }
|
||||
/* device — blue */
|
||||
.vv-chip-device { color: #5a9ec8; background: #0d1e2e; border-color: #1c3f5c; }
|
||||
/* resolution — teal */
|
||||
|
||||
@@ -1451,9 +1451,10 @@ function vvRenderStreams() {
|
||||
// shades[0] = base bg, shades[1] = slightly lighter, cycling per index
|
||||
function vvChipShade(cls, i) {
|
||||
const shades = {
|
||||
'vv-chip-device': ['#0d1e2e', '#112436'],
|
||||
'vv-chip-res': ['#0b1e1c', '#0e2422'],
|
||||
'vv-chip-codec': ['#201500', '#261900'],
|
||||
'vv-chip-device': ['#0d1e2e', '#112436'],
|
||||
'vv-chip-res': ['#0b1e1c', '#0e2422'],
|
||||
'vv-chip-codec': ['#201500', '#261900'],
|
||||
'vv-chip-mtype': ['#1a0d2e', '#1f1136'],
|
||||
};
|
||||
const bg = (shades[cls] ?? ['',''])[i % 2];
|
||||
return bg ? ` style="background:${bg};"` : '';
|
||||
@@ -1512,6 +1513,27 @@ function vvRenderStreams() {
|
||||
.join('');
|
||||
const codecSection = codecBar ? `<span class="vv-device-sep">·</span>${codecBar}` : '';
|
||||
|
||||
// Media type summary — Movies, Shows, Music, Live
|
||||
function vvMediaType(t) {
|
||||
if (!t) return null;
|
||||
const lc = t.toLowerCase();
|
||||
if (lc === 'movie') return 'Movies';
|
||||
if (lc === 'episode') return 'Shows';
|
||||
if (lc === 'audio' || lc === 'track' || lc === 'musicvideo') return 'Music';
|
||||
if (lc === 'livetvprogram' || lc === 'tvchannel' || lc === 'livetv' || lc === 'recording') return 'Live';
|
||||
return null;
|
||||
}
|
||||
const mtypeCounts = {};
|
||||
sessions.forEach(s => {
|
||||
const mt = vvMediaType(s.type || '');
|
||||
if (mt) mtypeCounts[mt] = (mtypeCounts[mt] || 0) + 1;
|
||||
});
|
||||
const mtypeOrder = ['Movies', 'Shows', 'Music', 'Live'];
|
||||
const mtypeBar = mtypeOrder.filter(mt => mtypeCounts[mt])
|
||||
.map((mt, i) => vvChip('vv-chip-mtype', `${mtypeCounts[mt]} ${mt}`, i))
|
||||
.join('');
|
||||
const mtypeSection = mtypeBar ? `<span class="vv-device-sep">·</span>${mtypeBar}` : '';
|
||||
|
||||
if (sessions.length === 0) {
|
||||
el.innerHTML = `<div class="vv-stream-servers">${badges}</div>`
|
||||
+ '<p class="vv-stream-empty">Nothing playing</p>';
|
||||
@@ -1571,7 +1593,7 @@ function vvRenderStreams() {
|
||||
? `<div style="font-size:10px;color:#555;margin-top:4px;">+${sessions.length - 12} more not shown</div>`
|
||||
: '';
|
||||
|
||||
el.innerHTML = `<div class="vv-stream-servers">${badges}${deviceSection}${resSection}${codecSection}</div>
|
||||
el.innerHTML = `<div class="vv-stream-servers">${badges}${mtypeSection}${deviceSection}${resSection}${codecSection}</div>
|
||||
<div style="display:flex;gap:10px;">${sCols.map(vvStreamCol).join('')}</div>${overflow}`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user