Archived
feat: auto-expand live event groups
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@jmfederico/pi-web": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Expand the live trailing events group while a session is active, then collapse it again once readable conversation output appears.
|
||||||
@@ -111,17 +111,18 @@ export class ChatView extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override render() {
|
override render() {
|
||||||
|
const groups = this.groupedMessages();
|
||||||
return html`
|
return html`
|
||||||
<div class="chat-wrap">
|
<div class="chat-wrap">
|
||||||
${this.renderHistoryIndicator()}
|
${this.renderHistoryIndicator()}
|
||||||
<div class="chat" @scroll=${() => { this.onScroll(); }} @wheel=${(event: WheelEvent) => { this.onWheel(event); }} @touchstart=${(event: TouchEvent) => { this.onTouchStart(event); }} @touchmove=${(event: TouchEvent) => { this.onTouchMove(event); }}>
|
<div class="chat" @scroll=${() => { this.onScroll(); }} @wheel=${(event: WheelEvent) => { this.onWheel(event); }} @touchstart=${(event: TouchEvent) => { this.onTouchStart(event); }} @touchmove=${(event: TouchEvent) => { this.onTouchMove(event); }}>
|
||||||
${this.renderHistoryBoundary()}
|
${this.renderHistoryBoundary()}
|
||||||
${repeat(
|
${repeat(
|
||||||
this.groupedMessages(),
|
groups,
|
||||||
(group) => group.kind === "message" ? this.messageAnchorKey(group.index) : this.groupAnchorKey(group.endIndex),
|
(group) => group.kind === "message" ? this.messageAnchorKey(group.index) : this.groupAnchorKey(group.endIndex),
|
||||||
(group) => group.kind === "message"
|
(group, index) => group.kind === "message"
|
||||||
? this.renderMessage(group.message, group.index)
|
? this.renderMessage(group.message, group.index)
|
||||||
: this.renderMessageGroup(group.messages, group.startIndex, group.endIndex),
|
: this.renderMessageGroup(group.messages, group.startIndex, group.endIndex, this.isLiveTailGroup(groups, index)),
|
||||||
)}
|
)}
|
||||||
${this.renderQueuedMessages()}
|
${this.renderQueuedMessages()}
|
||||||
${this.renderSessionActivity()}
|
${this.renderSessionActivity()}
|
||||||
@@ -139,6 +140,17 @@ export class ChatView extends LitElement {
|
|||||||
return this.groupedMessagesCache;
|
return this.groupedMessagesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private isLiveTailGroup(groups: ChatGroup[], index: number): boolean {
|
||||||
|
return index === groups.length - 1 && this.isSessionLive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private isSessionLive(): boolean {
|
||||||
|
return this.status?.isStreaming === true
|
||||||
|
|| this.status?.isCompacting === true
|
||||||
|
|| this.status?.isBashRunning === true
|
||||||
|
|| this.activity?.phase === "active";
|
||||||
|
}
|
||||||
|
|
||||||
private renderActivityDock() {
|
private renderActivityDock() {
|
||||||
const state = this.activityState();
|
const state = this.activityState();
|
||||||
if (state === undefined) return null;
|
if (state === undefined) return null;
|
||||||
@@ -259,13 +271,14 @@ export class ChatView extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderMessageGroup(messages: ChatLine[], startIndex: number, endIndex: number) {
|
private renderMessageGroup(messages: ChatLine[], startIndex: number, endIndex: number, autoOpen: boolean) {
|
||||||
const key = this.groupKey(endIndex);
|
const key = this.groupKey(endIndex);
|
||||||
|
const open = autoOpen || this.openGroupKeys.has(key);
|
||||||
return html`
|
return html`
|
||||||
${this.renderScrollMarker(this.groupScrollMarkerId(endIndex))}
|
${this.renderScrollMarker(this.groupScrollMarkerId(endIndex))}
|
||||||
<details class="msg event-group" data-index=${startIndex} data-anchor-key=${this.groupAnchorKey(endIndex)} ?open=${this.openGroupKeys.has(key)} @toggle=${(event: Event) => { this.onGroupToggle(key, event); }}>
|
<details class=${autoOpen ? "msg event-group live" : "msg event-group"} data-index=${startIndex} data-anchor-key=${this.groupAnchorKey(endIndex)} ?open=${open} @toggle=${(event: Event) => { this.onGroupToggle(key, event, autoOpen); }}>
|
||||||
<summary>
|
<summary>
|
||||||
<b class="label">events</b>
|
<b class="label">${autoOpen ? "live events" : "events"}</b>
|
||||||
<span>${summarizeChatGroup(messages)}</span>
|
<span>${summarizeChatGroup(messages)}</span>
|
||||||
</summary>
|
</summary>
|
||||||
<div class="group-body">
|
<div class="group-body">
|
||||||
@@ -410,12 +423,15 @@ export class ChatView extends LitElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private onGroupToggle(key: string, event: Event) {
|
private onGroupToggle(key: string, event: Event, autoOpen: boolean) {
|
||||||
const details = event.currentTarget;
|
const details = event.currentTarget;
|
||||||
if (!(details instanceof HTMLDetailsElement)) return;
|
if (!(details instanceof HTMLDetailsElement)) return;
|
||||||
|
if (autoOpen && details.open) return;
|
||||||
const openGroupKeys = new Set(this.openGroupKeys);
|
const openGroupKeys = new Set(this.openGroupKeys);
|
||||||
|
const wasOpen = openGroupKeys.has(key);
|
||||||
if (details.open) openGroupKeys.add(key);
|
if (details.open) openGroupKeys.add(key);
|
||||||
else openGroupKeys.delete(key);
|
else openGroupKeys.delete(key);
|
||||||
|
if (openGroupKeys.has(key) === wasOpen) return;
|
||||||
this.openGroupKeys = openGroupKeys;
|
this.openGroupKeys = openGroupKeys;
|
||||||
this.saveOpenGroupKeys();
|
this.saveOpenGroupKeys();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user