refactor(app): move prompt effects into controller (#39073)
This commit is contained in:
parent
b06768aa8e
commit
4469cecc4e
2 changed files with 63 additions and 77 deletions
|
|
@ -5,7 +5,7 @@ import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2"
|
||||||
import { Icon } from "@opencode-ai/ui/v2/icon"
|
import { Icon } from "@opencode-ai/ui/v2/icon"
|
||||||
import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2"
|
import { KeybindV2 } from "@opencode-ai/ui/v2/keybind-v2"
|
||||||
import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
|
import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
|
||||||
import type { Prompt, ReferenceInfo } from "@opencode-ai/sdk/v2/client"
|
import type { ReferenceInfo } from "@opencode-ai/sdk/v2/client"
|
||||||
import { createEffect, createMemo, on, Show } from "solid-js"
|
import { createEffect, createMemo, on, Show } from "solid-js"
|
||||||
import { ModelSelectorPopoverV2 } from "@/components/dialog-select-model"
|
import { ModelSelectorPopoverV2 } from "@/components/dialog-select-model"
|
||||||
import { DialogSelectModelUnpaidV2 } from "@/components/dialog-select-model-unpaid-v2"
|
import { DialogSelectModelUnpaidV2 } from "@/components/dialog-select-model-unpaid-v2"
|
||||||
|
|
@ -37,11 +37,9 @@ export type PromptInputV2ComposerProps = {
|
||||||
class?: string
|
class?: string
|
||||||
controller: PromptInputV2ComposerController
|
controller: PromptInputV2ComposerController
|
||||||
borderUnderlay?: boolean
|
borderUnderlay?: boolean
|
||||||
edit?: PromptInputProps["edit"]
|
|
||||||
onEditLoaded?: PromptInputProps["onEditLoaded"]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PromptInputV2ControllerProps = Omit<PromptInputProps, "class" | "edit" | "onEditLoaded" | "submission">
|
export type PromptInputV2ControllerProps = Omit<PromptInputProps, "class" | "submission">
|
||||||
export type PromptInputV2ComposerController = PromptInputV2Interaction & {
|
export type PromptInputV2ComposerController = PromptInputV2Interaction & {
|
||||||
readonly model: PromptInputProps["controls"]["model"]
|
readonly model: PromptInputProps["controls"]["model"]
|
||||||
}
|
}
|
||||||
|
|
@ -51,9 +49,6 @@ export function PromptInputV2Composer(props: PromptInputV2ComposerProps) {
|
||||||
const command = useCommand()
|
const command = useCommand()
|
||||||
const language = useLanguage()
|
const language = useLanguage()
|
||||||
|
|
||||||
useCommands(props)
|
|
||||||
useEditHandler(props)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<PromptInputV2
|
<PromptInputV2
|
||||||
|
|
@ -82,70 +77,6 @@ export function PromptInputV2Composer(props: PromptInputV2ComposerProps) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const useEditHandler = (props: PromptInputV2ComposerProps) => {
|
|
||||||
const prompt = usePrompt()
|
|
||||||
|
|
||||||
createEffect(
|
|
||||||
on(
|
|
||||||
() => props.edit?.id,
|
|
||||||
(id) => {
|
|
||||||
const edit = props.edit
|
|
||||||
if (!id || !edit) return
|
|
||||||
prompt.context.items().forEach((item) => prompt.context.remove(item.key))
|
|
||||||
edit.context.forEach((item) =>
|
|
||||||
prompt.context.add({
|
|
||||||
type: item.type,
|
|
||||||
path: item.path,
|
|
||||||
selection: item.selection,
|
|
||||||
comment: item.comment,
|
|
||||||
commentID: item.commentID,
|
|
||||||
commentOrigin: item.commentOrigin,
|
|
||||||
preview: item.preview,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
props.controller.dispatch({ type: "mode.normal" })
|
|
||||||
props.controller.resetHistory()
|
|
||||||
prompt.set(edit.prompt, promptLength(edit.prompt))
|
|
||||||
props.controller.restoreFocus()
|
|
||||||
props.onEditLoaded?.()
|
|
||||||
},
|
|
||||||
{ defer: true },
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const useCommands = (props: PromptInputV2ComposerProps) => {
|
|
||||||
const command = useCommand()
|
|
||||||
const language = useLanguage()
|
|
||||||
|
|
||||||
command.register("prompt-input", () => [
|
|
||||||
{
|
|
||||||
id: "file.attach",
|
|
||||||
title: language.t("prompt.action.attachFile"),
|
|
||||||
category: language.t("command.category.file"),
|
|
||||||
keybind: "mod+u",
|
|
||||||
disabled: props.controller.state.mode !== "normal",
|
|
||||||
onSelect: () => props.controller.attach(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "prompt.mode.shell",
|
|
||||||
title: language.t("command.prompt.mode.shell"),
|
|
||||||
category: language.t("command.category.session"),
|
|
||||||
keybind: "mod+shift+x",
|
|
||||||
disabled: props.controller.state.mode === "shell",
|
|
||||||
onSelect: () => props.controller.dispatch({ type: "mode.shell" }),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "prompt.mode.normal",
|
|
||||||
title: language.t("command.prompt.mode.normal"),
|
|
||||||
category: language.t("command.category.session"),
|
|
||||||
keybind: "mod+shift+e",
|
|
||||||
disabled: props.controller.state.mode === "normal",
|
|
||||||
onSelect: () => props.controller.dispatch({ type: "mode.normal" }),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
export function usePromptInputV2Controller(props: PromptInputV2ControllerProps): PromptInputV2ComposerController {
|
export function usePromptInputV2Controller(props: PromptInputV2ControllerProps): PromptInputV2ComposerController {
|
||||||
const sdk = useSDK()
|
const sdk = useSDK()
|
||||||
const sync = useSync()
|
const sync = useSync()
|
||||||
|
|
@ -472,6 +403,62 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
Object.defineProperty(controller, "model", { get: () => props.controls.model })
|
Object.defineProperty(controller, "model", { get: () => props.controls.model })
|
||||||
|
|
||||||
|
command.register("prompt-input", () => [
|
||||||
|
{
|
||||||
|
id: "file.attach",
|
||||||
|
title: language.t("prompt.action.attachFile"),
|
||||||
|
category: language.t("command.category.file"),
|
||||||
|
keybind: "mod+u",
|
||||||
|
disabled: controller.state.mode !== "normal",
|
||||||
|
onSelect: () => controller.attach(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "prompt.mode.shell",
|
||||||
|
title: language.t("command.prompt.mode.shell"),
|
||||||
|
category: language.t("command.category.session"),
|
||||||
|
keybind: "mod+shift+x",
|
||||||
|
disabled: controller.state.mode === "shell",
|
||||||
|
onSelect: () => controller.dispatch({ type: "mode.shell" }),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "prompt.mode.normal",
|
||||||
|
title: language.t("command.prompt.mode.normal"),
|
||||||
|
category: language.t("command.category.session"),
|
||||||
|
keybind: "mod+shift+e",
|
||||||
|
disabled: controller.state.mode === "normal",
|
||||||
|
onSelect: () => controller.dispatch({ type: "mode.normal" }),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
createEffect(
|
||||||
|
on(
|
||||||
|
() => props.edit?.id,
|
||||||
|
(id) => {
|
||||||
|
const edit = props.edit
|
||||||
|
if (!id || !edit) return
|
||||||
|
prompt.context.items().forEach((item) => prompt.context.remove(item.key))
|
||||||
|
edit.context.forEach((item) =>
|
||||||
|
prompt.context.add({
|
||||||
|
type: item.type,
|
||||||
|
path: item.path,
|
||||||
|
selection: item.selection,
|
||||||
|
comment: item.comment,
|
||||||
|
commentID: item.commentID,
|
||||||
|
commentOrigin: item.commentOrigin,
|
||||||
|
preview: item.preview,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
controller.dispatch({ type: "mode.normal" })
|
||||||
|
controller.resetHistory()
|
||||||
|
prompt.set(edit.prompt, promptLength(edit.prompt))
|
||||||
|
controller.restoreFocus()
|
||||||
|
props.onEditLoaded?.()
|
||||||
|
},
|
||||||
|
{ defer: true },
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
return controller as PromptInputV2ComposerController
|
return controller as PromptInputV2ComposerController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2217,6 +2217,10 @@ export default function Page() {
|
||||||
comments.clear()
|
comments.clear()
|
||||||
resumeScroll()
|
resumeScroll()
|
||||||
},
|
},
|
||||||
|
get edit() {
|
||||||
|
return editingFollowup()
|
||||||
|
},
|
||||||
|
onEditLoaded: clearFollowupEdit,
|
||||||
shouldQueue: queueEnabled,
|
shouldQueue: queueEnabled,
|
||||||
onQueue: queueFollowup,
|
onQueue: queueFollowup,
|
||||||
onAbort: () => {
|
onAbort: () => {
|
||||||
|
|
@ -2226,12 +2230,7 @@ export default function Page() {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<PromptInputV2Composer
|
<PromptInputV2Composer controller={controller} borderUnderlay />
|
||||||
controller={controller}
|
|
||||||
borderUnderlay
|
|
||||||
edit={editingFollowup()}
|
|
||||||
onEditLoaded={clearFollowupEdit}
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</Show>
|
</Show>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue