feat: in-app chat replay viewer — read .chat.json/.chat.jsonl without leaving the app
Up to now, the app saved chat data (4.6.2 VOD replay, 4.6.3 live
capture) but had no way to view it — users had to open the file in
Notepad or write a custom parser. New in-app modal closes that loop:
queue items with a sibling .chat.json or .chat.jsonl get a "View
chat" button next to Open file / Show in folder; click pops a modal
with a scrollable, filterable, formatted message list.
Server:
- New ipcMain.handle("read-chat-file") parses both formats. JSON
Lines (.jsonl) is split per line, header row skipped, malformed
lines silently dropped — that way a partial / killed live capture
still renders. JSON object (.json) is the VOD replay shape with
messages array. Hard-capped at 50k messages so a multi-day archive
can't kill the renderer; truncation is reported via {truncated,
total} in the result.
Renderer:
- New chatViewerModal in index.html — full-height list with a filter
input + status line.
- openChatViewer(filePath, title) loads the file via IPC, normalises
the message shape (supports both .chat.json and .chat.jsonl
fields), renders in 500-message chunks via setTimeout(0) so the
main thread stays responsive on a 30k-message archive.
- Each row: time marker (offset for replays, wall-clock for live),
user (in their stored color), message text. Non-msg event types
(subs, raids, clears) get a faint italic [type] tag.
- Filter substring-matches user OR text, case-insensitive, instant.
- Esc + outside-click + the close-x dismiss; Esc handler in
closeTopmostOpenModal lists the chat viewer first so a user
with multiple modals open closes the foreground one.
Queue UI:
- renderQueueItemFileActions detects sibling chat files (regex
/\.chat\.json(l)?$/) in item.outputFiles and surfaces the View
chat button. The button is shown for both 4.6.2-style replays
and 4.6.3-style live captures because both formats parse.
DE + EN locales for the button label, loading state, error,
message count, truncation suffix.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
dc0b92d5a4
commit
3129c9b5be
@@ -136,6 +136,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat Replay Viewer Modal -->
|
||||
<div class="modal-overlay" id="chatViewerModal">
|
||||
<div class="modal" style="max-width: 800px; height: 80vh; display:flex; flex-direction:column;">
|
||||
<button class="modal-close" onclick="closeChatViewer()">x</button>
|
||||
<h2 id="chatViewerTitle" style="margin-top:0;">Chat replay</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>
|
||||
</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>
|
||||
</div>
|
||||
|
||||
<!-- Template Guide Modal -->
|
||||
<div class="modal-overlay" id="templateGuideModal">
|
||||
<div class="modal template-guide-modal">
|
||||
|
||||
Reference in New Issue
Block a user