cleanup: stats top-streamers bar list — extract inline styles
Second pass on the Statistik tab. The top-10 streamers-by-size list rendered each row as a 6-inline-style template (margin, two flex containers, two span colour overrides, two bar wrappers, two bar fills with hard-coded gradient). Extracted to a .stats-top-* family in styles.css: - .stats-top-row — outer row spacing - .stats-top-meta + .stats-top-meta-sub for the label/byte-size flex header - .stats-top-share for the muted (X.Y%) suffix - .stats-top-bar-track + .stats-top-bar-fill for the gradient progress bar (now with a width-transition for the streamer-by- streamer animation when the data refreshes) - .stats-top-bar-labels for the overlaid LIVE/VOD breakdown that gets pointer-events: none so the bar isn't accidentally hover- blocked Also picked up the "no top streamers" empty-state message and swapped its inline-style div for the existing .form-note utility class introduced in 4.6.42. Top streamers row hover state intentionally NOT added — these are read-only summary rows, not interactive ones. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7ffd52a901
commit
abc983c035
@ -71,7 +71,7 @@ function renderStatsTopStreamers(top: ArchiveStatsTopStreamer[], totalBytes: num
|
||||
if (!container) return;
|
||||
|
||||
if (top.length === 0) {
|
||||
applyHtml(container, `<div style="color: var(--text-secondary);">${escapeStatsHtml(UI_TEXT.static.statsEmpty)}</div>`);
|
||||
applyHtml(container, `<div class="form-note">${escapeStatsHtml(UI_TEXT.static.statsEmpty)}</div>`);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -80,14 +80,14 @@ function renderStatsTopStreamers(top: ArchiveStatsTopStreamer[], totalBytes: num
|
||||
const pct = Math.max(2, Math.round((s.bytes / maxBytes) * 100));
|
||||
const sharePct = totalBytes > 0 ? ((s.bytes / totalBytes) * 100).toFixed(1) : '0';
|
||||
return `
|
||||
<div style="margin-bottom: 10px;">
|
||||
<div style="display:flex; justify-content:space-between; font-size:13px; margin-bottom:4px;">
|
||||
<span><strong>${escapeStatsHtml(s.streamer)}</strong> <span style="color:var(--text-secondary);">· ${s.fileCount} ${escapeStatsHtml(UI_TEXT.static.statsFiles)}</span></span>
|
||||
<span style="color:var(--text-secondary);">${formatBytesForStats(s.bytes)} <span style="opacity:0.7;">(${sharePct}%)</span></span>
|
||||
<div class="stats-top-row">
|
||||
<div class="stats-top-meta">
|
||||
<span><strong>${escapeStatsHtml(s.streamer)}</strong> <span class="stats-top-meta-sub">· ${s.fileCount} ${escapeStatsHtml(UI_TEXT.static.statsFiles)}</span></span>
|
||||
<span class="stats-top-meta-sub">${formatBytesForStats(s.bytes)} <span class="stats-top-share">(${sharePct}%)</span></span>
|
||||
</div>
|
||||
<div style="background: var(--bg-elevated); border-radius: 3px; height: 18px; overflow: hidden; position: relative;">
|
||||
<div style="width: ${pct}%; height: 100%; background: linear-gradient(90deg, #9146ff 0%, #00c853 100%);"></div>
|
||||
${(s.liveBytes > 0 || s.vodBytes > 0) ? `<div style="position:absolute; top:0; left:8px; right:8px; height:100%; display:flex; align-items:center; gap:8px; font-size:10px; color:rgba(255,255,255,0.92); font-weight:600;">
|
||||
<div class="stats-top-bar-track">
|
||||
<div class="stats-top-bar-fill" style="width: ${pct}%;"></div>
|
||||
${(s.liveBytes > 0 || s.vodBytes > 0) ? `<div class="stats-top-bar-labels">
|
||||
${s.liveBytes > 0 ? `LIVE ${formatBytesForStats(s.liveBytes)}` : ''}
|
||||
${s.vodBytes > 0 ? `VOD ${formatBytesForStats(s.vodBytes)}` : ''}
|
||||
</div>` : ''}
|
||||
|
||||
@ -2253,6 +2253,64 @@ select option {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* Top-streamers bar list — one row per streamer, label row above a
|
||||
purple-to-green gradient bar. Live/VOD breakdown labels sit
|
||||
overlaid on top of the bar for a compact two-column read. */
|
||||
.stats-top-row {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.stats-top-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.stats-top-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
margin-bottom: 4px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.stats-top-meta-sub {
|
||||
color: var(--text-secondary);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.stats-top-share {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.stats-top-bar-track {
|
||||
background: var(--bg-elevated);
|
||||
border-radius: 3px;
|
||||
height: 18px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.stats-top-bar-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #9146ff 0%, #00c853 100%);
|
||||
transition: width 0.4s ease-out;
|
||||
}
|
||||
|
||||
.stats-top-bar-labels {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.92);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.3px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Old generic scrollbar rules were dead — superseded by the
|
||||
purple-themed *::-webkit-scrollbar block further down the file.
|
||||
Removed to avoid confusion when someone greps for scrollbar styles. */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user