feat(ui): add back button to session view and auto-clear active session on instance stop

This commit is contained in:
Gemini AI
2025-12-27 12:36:25 +04:00
Unverified
parent 0e5059fc88
commit c5b62f31a8
2 changed files with 32 additions and 23 deletions

View File

@@ -217,6 +217,7 @@ const App: Component = () => {
if (!confirmed) return if (!confirmed) return
clearActiveParentSession(instanceId)
await stopInstance(instanceId) await stopInstance(instanceId)
} }
@@ -303,7 +304,7 @@ const App: Component = () => {
const tauriBridge = (window as { __TAURI__?: { event?: { listen: (event: string, handler: (event: { payload: unknown }) => void) => Promise<() => void> } } }).__TAURI__ const tauriBridge = (window as { __TAURI__?: { event?: { listen: (event: string, handler: (event: { payload: unknown }) => void) => Promise<() => void> } } }).__TAURI__
if (tauriBridge?.event) { if (tauriBridge?.event) {
let unlistenMenu: (() => void) | null = null let unlistenMenu: (() => void) | null = null
tauriBridge.event.listen("menu:newInstance", () => { tauriBridge.event.listen("menu:newInstance", () => {
handleNewInstanceRequest() handleNewInstanceRequest()
}).then((unlisten) => { }).then((unlisten) => {
@@ -321,7 +322,7 @@ const App: Component = () => {
// Check if this is OAuth callback // Check if this is OAuth callback
const isOAuthCallback = window.location.pathname === '/auth/qwen/callback' const isOAuthCallback = window.location.pathname === '/auth/qwen/callback'
if (isOAuthCallback) { if (isOAuthCallback) {
return <QwenOAuthCallback /> return <QwenOAuthCallback />
} }
@@ -391,29 +392,29 @@ const App: Component = () => {
onNew={handleNewInstanceRequest} onNew={handleNewInstanceRequest}
onOpenRemoteAccess={() => setRemoteAccessOpen(true)} onOpenRemoteAccess={() => setRemoteAccessOpen(true)}
/> />
<For each={Array.from(instances().values())}> <For each={Array.from(instances().values())}>
{(instance) => { {(instance) => {
const isActiveInstance = () => activeInstanceId() === instance.id const isActiveInstance = () => activeInstanceId() === instance.id
const isVisible = () => isActiveInstance() && !showFolderSelection() const isVisible = () => isActiveInstance() && !showFolderSelection()
return ( return (
<div class="flex-1 min-h-0 overflow-hidden" style={{ display: isVisible() ? "flex" : "none" }}> <div class="flex-1 min-h-0 overflow-hidden" style={{ display: isVisible() ? "flex" : "none" }}>
<InstanceMetadataProvider instance={instance}> <InstanceMetadataProvider instance={instance}>
<InstanceShell <InstanceShell
instance={instance} instance={instance}
escapeInDebounce={escapeInDebounce()} escapeInDebounce={escapeInDebounce()}
paletteCommands={paletteCommands} paletteCommands={paletteCommands}
onCloseSession={(sessionId) => handleCloseSession(instance.id, sessionId)} onCloseSession={(sessionId) => handleCloseSession(instance.id, sessionId)}
onNewSession={() => handleNewSession(instance.id)} onNewSession={() => handleNewSession(instance.id)}
handleSidebarAgentChange={(sessionId, agent) => handleSidebarAgentChange(instance.id, sessionId, agent)} handleSidebarAgentChange={(sessionId, agent) => handleSidebarAgentChange(instance.id, sessionId, agent)}
handleSidebarModelChange={(sessionId, model) => handleSidebarModelChange(instance.id, sessionId, model)} handleSidebarModelChange={(sessionId, model) => handleSidebarModelChange(instance.id, sessionId, model)}
onExecuteCommand={executeCommand} onExecuteCommand={executeCommand}
tabBarOffset={instanceTabBarHeight()} tabBarOffset={instanceTabBarHeight()}
/> />
</InstanceMetadataProvider> </InstanceMetadataProvider>
</div> </div>
) )
}} }}
</For> </For>
@@ -458,9 +459,9 @@ const App: Component = () => {
</div> </div>
</div> </div>
</Show> </Show>
<RemoteAccessOverlay open={remoteAccessOpen()} onClose={() => setRemoteAccessOpen(false)} /> <RemoteAccessOverlay open={remoteAccessOpen()} onClose={() => setRemoteAccessOpen(false)} />
<AlertDialog /> <AlertDialog />
<Toaster <Toaster

View File

@@ -66,7 +66,7 @@ import SessionView from "../session/session-view"
import { Sidebar, type FileNode } from "./sidebar" import { Sidebar, type FileNode } from "./sidebar"
import { Editor } from "./editor" import { Editor } from "./editor"
import { serverApi } from "../../lib/api-client" import { serverApi } from "../../lib/api-client"
import { Sparkles, Layout as LayoutIcon, Terminal as TerminalIcon, Search, Loader2, Zap, Shield, Settings, FileArchive } from "lucide-solid" import { Sparkles, Layout as LayoutIcon, Terminal as TerminalIcon, Search, Loader2, Zap, Shield, Settings, FileArchive, ArrowLeft } from "lucide-solid"
import { formatTokenTotal } from "../../lib/formatters" import { formatTokenTotal } from "../../lib/formatters"
import { sseManager } from "../../lib/sse-manager" import { sseManager } from "../../lib/sse-manager"
import { getLogger } from "../../lib/logger" import { getLogger } from "../../lib/logger"
@@ -1342,6 +1342,14 @@ Now analyze the project and report your findings.`
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
<Show when={activeSessionIdForInstance() && activeSessionIdForInstance() !== "info"}> <Show when={activeSessionIdForInstance() && activeSessionIdForInstance() !== "info"}>
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
<button
onClick={() => props.onCloseSession(activeSessionIdForInstance()!)}
class="flex items-center gap-1.5 px-2.5 py-1 text-[11px] font-semibold text-zinc-400 hover:text-white hover:bg-white/10 border border-transparent hover:border-white/10 transition-all rounded-full"
title="Back to Sessions"
>
<ArrowLeft size={14} strokeWidth={2} />
<span>Back</span>
</button>
{/* Compact Button */} {/* Compact Button */}
<button <button
onClick={handleCompact} onClick={handleCompact}