fix(tui): preserve burst form input
This commit is contained in:
@@ -71,6 +71,7 @@ export function RunFormBody(props: {
|
||||
return typeof value === "string" ? value : undefined
|
||||
})
|
||||
let area: TextareaRenderable | undefined
|
||||
let editingReady = false
|
||||
|
||||
createEffect(() => {
|
||||
setState((previous) => formSync(previous, props.request))
|
||||
@@ -93,6 +94,7 @@ export function RunFormBody(props: {
|
||||
if (!area || area.isDestroyed || !state().editing) return
|
||||
area.focus()
|
||||
area.cursorOffset = area.plainText.length
|
||||
editingReady = true
|
||||
})
|
||||
})
|
||||
|
||||
@@ -209,7 +211,6 @@ export function RunFormBody(props: {
|
||||
return
|
||||
}
|
||||
if (unsupported()) return
|
||||
if (state().editing) return
|
||||
const character =
|
||||
!event.ctrl &&
|
||||
!event.meta &&
|
||||
@@ -219,12 +220,14 @@ export function RunFormBody(props: {
|
||||
/^[^\p{C}\p{Zl}\p{Zp}]$/u.test(event.sequence)
|
||||
? event.sequence
|
||||
: undefined
|
||||
if (custom() && state().selected === rows().length && character) {
|
||||
const next = formPick(state(), props.request)
|
||||
if (custom() && state().selected === rows().length && character && !editingReady) {
|
||||
const next = state().editing ? state() : formPick(state(), props.request)
|
||||
if (!state().editing) editingReady = false
|
||||
setState(formSetDraft(next, current(), formInput(next, current()) + character))
|
||||
event.preventDefault()
|
||||
return
|
||||
}
|
||||
if (state().editing) return
|
||||
if (
|
||||
event.name === "tab" ||
|
||||
event.name === "left" ||
|
||||
|
||||
@@ -67,6 +67,7 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
||||
})
|
||||
|
||||
let textarea: TextareaRenderable | undefined
|
||||
let editingReady = false
|
||||
let review: ScrollBoxRenderable | undefined
|
||||
|
||||
const message = createMemo(() => {
|
||||
@@ -178,13 +179,16 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
||||
onCleanup(
|
||||
keymap.intercept("key", ({ event, consume }) => {
|
||||
if (keymap.mode.current() !== FORM_MODE) return
|
||||
if (store.editing || textual() || !other()) return
|
||||
if (textual() || !other() || (store.editing && editingReady)) return
|
||||
if (event.ctrl || event.meta || event.option || event.super || event.hyper) return
|
||||
if (!/^[^\p{C}\p{Zl}\p{Zp}]$/u.test(event.sequence)) return
|
||||
const current = answerField()
|
||||
if (!current) return
|
||||
setStore("custom", { ...store.custom, [current.key]: input() + event.sequence })
|
||||
setStore("editing", true)
|
||||
if (!store.editing) {
|
||||
editingReady = false
|
||||
setStore("editing", true)
|
||||
}
|
||||
consume()
|
||||
}),
|
||||
)
|
||||
@@ -884,8 +888,10 @@ export function FormPrompt(props: { form: FormWithLocation }) {
|
||||
textarea = val
|
||||
val.traits = { status: "ANSWER" }
|
||||
queueMicrotask(() => {
|
||||
val.setText(input())
|
||||
val.focus()
|
||||
val.gotoLineEnd()
|
||||
editingReady = true
|
||||
})
|
||||
}}
|
||||
initialValue={input()}
|
||||
|
||||
@@ -148,9 +148,9 @@ test("typing starts a highlighted custom answer without losing the first charact
|
||||
expect(prompt.app.renderer.currentFocusedEditor).toBeNull()
|
||||
|
||||
prompt.app.mockInput.pressKey("j")
|
||||
prompt.app.mockInput.pressKey("1")
|
||||
await prompt.app.waitFor(() => prompt.app.renderer.currentFocusedEditor?.plainText === "1")
|
||||
expect(prompt.app.renderer.currentFocusedEditor?.plainText).toBe("1")
|
||||
await prompt.app.mockInput.typeText("123")
|
||||
await prompt.app.waitFor(() => prompt.app.renderer.currentFocusedEditor?.plainText === "123")
|
||||
expect(prompt.app.renderer.currentFocusedEditor?.plainText).toBe("123")
|
||||
} finally {
|
||||
prompt.app.renderer.destroy()
|
||||
}
|
||||
|
||||
@@ -300,9 +300,9 @@ test("direct footer typing starts a highlighted custom answer without losing the
|
||||
expect(app.renderer.currentFocusedEditor).toBeNull()
|
||||
|
||||
app.mockInput.pressKey("j")
|
||||
app.mockInput.pressKey("h")
|
||||
await app.waitFor(() => app.renderer.currentFocusedEditor?.plainText === "h")
|
||||
expect(app.renderer.currentFocusedEditor?.plainText).toBe("h")
|
||||
await app.mockInput.typeText("hello")
|
||||
await app.waitFor(() => app.renderer.currentFocusedEditor?.plainText === "hello")
|
||||
expect(app.renderer.currentFocusedEditor?.plainText).toBe("hello")
|
||||
} finally {
|
||||
app.cleanup()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user