Archived
Persist chat event group expansion
This commit is contained in:
@@ -11,6 +11,7 @@ export class ChatView extends LitElement {
|
|||||||
@property() sessionId = "";
|
@property() sessionId = "";
|
||||||
@query(".chat") private chat?: HTMLDivElement;
|
@query(".chat") private chat?: HTMLDivElement;
|
||||||
@state() private pinnedToBottom = true;
|
@state() private pinnedToBottom = true;
|
||||||
|
@state() private openGroupKeys = new Set<string>();
|
||||||
private suppressScrollSave = false;
|
private suppressScrollSave = false;
|
||||||
private saveScrollTimer?: number;
|
private saveScrollTimer?: number;
|
||||||
|
|
||||||
@@ -19,7 +20,8 @@ export class ChatView extends LitElement {
|
|||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected willUpdate(): void {
|
protected willUpdate(changed: Map<string, unknown>): void {
|
||||||
|
if (changed.has("sessionId")) this.openGroupKeys = this.readOpenGroupKeys();
|
||||||
this.pinnedToBottom = this.isNearBottom();
|
this.pinnedToBottom = this.isNearBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,8 +50,9 @@ export class ChatView extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderMessageGroup(messages: ChatLine[], startIndex: number) {
|
private renderMessageGroup(messages: ChatLine[], startIndex: number) {
|
||||||
|
const key = this.groupKey(startIndex);
|
||||||
return html`
|
return html`
|
||||||
<details class="msg event-group" data-index=${startIndex}>
|
<details class="msg event-group" data-index=${startIndex} ?open=${this.openGroupKeys.has(key)} @toggle=${(event: Event) => this.onGroupToggle(key, event)}>
|
||||||
<summary>
|
<summary>
|
||||||
<b class="label">events</b>
|
<b class="label">events</b>
|
||||||
<span>${summarizeChatGroup(messages)}</span>
|
<span>${summarizeChatGroup(messages)}</span>
|
||||||
@@ -79,6 +82,15 @@ export class ChatView extends LitElement {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onGroupToggle(key: string, event: Event) {
|
||||||
|
const details = event.currentTarget as HTMLDetailsElement;
|
||||||
|
const openGroupKeys = new Set(this.openGroupKeys);
|
||||||
|
if (details.open) openGroupKeys.add(key);
|
||||||
|
else openGroupKeys.delete(key);
|
||||||
|
this.openGroupKeys = openGroupKeys;
|
||||||
|
this.saveOpenGroupKeys();
|
||||||
|
}
|
||||||
|
|
||||||
private onScroll() {
|
private onScroll() {
|
||||||
this.pinnedToBottom = this.isNearBottom();
|
this.pinnedToBottom = this.isNearBottom();
|
||||||
if (!this.suppressScrollSave) this.scheduleScrollPositionSave();
|
if (!this.suppressScrollSave) this.scheduleScrollPositionSave();
|
||||||
@@ -200,5 +212,33 @@ export class ChatView extends LitElement {
|
|||||||
return `pi-web:chat-scroll:${sessionId}`;
|
return `pi-web:chat-scroll:${sessionId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private groupStorageKey(sessionId = this.sessionId): string {
|
||||||
|
return `pi-web:chat-groups:${sessionId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private groupKey(startIndex: number): string {
|
||||||
|
return `${this.sessionId}:${startIndex}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readOpenGroupKeys(): Set<string> {
|
||||||
|
if (!this.sessionId) return new Set();
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(this.groupStorageKey());
|
||||||
|
const value = raw ? JSON.parse(raw) : [];
|
||||||
|
return new Set(Array.isArray(value) ? value.filter((item) => typeof item === "string") : []);
|
||||||
|
} catch {
|
||||||
|
return new Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private saveOpenGroupKeys(): void {
|
||||||
|
if (!this.sessionId) return;
|
||||||
|
try {
|
||||||
|
localStorage.setItem(this.groupStorageKey(), JSON.stringify([...this.openGroupKeys]));
|
||||||
|
} catch {
|
||||||
|
// Ignore storage failures; group expansion should still work for this render.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static styles = chatStyles;
|
static styles = chatStyles;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user