diff --git a/packages/tui/src/routes/home.tsx b/packages/tui/src/routes/home.tsx
index 672e4e954cc..0712eacd2fb 100644
--- a/packages/tui/src/routes/home.tsx
+++ b/packages/tui/src/routes/home.tsx
@@ -1,5 +1,5 @@
import { Prompt, type PromptRef } from "../component/prompt"
-import { createEffect, createMemo, createSignal, Match, onMount, Show, Switch, untrack } from "solid-js"
+import { createEffect, createMemo, createSignal, onMount, Show, untrack } from "solid-js"
import { Logo } from "../component/logo"
import { useArgs } from "../context/args"
import { useRouteData } from "../context/route"
@@ -11,11 +11,10 @@ import { useLocation } from "../context/location"
import { FormPrompt } from "./session/form"
import { Slot } from "../plugin/render"
import { useTerminalDimensions } from "@opentui/solid"
-import { TextAttributes, type RGBA } from "@opentui/core"
import { useTheme } from "../context/theme"
import { useUpdateNotification } from "../context/update-notification"
+import { useExit } from "../context/exit"
import { FadeInText } from "../component/fade-in-text"
-import { stringWidth } from "../util/string-width"
let once = false
const placeholder = {
@@ -33,6 +32,7 @@ export function Home() {
const data = useData()
const location = useLocation()
const dimensions = useTerminalDimensions()
+ const [logoWidth, setLogoWidth] = createSignal(0)
// Global MCP elicitations can arrive without a session route, so keep them reachable from Home.
const currentLocation = () => route.location ?? data.location.default()
const forms = createMemo(() => data.session.form.list("global", currentLocation()) ?? [])
@@ -87,15 +87,18 @@ export function Home() {
>
-
+
-
+
+
0} />
-
-
-
@@ -118,87 +121,55 @@ export function Home() {
)
}
-function UpdateNotification() {
+function UpdateNotification(props: { width: number }) {
const update = useUpdateNotification()
+ const exit = useExit()
const theme = useTheme()
- const remoteMessage = "A remote server cannot be updated from here. Updating it is recommended."
- const [hovered, setHovered] = createSignal<"primary" | "close">()
+ const [hovered, setHovered] = createSignal(false)
+ const backdrop = () => (hovered() ? theme.background.action.primary.hovered : theme.background.default)
createEffect(() => {
update.notification()
- setHovered(undefined)
+ setHovered(false)
})
return (
- {(state) => (
-
-
-
- setHovered("primary")}
- onMouseOut={() => setHovered(undefined)}
- onMouseUp={() => update.open?.("notification")}
- >
-
-
-
-
-
-
- setHovered("close")}
- onMouseOut={() => setHovered(undefined)}
- onMouseUp={update.dismiss}
- >
- Close
-
-
-
-
-
- )}
+ {(state) => {
+ const remote = state.source === "server" && state.remote
+ return (
+
+ setHovered(true)}
+ onMouseOut={() => setHovered(false)}
+ onMouseUp={() => {
+ if (remote) return update.dismiss()
+ if (state.type === "installed") return exit()
+ update.open?.("notification")
+ }}
+ >
+
+
+
+ {state.type === "installed" ? "/exit" : "/update"}
+
+
+ {remote
+ ? "remote server update available"
+ : state.type === "installed"
+ ? ` restart to use v${state.version}`
+ : ` to install v${state.version}`}
+
+
+
+ )
+ }}
)
}
-
-function UpdateMessage(props: { title: string; description: string; backdrop: RGBA }) {
- const theme = useTheme()
- const titleWidth = stringWidth(props.title)
- const descriptionWidth = stringWidth(props.description)
- const width = Math.max(titleWidth, descriptionWidth)
- return (
-
-
- {" ".repeat(Math.floor((width - titleWidth) / 2))}
- {props.title}
-
- {"\n"}
-
- {" ".repeat(Math.floor((width - descriptionWidth) / 2))}
- {props.description}
-
-
- )
-}