mirror of
https://fastgit.cc/https://github.com/anomalyco/opencode
synced 2026-04-21 05:10:58 +08:00
tui: fix agent cycling and prompt metadata polish (#23115)
This commit is contained in:
@@ -63,6 +63,7 @@ function init() {
|
||||
useKeyboard((evt) => {
|
||||
if (suspended()) return
|
||||
if (dialog.stack.length > 0) return
|
||||
if (evt.defaultPrevented) return
|
||||
for (const option of entries()) {
|
||||
if (!isEnabled(option)) continue
|
||||
if (option.keybind && keybind.match(option.keybind, evt)) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import path from "path"
|
||||
import { fileURLToPath } from "url"
|
||||
import { Filesystem } from "@/util"
|
||||
import { useLocal } from "@tui/context/local"
|
||||
import { useTheme } from "@tui/context/theme"
|
||||
import { tint, useTheme } from "@tui/context/theme"
|
||||
import { EmptyBorder, SplitBorder } from "@tui/component/border"
|
||||
import { useSDK } from "@tui/context/sdk"
|
||||
import { useRoute } from "@tui/context/route"
|
||||
@@ -463,19 +463,25 @@ export function Prompt(props: PromptProps) {
|
||||
createEffect(() => {
|
||||
if (!input || input.isDestroyed) return
|
||||
if (props.visible === false || dialog.stack.length > 0) {
|
||||
input.blur()
|
||||
if (input.focused) input.blur()
|
||||
return
|
||||
}
|
||||
|
||||
// Slot/plugin updates can remount the background prompt while a dialog is open.
|
||||
// Keep focus with the dialog and let the prompt reclaim it after the dialog closes.
|
||||
input.focus()
|
||||
if (!input.focused) input.focus()
|
||||
})
|
||||
|
||||
createEffect(() => {
|
||||
if (!input || input.isDestroyed) return
|
||||
const capture =
|
||||
store.mode === "normal"
|
||||
? auto()?.visible
|
||||
? (["escape", "navigate", "submit", "tab"] as const)
|
||||
: (["tab"] as const)
|
||||
: undefined
|
||||
input.traits = {
|
||||
capture: auto()?.visible ? ["escape", "navigate", "submit", "tab"] : undefined,
|
||||
capture,
|
||||
suspend: !!props.disabled || store.mode === "shell",
|
||||
status: store.mode === "shell" ? "SHELL" : undefined,
|
||||
}
|
||||
@@ -870,6 +876,7 @@ export function Prompt(props: PromptProps) {
|
||||
() => !!local.agent.current() && store.mode === "normal" && showVariant(),
|
||||
animationsEnabled,
|
||||
)
|
||||
const borderHighlight = createMemo(() => tint(theme.border, highlight(), agentMetaAlpha()))
|
||||
|
||||
const placeholderText = createMemo(() => {
|
||||
if (props.showPlaceholder === false) return undefined
|
||||
@@ -931,7 +938,7 @@ export function Prompt(props: PromptProps) {
|
||||
<box ref={(r) => (anchor = r)} visible={props.visible !== false}>
|
||||
<box
|
||||
border={["left"]}
|
||||
borderColor={highlight()}
|
||||
borderColor={borderHighlight()}
|
||||
customBorderChars={{
|
||||
...SplitBorder.customBorderChars,
|
||||
bottomLeft: "╹",
|
||||
@@ -1146,11 +1153,10 @@ export function Prompt(props: PromptProps) {
|
||||
<Show when={local.agent.current()} fallback={<box height={1} />}>
|
||||
{(agent) => (
|
||||
<>
|
||||
<text fg={fadeColor(highlight(), agentMetaAlpha())}>
|
||||
{store.mode === "shell" ? "Shell" : Locale.titlecase(agent().name)}{" "}
|
||||
</text>
|
||||
<text fg={fadeColor(highlight(), agentMetaAlpha())}>{store.mode === "shell" ? "Shell" : Locale.titlecase(agent().name)}</text>
|
||||
<Show when={store.mode === "normal"}>
|
||||
<box flexDirection="row" gap={1}>
|
||||
<text fg={fadeColor(theme.textMuted, modelMetaAlpha())}>·</text>
|
||||
<text
|
||||
flexShrink={0}
|
||||
fg={fadeColor(keybind.leader ? theme.textMuted : theme.text, modelMetaAlpha())}
|
||||
@@ -1183,7 +1189,7 @@ export function Prompt(props: PromptProps) {
|
||||
<box
|
||||
height={1}
|
||||
border={["left"]}
|
||||
borderColor={highlight()}
|
||||
borderColor={borderHighlight()}
|
||||
customBorderChars={{
|
||||
...EmptyBorder,
|
||||
vertical: theme.backgroundElement.a !== 0 ? "╹" : " ",
|
||||
|
||||
@@ -75,7 +75,9 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
|
||||
},
|
||||
move(direction: 1 | -1) {
|
||||
batch(() => {
|
||||
let next = agents().findIndex((x) => x.name === agentStore.current) + direction
|
||||
const current = this.current()
|
||||
if (!current) return
|
||||
let next = agents().findIndex((x) => x.name === current.name) + direction
|
||||
if (next < 0) next = agents().length - 1
|
||||
if (next >= agents().length) next = 0
|
||||
const value = agents()[next]
|
||||
|
||||
@@ -8,20 +8,23 @@ export function createDebouncedSignal<T>(value: T, ms: number): [Accessor<T>, Sc
|
||||
|
||||
export function createFadeIn(show: Accessor<boolean>, enabled: Accessor<boolean>) {
|
||||
const [alpha, setAlpha] = createSignal(show() ? 1 : 0)
|
||||
let revealed = show()
|
||||
|
||||
createEffect(
|
||||
on([show, enabled], ([visible, animate], previous) => {
|
||||
on([show, enabled], ([visible, animate]) => {
|
||||
if (!visible) {
|
||||
setAlpha(0)
|
||||
return
|
||||
}
|
||||
|
||||
if (!animate || !previous) {
|
||||
if (!animate || revealed) {
|
||||
revealed = true
|
||||
setAlpha(1)
|
||||
return
|
||||
}
|
||||
|
||||
const start = performance.now()
|
||||
revealed = true
|
||||
setAlpha(0)
|
||||
|
||||
const timer = setInterval(() => {
|
||||
|
||||
Reference in New Issue
Block a user