mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-08-31 16:21:50 +03:00
fix(tui): keep composer visible and focused
This commit is contained in:
+29
-4
@@ -1350,7 +1350,7 @@ describe("NanobotTui layout", () => {
|
|||||||
expect(markdown?.syntaxStyle).not.toBe(darkSyntax)
|
expect(markdown?.syntaxStyle).not.toBe(darkSyntax)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("uses a quiet surface instead of a boxed composer", async () => {
|
test("distinguishes the composer with a quiet focus edge", async () => {
|
||||||
setup = await createRenderer({ width: 72, height: 20, screenMode: "alternate-screen" })
|
setup = await createRenderer({ width: 72, height: 20, screenMode: "alternate-screen" })
|
||||||
const app = NanobotTui.mount(
|
const app = NanobotTui.mount(
|
||||||
setup.renderer,
|
setup.renderer,
|
||||||
@@ -1362,14 +1362,20 @@ describe("NanobotTui layout", () => {
|
|||||||
ready: boolean
|
ready: boolean
|
||||||
composerFrame: {
|
composerFrame: {
|
||||||
border: boolean | string[]
|
border: boolean | string[]
|
||||||
|
borderColor: { toInts(): number[] }
|
||||||
backgroundColor: { toInts(): number[] }
|
backgroundColor: { toInts(): number[] }
|
||||||
}
|
}
|
||||||
composer: { backgroundColor: { toInts(): number[] } }
|
composer: {
|
||||||
|
backgroundColor: { toInts(): number[] }
|
||||||
|
placeholderColor: { toInts(): number[] }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(internals.composerFrame.border).toBeFalse()
|
expect(internals.composerFrame.border).toEqual(["left"])
|
||||||
|
expect(internals.composerFrame.borderColor.toInts().slice(0, 3)).toEqual([185, 77, 11])
|
||||||
expect(internals.composerFrame.backgroundColor.toInts().slice(0, 3)).toEqual([240, 240, 240])
|
expect(internals.composerFrame.backgroundColor.toInts().slice(0, 3)).toEqual([240, 240, 240])
|
||||||
expect(internals.composer.backgroundColor.toInts().slice(0, 3)).toEqual([240, 240, 240])
|
expect(internals.composer.backgroundColor.toInts().slice(0, 3)).toEqual([240, 240, 240])
|
||||||
|
expect(internals.composer.placeholderColor.toInts().slice(0, 3)).toEqual([111, 111, 120])
|
||||||
|
|
||||||
app.accept({ event: "attached", chat_id: "chat" })
|
app.accept({ event: "attached", chat_id: "chat" })
|
||||||
await waitUntil(() => internals.ready)
|
await waitUntil(() => internals.ready)
|
||||||
@@ -1377,7 +1383,9 @@ describe("NanobotTui layout", () => {
|
|||||||
|
|
||||||
const composerLine = setup.captureCharFrame().split("\n")
|
const composerLine = setup.captureCharFrame().split("\n")
|
||||||
.find((line) => line.includes("Ask nanobot anything")) || ""
|
.find((line) => line.includes("Ask nanobot anything")) || ""
|
||||||
expect(composerLine).not.toContain("│")
|
expect(composerLine).toContain("│")
|
||||||
|
expect(composerLine).not.toContain("┌")
|
||||||
|
expect(composerLine).not.toContain("┐")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("uses asymmetric roles instead of chat bubbles", async () => {
|
test("uses asymmetric roles instead of chat bubbles", async () => {
|
||||||
@@ -1666,6 +1674,23 @@ describe("NanobotTui layout", () => {
|
|||||||
expect(setup.renderer.getSelection()).toBeNull()
|
expect(setup.renderer.getSelection()).toBeNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("returns text input focus when other TUI content is clicked", async () => {
|
||||||
|
setup = await createRenderer({ width: 72, height: 20, screenMode: "alternate-screen" })
|
||||||
|
const app = mount(setup)
|
||||||
|
const ui = app as unknown as {
|
||||||
|
composer: TextareaRenderable
|
||||||
|
status: TextRenderable
|
||||||
|
}
|
||||||
|
app.accept({ event: "delta", chat_id: "chat", text: "clickable answer" })
|
||||||
|
app.accept({ event: "stream_end", chat_id: "chat" })
|
||||||
|
await setup.flush()
|
||||||
|
|
||||||
|
ui.composer.blur()
|
||||||
|
await setup.mockMouse.click(ui.status.x, ui.status.y)
|
||||||
|
|
||||||
|
expect(ui.composer.focused).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
test("animates one stable status line while the agent works", async () => {
|
test("animates one stable status line while the agent works", async () => {
|
||||||
setup = await createRenderer({ width: 88, height: 24, screenMode: "alternate-screen" })
|
setup = await createRenderer({ width: 88, height: 24, screenMode: "alternate-screen" })
|
||||||
const app = mount(setup)
|
const app = mount(setup)
|
||||||
|
|||||||
+6
-2
@@ -511,6 +511,7 @@ export class NanobotTui {
|
|||||||
backgroundColor: RGBA.defaultBackground(),
|
backgroundColor: RGBA.defaultBackground(),
|
||||||
onMouseDown: (event) => {
|
onMouseDown: (event) => {
|
||||||
if (event.button !== 0) return
|
if (event.button !== 0) return
|
||||||
|
if (!this.diffViewer.visible) this.composer.focus()
|
||||||
// Runtime pickers are transient popovers. A primary click anywhere
|
// Runtime pickers are transient popovers. A primary click anywhere
|
||||||
// outside their trigger or body dismisses them; hide() restores the
|
// outside their trigger or body dismisses them; hide() restores the
|
||||||
// composer focus through the shared visibility callback.
|
// composer focus through the shared visibility callback.
|
||||||
@@ -602,7 +603,8 @@ export class NanobotTui {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
minHeight: 1,
|
minHeight: 1,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
border: false,
|
border: ["left"],
|
||||||
|
borderColor: this.palette.accent,
|
||||||
paddingLeft: 1,
|
paddingLeft: 1,
|
||||||
paddingRight: 1,
|
paddingRight: 1,
|
||||||
backgroundColor: composerSurface,
|
backgroundColor: composerSurface,
|
||||||
@@ -614,7 +616,7 @@ export class NanobotTui {
|
|||||||
maxHeight: 8,
|
maxHeight: 8,
|
||||||
wrapMode: "word",
|
wrapMode: "word",
|
||||||
placeholder: COMPOSER_PLACEHOLDER,
|
placeholder: COMPOSER_PLACEHOLDER,
|
||||||
placeholderColor: this.palette.faint,
|
placeholderColor: this.palette.muted,
|
||||||
textColor: this.palette.text,
|
textColor: this.palette.text,
|
||||||
focusedTextColor: this.palette.text,
|
focusedTextColor: this.palette.text,
|
||||||
backgroundColor: composerSurface,
|
backgroundColor: composerSurface,
|
||||||
@@ -1693,8 +1695,10 @@ export class NanobotTui {
|
|||||||
private updateComposerAppearance(): void {
|
private updateComposerAppearance(): void {
|
||||||
const surface = this.composerSurface()
|
const surface = this.composerSurface()
|
||||||
this.composerFrame.backgroundColor = surface
|
this.composerFrame.backgroundColor = surface
|
||||||
|
this.composerFrame.borderColor = this.palette.accent
|
||||||
this.composer.backgroundColor = surface
|
this.composer.backgroundColor = surface
|
||||||
this.composer.focusedBackgroundColor = surface
|
this.composer.focusedBackgroundColor = surface
|
||||||
|
this.composer.placeholderColor = this.palette.muted
|
||||||
}
|
}
|
||||||
|
|
||||||
private syncComposerPlaceholder(): void {
|
private syncComposerPlaceholder(): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user