Improve session refresh and UI polish
This commit is contained in:
16
src/App.tsx
16
src/App.tsx
@@ -63,6 +63,7 @@ import {
|
||||
agents,
|
||||
getSessionInfo,
|
||||
isSessionMessagesLoading,
|
||||
fetchSessions,
|
||||
} from "./stores/sessions"
|
||||
import { isSessionBusy } from "./stores/session-status"
|
||||
import { setupTabKeyboardShortcuts } from "./lib/keyboard"
|
||||
@@ -461,13 +462,24 @@ const App: Component = () => {
|
||||
const sessions = getSessions(instanceId)
|
||||
const session = sessions.find((s) => s.id === sessionId)
|
||||
|
||||
const isParent = session?.parentId === null
|
||||
if (!session) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isParent) {
|
||||
const parentSessionId = session.parentId ?? session.id
|
||||
const parentSession = sessions.find((s) => s.id === parentSessionId)
|
||||
|
||||
if (!parentSession || parentSession.parentId !== null) {
|
||||
return
|
||||
}
|
||||
|
||||
clearActiveParentSession(instanceId)
|
||||
|
||||
try {
|
||||
await fetchSessions(instanceId)
|
||||
} catch (error) {
|
||||
console.error("Failed to refresh sessions after closing:", error)
|
||||
}
|
||||
}
|
||||
|
||||
function setupCommands() {
|
||||
|
||||
@@ -545,15 +545,14 @@ export default function MessageStream(props: MessageStreamProps) {
|
||||
return (
|
||||
<div class="message-stream-container">
|
||||
<div class="connection-status">
|
||||
<div class="connection-status-text flex items-center gap-2 text-sm font-medium">
|
||||
<div class="connection-status-text connection-status-info flex items-center gap-2 text-sm font-medium">
|
||||
<span>{formattedSessionInfo()}</span>
|
||||
</div>
|
||||
<div class="flex-1" />
|
||||
<div class="connection-status-text flex items-center gap-2 text-sm font-medium">
|
||||
<div class="connection-status-text connection-status-shortcut flex items-center gap-2 text-sm font-medium">
|
||||
<span>Command Palette</span>
|
||||
<Kbd shortcut="cmd+shift+p" />
|
||||
</div>
|
||||
<div class="flex-1 flex items-center justify-end gap-3">
|
||||
<div class="connection-status-meta flex items-center justify-end gap-3">
|
||||
<Show when={connectionStatus() === "connected"}>
|
||||
<span class="status-indicator connected">
|
||||
<span class="status-dot" />
|
||||
|
||||
@@ -225,7 +225,7 @@ const SessionList: Component<SessionListProps> = (props) => {
|
||||
</div>
|
||||
<Show when={rowProps.canClose}>
|
||||
<span
|
||||
class="session-item-close opacity-0 group-hover:opacity-100 hover:bg-status-error hover:text-white rounded p-0.5 transition-all"
|
||||
class="session-item-close opacity-80 hover:opacity-100 hover:bg-status-error hover:text-white rounded p-0.5 transition-all"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
props.onClose(rowProps.sessionId)
|
||||
@@ -333,11 +333,13 @@ const SessionList: Component<SessionListProps> = (props) => {
|
||||
role="button"
|
||||
aria-selected={props.activeSessionId === "info"}
|
||||
>
|
||||
<div class="flex items-center gap-2 flex-1">
|
||||
<Info class="w-4 h-4 flex-shrink-0" />
|
||||
<span class="session-item-title truncate">Instance Info</span>
|
||||
<div class="session-item-row session-item-header">
|
||||
<div class="session-item-title-row">
|
||||
<Info class="w-4 h-4 flex-shrink-0" />
|
||||
<span class="session-item-title truncate">Instance Info</span>
|
||||
</div>
|
||||
{infoShortcut && <Kbd shortcut={formatShortcut(infoShortcut)} class="ml-2 not-italic" />}
|
||||
</div>
|
||||
{infoShortcut && <Kbd shortcut={formatShortcut(infoShortcut)} class="ml-2 not-italic" />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -699,7 +699,7 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const shouldShowTag = (status: string) => status === "in_progress" || status === "cancelled"
|
||||
const shouldShowTag = (status: string) => status === "cancelled"
|
||||
|
||||
return (
|
||||
<div class="tool-call-todos" role="list">
|
||||
|
||||
@@ -409,15 +409,19 @@ async function fetchSessions(instanceId: string): Promise<void> {
|
||||
return
|
||||
}
|
||||
|
||||
const existingSessions = sessions().get(instanceId)
|
||||
|
||||
for (const apiSession of response.data) {
|
||||
const existingSession = existingSessions?.get(apiSession.id)
|
||||
|
||||
sessionMap.set(apiSession.id, {
|
||||
id: apiSession.id,
|
||||
instanceId,
|
||||
title: apiSession.title || "Untitled",
|
||||
parentId: apiSession.parentID || null,
|
||||
agent: "",
|
||||
model: { providerId: "", modelId: "" },
|
||||
version: apiSession.version, // Include version from SDK
|
||||
agent: existingSession?.agent ?? "",
|
||||
model: existingSession?.model ?? { providerId: "", modelId: "" },
|
||||
version: apiSession.version, // Include version from SDK
|
||||
time: {
|
||||
...apiSession.time,
|
||||
},
|
||||
@@ -429,17 +433,34 @@ async function fetchSessions(instanceId: string): Promise<void> {
|
||||
diff: apiSession.revert.diff,
|
||||
}
|
||||
: undefined,
|
||||
messages: [],
|
||||
messagesInfo: new Map(),
|
||||
messages: existingSession?.messages ?? [],
|
||||
messagesInfo: existingSession?.messagesInfo ?? new Map(),
|
||||
})
|
||||
}
|
||||
|
||||
const validSessionIds = new Set(sessionMap.keys())
|
||||
|
||||
setSessions((prev) => {
|
||||
const next = new Map(prev)
|
||||
next.set(instanceId, sessionMap)
|
||||
return next
|
||||
})
|
||||
|
||||
setMessagesLoaded((prev) => {
|
||||
const next = new Map(prev)
|
||||
const loadedSet = next.get(instanceId)
|
||||
if (loadedSet) {
|
||||
const filtered = new Set<string>()
|
||||
for (const id of loadedSet) {
|
||||
if (validSessionIds.has(id)) {
|
||||
filtered.add(id)
|
||||
}
|
||||
}
|
||||
next.set(instanceId, filtered)
|
||||
}
|
||||
return next
|
||||
})
|
||||
|
||||
for (const session of sessionMap.values()) {
|
||||
const flag = (session.time as (Session["time"] & { compacting?: number | boolean }) | undefined)?.compacting
|
||||
const active = typeof flag === "number" ? flag > 0 : Boolean(flag)
|
||||
|
||||
@@ -545,11 +545,25 @@ button.button-primary:disabled {
|
||||
}
|
||||
|
||||
.connection-status {
|
||||
@apply flex justify-center items-center px-4 py-2 gap-4;
|
||||
@apply grid items-center px-4 py-2 gap-4;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
background-color: var(--surface-secondary);
|
||||
border-bottom: 1px solid var(--border-base);
|
||||
}
|
||||
|
||||
.connection-status-info {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
.connection-status-shortcut {
|
||||
justify-self: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.connection-status-meta {
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
.connection-status-text {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user