Archived
Refresh chat history after reconnect
This commit is contained in:
@@ -68,6 +68,10 @@ export class PiWebApp extends LitElement {
|
|||||||
private terminalAutoStartWorkspaceId: string | undefined;
|
private terminalAutoStartWorkspaceId: string | undefined;
|
||||||
private readonly plugins = createPluginRegistry();
|
private readonly plugins = createPluginRegistry();
|
||||||
private readonly onPopState = () => void this.withChatScrollTransition(() => this.restoreRoute(false));
|
private readonly onPopState = () => void this.withChatScrollTransition(() => this.restoreRoute(false));
|
||||||
|
private readonly onFocus = () => { void this.sessions.refreshSelectedSession(); };
|
||||||
|
private readonly onVisibilityChange = () => {
|
||||||
|
if (document.visibilityState === "visible") void this.sessions.refreshSelectedSession();
|
||||||
|
};
|
||||||
private readonly onKeyDown = (event: KeyboardEvent) => {
|
private readonly onKeyDown = (event: KeyboardEvent) => {
|
||||||
if (this.keyboard.handle(event, this.getActions())) {
|
if (this.keyboard.handle(event, this.getActions())) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@@ -78,6 +82,8 @@ export class PiWebApp extends LitElement {
|
|||||||
override connectedCallback(): void {
|
override connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
window.addEventListener("popstate", this.onPopState);
|
window.addEventListener("popstate", this.onPopState);
|
||||||
|
window.addEventListener("focus", this.onFocus);
|
||||||
|
document.addEventListener("visibilitychange", this.onVisibilityChange);
|
||||||
window.addEventListener("keydown", this.onKeyDown);
|
window.addEventListener("keydown", this.onKeyDown);
|
||||||
this.connectRealtime();
|
this.connectRealtime();
|
||||||
void this.loadExternalPlugins();
|
void this.loadExternalPlugins();
|
||||||
@@ -86,6 +92,8 @@ export class PiWebApp extends LitElement {
|
|||||||
|
|
||||||
override disconnectedCallback(): void {
|
override disconnectedCallback(): void {
|
||||||
window.removeEventListener("popstate", this.onPopState);
|
window.removeEventListener("popstate", this.onPopState);
|
||||||
|
window.removeEventListener("focus", this.onFocus);
|
||||||
|
document.removeEventListener("visibilitychange", this.onVisibilityChange);
|
||||||
window.removeEventListener("keydown", this.onKeyDown);
|
window.removeEventListener("keydown", this.onKeyDown);
|
||||||
this.keyboard.reset();
|
this.keyboard.reset();
|
||||||
this.sessions.dispose();
|
this.sessions.dispose();
|
||||||
|
|||||||
@@ -74,7 +74,11 @@ export class SessionController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const buffered: SessionUiEvent[] = [];
|
const buffered: SessionUiEvent[] = [];
|
||||||
this.socket.connect(session.id, (event) => buffered.push(event));
|
this.socket.connect(
|
||||||
|
session.id,
|
||||||
|
(event) => buffered.push(event),
|
||||||
|
() => { void this.refreshSelectedSession(session.id); },
|
||||||
|
);
|
||||||
const [page, status] = await Promise.all([api.messages(session.id, { limit: MESSAGE_PAGE_SIZE }), api.status(session.id)]);
|
const [page, status] = await Promise.all([api.messages(session.id, { limit: MESSAGE_PAGE_SIZE }), api.status(session.id)]);
|
||||||
if (seq !== this.selectionSeq || this.getState().selectedSession?.id !== session.id) return;
|
if (seq !== this.selectionSeq || this.getState().selectedSession?.id !== session.id) return;
|
||||||
const history = this.mergeAndCacheHistory(session.id, page);
|
const history = this.mergeAndCacheHistory(session.id, page);
|
||||||
@@ -278,6 +282,28 @@ export class SessionController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async refreshSelectedSession(sessionId = this.getState().selectedSession?.id): Promise<void> {
|
||||||
|
const session = this.getState().selectedSession;
|
||||||
|
if (sessionId === undefined || session?.id !== sessionId || session.archived === true) return;
|
||||||
|
try {
|
||||||
|
this.flushPendingTranscriptEvents();
|
||||||
|
const [page, status] = await Promise.all([api.messages(sessionId, { limit: MESSAGE_PAGE_SIZE }), api.status(sessionId)]);
|
||||||
|
if (this.getState().selectedSession?.id !== sessionId) return;
|
||||||
|
const history = this.mergeAndCacheHistory(sessionId, page);
|
||||||
|
this.setState({
|
||||||
|
messages: normalizeMessages(history.messages),
|
||||||
|
messagePageStart: history.start,
|
||||||
|
messagePageTotal: history.total,
|
||||||
|
status,
|
||||||
|
activity: this.getState().sessionActivities[sessionId],
|
||||||
|
isReceivingPartialStream: status.isStreaming,
|
||||||
|
});
|
||||||
|
this.applyStatus(status);
|
||||||
|
} catch (error) {
|
||||||
|
if (this.getState().selectedSession?.id === sessionId) this.setState({ error: String(error) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private replaceSession(session: SessionInfo) {
|
private replaceSession(session: SessionInfo) {
|
||||||
const current = this.getState().selectedSession;
|
const current = this.getState().selectedSession;
|
||||||
this.setState({
|
this.setState({
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ export class SessionSocket {
|
|||||||
private reconnectTimer?: number;
|
private reconnectTimer?: number;
|
||||||
private reconnectDelay = 500;
|
private reconnectDelay = 500;
|
||||||
private shouldReconnect = false;
|
private shouldReconnect = false;
|
||||||
|
private hasOpened = false;
|
||||||
|
private onReconnect: (() => void) | undefined;
|
||||||
|
|
||||||
connect(sessionId: string, onEvent: (event: SessionUiEvent) => void): void {
|
connect(sessionId: string, onEvent: (event: SessionUiEvent) => void, onReconnect?: () => void): void {
|
||||||
this.close();
|
this.close();
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
this.onEvent = onEvent;
|
this.onEvent = onEvent;
|
||||||
|
this.onReconnect = onReconnect;
|
||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
this.open();
|
this.open();
|
||||||
}
|
}
|
||||||
@@ -30,6 +33,8 @@ export class SessionSocket {
|
|||||||
this.socket = undefined;
|
this.socket = undefined;
|
||||||
this.sessionId = undefined;
|
this.sessionId = undefined;
|
||||||
this.onEvent = undefined;
|
this.onEvent = undefined;
|
||||||
|
this.onReconnect = undefined;
|
||||||
|
this.hasOpened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private open(): void {
|
private open(): void {
|
||||||
@@ -38,6 +43,8 @@ export class SessionSocket {
|
|||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
socket.onopen = () => {
|
socket.onopen = () => {
|
||||||
this.reconnectDelay = 500;
|
this.reconnectDelay = 500;
|
||||||
|
if (this.hasOpened) this.onReconnect?.();
|
||||||
|
this.hasOpened = true;
|
||||||
};
|
};
|
||||||
socket.onmessage = (message) => void this.handleMessage(message.data);
|
socket.onmessage = (message) => void this.handleMessage(message.data);
|
||||||
socket.onerror = () => { socket.close(); };
|
socket.onerror = () => { socket.close(); };
|
||||||
|
|||||||
Reference in New Issue
Block a user