Merge pull request #1288 from bradleypriest/pr/chat-session-url
ui(chat): persist session in URL and stabilize picker
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
import { html } from "lit";
|
||||
import { repeat } from "lit/directives/repeat.js";
|
||||
|
||||
import type { AppViewState } from "./app-view-state";
|
||||
import { iconForTab, pathForTab, titleForTab, type Tab } from "./navigation";
|
||||
import { loadChatHistory } from "./controllers/chat";
|
||||
import { syncUrlWithSessionKey } from "./app-settings";
|
||||
import type { SessionsListResult } from "./types";
|
||||
import type { ThemeMode } from "./theme";
|
||||
import type { ThemeTransitionContext } from "./theme-transition";
|
||||
@@ -64,10 +66,13 @@ export function renderChatControls(state: AppViewState) {
|
||||
sessionKey: next,
|
||||
lastActiveSessionKey: next,
|
||||
});
|
||||
syncUrlWithSessionKey(state, next, true);
|
||||
void loadChatHistory(state);
|
||||
}}
|
||||
>
|
||||
${sessionOptions.map(
|
||||
${repeat(
|
||||
sessionOptions,
|
||||
(entry) => entry.key,
|
||||
(entry) =>
|
||||
html`<option value=${entry.key}>
|
||||
${entry.displayName ?? entry.key}
|
||||
@@ -119,9 +124,11 @@ function resolveSessionOptions(sessionKey: string, sessions: SessionsListResult
|
||||
const seen = new Set<string>();
|
||||
const options: Array<{ key: string; displayName?: string }> = [];
|
||||
|
||||
const resolvedCurrent = sessions?.sessions?.find((s) => s.key === sessionKey);
|
||||
|
||||
// Add current session key first
|
||||
seen.add(sessionKey);
|
||||
options.push({ key: sessionKey });
|
||||
options.push({ key: sessionKey, displayName: resolvedCurrent?.displayName });
|
||||
|
||||
// Add sessions from the result
|
||||
if (sessions?.sessions) {
|
||||
|
||||
@@ -85,9 +85,12 @@ export function applySettingsFromUrl(host: SettingsHost) {
|
||||
const session = sessionRaw.trim();
|
||||
if (session) {
|
||||
host.sessionKey = session;
|
||||
applySettings(host, {
|
||||
...host.settings,
|
||||
sessionKey: session,
|
||||
lastActiveSessionKey: session,
|
||||
});
|
||||
}
|
||||
params.delete("session");
|
||||
shouldCleanUrl = true;
|
||||
}
|
||||
|
||||
if (!shouldCleanUrl) return;
|
||||
@@ -225,6 +228,18 @@ export function onPopState(host: SettingsHost) {
|
||||
if (typeof window === "undefined") return;
|
||||
const resolved = tabFromPath(window.location.pathname, host.basePath);
|
||||
if (!resolved) return;
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
const session = url.searchParams.get("session")?.trim();
|
||||
if (session) {
|
||||
host.sessionKey = session;
|
||||
applySettings(host, {
|
||||
...host.settings,
|
||||
sessionKey: session,
|
||||
lastActiveSessionKey: session,
|
||||
});
|
||||
}
|
||||
|
||||
setTabFromRoute(host, resolved);
|
||||
}
|
||||
|
||||
@@ -241,9 +256,18 @@ export function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {
|
||||
if (typeof window === "undefined") return;
|
||||
const targetPath = normalizePath(pathForTab(tab, host.basePath));
|
||||
const currentPath = normalizePath(window.location.pathname);
|
||||
if (currentPath === targetPath) return;
|
||||
const url = new URL(window.location.href);
|
||||
url.pathname = targetPath;
|
||||
|
||||
if (tab === "chat" && host.sessionKey) {
|
||||
url.searchParams.set("session", host.sessionKey);
|
||||
} else {
|
||||
url.searchParams.delete("session");
|
||||
}
|
||||
|
||||
if (currentPath !== targetPath) {
|
||||
url.pathname = targetPath;
|
||||
}
|
||||
|
||||
if (replace) {
|
||||
window.history.replaceState({}, "", url.toString());
|
||||
} else {
|
||||
@@ -251,6 +275,18 @@ export function syncUrlWithTab(host: SettingsHost, tab: Tab, replace: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
export function syncUrlWithSessionKey(
|
||||
host: SettingsHost,
|
||||
sessionKey: string,
|
||||
replace: boolean,
|
||||
) {
|
||||
if (typeof window === "undefined") return;
|
||||
const url = new URL(window.location.href);
|
||||
url.searchParams.set("session", sessionKey);
|
||||
if (replace) window.history.replaceState({}, "", url.toString());
|
||||
else window.history.pushState({}, "", url.toString());
|
||||
}
|
||||
|
||||
export async function loadOverview(host: SettingsHost) {
|
||||
await Promise.all([
|
||||
loadChannels(host as unknown as ClawdbotApp, false),
|
||||
|
||||
Reference in New Issue
Block a user