Long chats stay fast; search in a chat; media overview
Performance (measured with 5,900 messages: open 9 s -> 0.7 s, typing 440 ms -> 25 ms)
- GET /sessions/{id}?limit=N loads the end of a chat (from the last summary
on, at most N); /sessions/{id}/messages?before|after|around loads more
(scrolling up stops at a summary unless asked). Without parameters the
full history as before (terminal client).
- Chat view: memoised message list (typing, streaming and status changes no
longer re-render the history), finished turns fold into "N steps · M files"
with the answer visible, tool card bodies and summaries are built only when
opened, scroll-to-bottom only when content changes.
Search: /sessions/{id}/search over the whole chat; a hit loads its part
(around) and marks the message, "back to the latest messages" returns.
Media: /sessions/{id}/media lists images, videos and audio of a chat and its
subagents (generated images, tool output, files written, media in answers,
attachments); ⋯ -> Media shows them with filters, a large view and a jump to
the message.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
6e9eda28b5
commit
3b0764450a
14 files changed
+1278
-99
No files matched your search
@@ -4185,3 +4185,216 @@ span.chat-tab > button {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- long chats ------------------------------------------------------------------
|
||||
* Finished turns fold into one line, older messages load on demand, search hits. */
|
||||
.work-block > .work-head {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 2px 0;
|
||||
margin-bottom: 4px;
|
||||
font-size: 12.5px;
|
||||
color: var(--muted);
|
||||
cursor: pointer;
|
||||
}
|
||||
.work-block > .work-head:hover {
|
||||
color: var(--fg1);
|
||||
}
|
||||
.work-block.open {
|
||||
border-left: 2px solid var(--bg2);
|
||||
padding-left: 10px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.older-loader {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 6px 0 12px;
|
||||
}
|
||||
.back-to-latest {
|
||||
position: sticky;
|
||||
bottom: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin: 10px auto 0;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.msg.highlight,
|
||||
.summary-divider[data-mid].highlight {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 4px;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
.chat-search {
|
||||
border-bottom: 1px solid var(--bg2);
|
||||
padding: 6px 12px;
|
||||
background: var(--bg0);
|
||||
}
|
||||
.chat-search > .row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.chat-search > .row input {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
.chat-search-hits {
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
.chat-search-hits button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 2px;
|
||||
text-align: left;
|
||||
border: none;
|
||||
background: transparent;
|
||||
padding: 6px 8px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.chat-search-hits button:hover {
|
||||
background: var(--bg1);
|
||||
}
|
||||
.chat-search-hits .who {
|
||||
font-size: 11.5px;
|
||||
color: var(--muted);
|
||||
}
|
||||
.chat-search-hits .snippet {
|
||||
font-size: 13px;
|
||||
color: var(--fg1);
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
/* --- media overview of a chat --------------------------------------------------- */
|
||||
.media-gallery {
|
||||
width: min(1100px, calc(100vw - 24px));
|
||||
height: min(820px, calc(100dvh - 24px));
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
.media-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.media-head h3 {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
.media-filters {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
}
|
||||
.media-filters .chip-btn {
|
||||
padding: 3px 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.media-filters small {
|
||||
color: var(--muted);
|
||||
margin-left: 2px;
|
||||
}
|
||||
.media-grid {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
grid-auto-rows: 150px;
|
||||
gap: 8px;
|
||||
}
|
||||
.media-tile {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
background: var(--bg2);
|
||||
border: 1px solid var(--bg3);
|
||||
}
|
||||
.media-tile img,
|
||||
.media-tile video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.media-tile .media-play {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
margin: auto;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
color: #fff;
|
||||
filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
|
||||
}
|
||||
.media-audio {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
height: 100%;
|
||||
padding: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--fg2);
|
||||
word-break: break-all;
|
||||
}
|
||||
.media-audio .icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
color: var(--accent);
|
||||
}
|
||||
.media-viewer {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.media-stage {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--bg1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
.media-stage img,
|
||||
.media-stage video {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
.media-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
font-size: 12.5px;
|
||||
color: var(--fg2);
|
||||
}
|
||||
.media-bar .grow {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
Reference in new issue
Block a user