cleanup: extract events/chat viewer inline styles + drop dead var

The events-viewer and chat-viewer modals were each carrying ~5 inline
styled elements (modal sizing, status text, list container, filter
row + filter input) duplicated between the two modals. Edits to one
viewer left the other drifting visually.

Extracted to a shared .viewer-modal* family in styles.css:
- .viewer-modal sets the column flex layout
- .viewer-modal-events / .viewer-modal-chat set their own sizing
- .viewer-modal-title / .viewer-modal-status / .viewer-modal-list +
  inline + chat list variants for the data area
- .viewer-modal-filter-row + .viewer-modal-filter-input for the
  chat viewer's filter

Zero visual change; just stops the two viewers from drifting and
unblocks future polish (skeleton states inside the list, sticky
filter row, etc.) without an inline-edit-by-inline-edit grind.

Side: removed lastArchiveStatsScannedAt module variable in
renderer-stats.ts. It was assigned in refreshArchiveStats but never
read anywhere — leftover from an early plan to compare against a
previous timestamp before refreshing. The renderer-rendered "Last
scan" line reads stats.scannedAt directly. Dead, removed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
xRangerDE 2026-05-11 02:05:37 +02:00
parent 0ae0f8bb7d
commit ee8f9425fc
3 changed files with 78 additions and 13 deletions

View File

@ -115,24 +115,24 @@
<!-- Events Viewer Modal -->
<div class="modal-overlay" id="eventsViewerModal" role="dialog" aria-modal="true" aria-labelledby="eventsViewerTitle">
<div class="modal" style="max-width: 700px; max-height: 80vh; display:flex; flex-direction:column;">
<div class="modal viewer-modal viewer-modal-events">
<button class="modal-close modal-close-localizable" aria-label="Close" onclick="closeEventsViewer()">x</button>
<h2 id="eventsViewerTitle" style="margin-top:0;"></h2>
<div id="eventsViewerStatus" style="color:var(--text-secondary); font-size:12px; margin-bottom:8px;"></div>
<div id="eventsViewerList" style="flex:1; overflow-y:auto; background: var(--bg-main); border:1px solid var(--border-soft); border-radius:6px; padding:8px;"></div>
<h2 id="eventsViewerTitle" class="viewer-modal-title"></h2>
<div id="eventsViewerStatus" class="viewer-modal-status"></div>
<div id="eventsViewerList" class="viewer-modal-list"></div>
</div>
</div>
<!-- Chat Replay Viewer Modal -->
<div class="modal-overlay" id="chatViewerModal" role="dialog" aria-modal="true" aria-labelledby="chatViewerTitle">
<div class="modal" style="max-width: 800px; height: 80vh; display:flex; flex-direction:column;">
<div class="modal viewer-modal viewer-modal-chat">
<button class="modal-close modal-close-localizable" aria-label="Close" onclick="closeChatViewer()">x</button>
<h2 id="chatViewerTitle" style="margin-top:0;"></h2>
<div class="form-row" style="margin-bottom:8px; gap:8px; flex-wrap:wrap; align-items:center;">
<input type="text" id="chatViewerFilter" placeholder="Filter..." oninput="onChatViewerFilterChange()" style="flex:1; min-width:160px; background: var(--bg-card); border:1px solid var(--border-soft); border-radius:6px; padding:6px 10px; color:var(--text); font-size:13px;">
<span id="chatViewerStatus" style="color:var(--text-secondary); font-size:12px;"></span>
<h2 id="chatViewerTitle" class="viewer-modal-title"></h2>
<div class="viewer-modal-filter-row">
<input type="text" id="chatViewerFilter" class="viewer-modal-filter-input" placeholder="Filter..." oninput="onChatViewerFilterChange()">
<span id="chatViewerStatus" class="viewer-modal-status viewer-modal-status-inline"></span>
</div>
<div id="chatViewerList" style="flex:1; overflow-y:auto; background: var(--bg-main); border:1px solid var(--border-soft); border-radius:6px; padding:8px; font-family: 'Consolas', monospace; font-size: 12px;"></div>
<div id="chatViewerList" class="viewer-modal-list viewer-modal-list-chat"></div>
</div>
</div>

View File

@ -1,5 +1,3 @@
let lastArchiveStatsScannedAt = '';
// Trivial property-access wrapper. The codebase's renderer relies on
// HTML-string rendering throughout (queue items, settings cards, etc.),
// and all dynamic inputs are passed through escapeStatsHtml below — no
@ -20,7 +18,6 @@ async function refreshArchiveStats(): Promise<void> {
try {
const stats = await window.api.getArchiveStats();
renderArchiveStats(stats);
lastArchiveStatsScannedAt = stats.scannedAt;
} catch (e) {
const summary = document.getElementById('statsSummaryGrid');
if (summary) summary.textContent = `Fehler: ${String(e)}`;

View File

@ -324,6 +324,74 @@ body {
margin-top: 10px;
}
/* ============================================
EVENTS / CHAT VIEWER MODALS shared structure
============================================
Both viewers used to roll their own inline-styled list container
+ status row. Extracted into a small shared family so the look
stays consistent if either one is touched independently later. */
.viewer-modal {
display: flex;
flex-direction: column;
}
.viewer-modal-events {
max-width: 700px;
max-height: 80vh;
}
.viewer-modal-chat {
max-width: 800px;
height: 80vh;
}
.viewer-modal-title {
margin-top: 0;
}
.viewer-modal-status {
color: var(--text-secondary);
font-size: 12px;
margin-bottom: 8px;
}
.viewer-modal-status-inline {
margin-bottom: 0;
}
.viewer-modal-list {
flex: 1;
overflow-y: auto;
background: var(--bg-main);
border: 1px solid var(--border-soft);
border-radius: 6px;
padding: 8px;
}
.viewer-modal-list-chat {
font-family: 'Consolas', 'Segoe UI Mono', monospace;
font-size: 12px;
}
.viewer-modal-filter-row {
display: flex;
margin-bottom: 8px;
gap: 8px;
flex-wrap: wrap;
align-items: center;
}
.viewer-modal-filter-input {
flex: 1;
min-width: 160px;
background: var(--bg-card);
border: 1px solid var(--border-soft);
border-radius: 6px;
padding: 6px 10px;
color: var(--text);
font-size: 13px;
}
.streamer-item .remove {
margin-left: auto;
opacity: 0;