diff options
| author | David Hill <[email protected]> | 2026-03-08 01:27:45 +0000 |
|---|---|---|
| committer | David Hill <[email protected]> | 2026-03-08 01:27:45 +0000 |
| commit | 09388c98f3bbf737615845e3d40c2adfe66089f7 (patch) | |
| tree | 7527ed5793345b7cb110420f6cc9d0bdc6a929fb /packages | |
| parent | ae25c1e7b75c17d799f7a245f03ca0cd8bef1eab (diff) | |
| download | opencode-09388c98f3bbf737615845e3d40c2adfe66089f7.tar.gz opencode-09388c98f3bbf737615845e3d40c2adfe66089f7.zip | |
Revert "tui: remove prompt model/thinking/permissions selectors on dev so the composer stays simple"
This reverts commit ae25c1e7b75c17d799f7a245f03ca0cd8bef1eab.
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/app/src/components/prompt-input.tsx | 149 |
1 files changed, 148 insertions, 1 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index de7a219c8..3ae362e6f 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -23,11 +23,15 @@ import { useComments } from "@/context/comments" import { Button } from "@opencode-ai/ui/button" import { DockShellForm, DockTray } from "@opencode-ai/ui/dock-surface" import { Icon } from "@opencode-ai/ui/icon" +import { ProviderIcon } from "@opencode-ai/ui/provider-icon" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { IconButton } from "@opencode-ai/ui/icon-button" import { Select } from "@opencode-ai/ui/select" import { RadioGroup } from "@opencode-ai/ui/radio-group" import { useDialog } from "@opencode-ai/ui/context/dialog" +import { ModelSelectorPopover } from "@/components/dialog-select-model" +import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid" +import { useProviders } from "@/hooks/use-providers" import { useCommand } from "@/context/command" import { Persist, persisted } from "@/utils/persist" import { usePermission } from "@/context/permission" @@ -100,6 +104,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => { const comments = useComments() const params = useParams() const dialog = useDialog() + const providers = useProviders() const command = useCommand() const permission = usePermission() const language = useLanguage() @@ -945,12 +950,21 @@ export const PromptInput: Component<PromptInputProps> = (props) => { readClipboardImage: platform.readClipboardImage, }) + const variants = createMemo(() => ["default", ...local.model.variant.list()]) const accepting = createMemo(() => { const id = params.id if (!id) return permission.isAutoAcceptingDirectory(sdk.directory) return permission.isAutoAccepting(id, sdk.directory) }) + const flip = () => { + if (!params.id) { + permission.toggleAutoAcceptDirectory(sdk.directory) + return + } + permission.toggleAutoAccept(params.id, sdk.directory) + } + const { abort, handleSubmit } = createPromptSubmit({ info, imageAttachments, @@ -1176,7 +1190,11 @@ export const PromptInput: Component<PromptInputProps> = (props) => { onMouseDown={(e) => { const target = e.target if (!(target instanceof HTMLElement)) return - if (target.closest('[data-action="prompt-attach"], [data-action="prompt-submit"]')) { + if ( + target.closest( + '[data-action="prompt-attach"], [data-action="prompt-submit"], [data-action="prompt-permissions"]', + ) + ) { return } editorRef?.focus() @@ -1310,6 +1328,99 @@ export const PromptInput: Component<PromptInputProps> = (props) => { <Icon name="plus" class="size-4.5" /> </Button> </TooltipKeybind> + + <Show + when={providers.paid().length > 0} + fallback={ + <TooltipKeybind + placement="top" + gutter={8} + title={language.t("command.model.choose")} + keybind={command.keybind("model.choose")} + > + <Button + as="div" + variant="ghost" + size="small" + class="min-w-0 max-w-[240px] text-13-regular text-text-base group" + style={{ + opacity: buttonsSpring(), + transform: `scale(${0.95 + buttonsSpring() * 0.05})`, + filter: `blur(${(1 - buttonsSpring()) * 2}px)`, + }} + onClick={() => dialog.show(() => <DialogSelectModelUnpaid />)} + > + <Show when={local.model.current()?.provider?.id}> + <ProviderIcon + id={local.model.current()!.provider.id} + class="size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150" + style={{ "will-change": "opacity", transform: "translateZ(0)" }} + /> + </Show> + <span class="truncate"> + {local.model.current()?.name ?? language.t("dialog.model.select.title")} + </span> + <Icon name="chevron-down" size="small" class="shrink-0" /> + </Button> + </TooltipKeybind> + } + > + <TooltipKeybind + placement="top" + gutter={8} + title={language.t("command.model.choose")} + keybind={command.keybind("model.choose")} + > + <ModelSelectorPopover + triggerAs={Button} + triggerProps={{ + variant: "ghost", + size: "small", + style: { + opacity: buttonsSpring(), + transform: `scale(${0.95 + buttonsSpring() * 0.05})`, + filter: `blur(${(1 - buttonsSpring()) * 2}px)`, + }, + class: "min-w-0 max-w-[240px] text-13-regular text-text-base group", + }} + > + <Show when={local.model.current()?.provider?.id}> + <ProviderIcon + id={local.model.current()!.provider.id} + class="size-4 shrink-0 opacity-40 group-hover:opacity-100 transition-opacity duration-150" + style={{ "will-change": "opacity", transform: "translateZ(0)" }} + /> + </Show> + <span class="truncate"> + {local.model.current()?.name ?? language.t("dialog.model.select.title")} + </span> + <Icon name="chevron-down" size="small" class="shrink-0" /> + </ModelSelectorPopover> + </TooltipKeybind> + </Show> + + <TooltipKeybind + placement="top" + gutter={8} + title={language.t("command.model.variant.cycle")} + keybind={command.keybind("model.variant.cycle")} + > + <Select + size="small" + options={variants()} + current={local.model.variant.current() ?? "default"} + label={(x) => (x === "default" ? language.t("common.default") : x)} + onSelect={(x) => local.model.variant.set(x === "default" ? undefined : x)} + class="capitalize max-w-[160px]" + valueClass="truncate text-13-regular text-text-base" + triggerStyle={{ + opacity: buttonsSpring(), + transform: `scale(${0.95 + buttonsSpring() * 0.05})`, + filter: `blur(${(1 - buttonsSpring()) * 2}px)`, + }} + variant="ghost" + /> + </TooltipKeybind> </div> </div> </div> @@ -1355,6 +1466,42 @@ export const PromptInput: Component<PromptInputProps> = (props) => { variant="ghost" /> </TooltipKeybind> + + <TooltipKeybind + placement="top" + gutter={4} + title={language.t( + accepting() ? "command.permissions.autoaccept.disable" : "command.permissions.autoaccept.enable", + )} + keybind={command.keybind("permissions.autoaccept")} + > + <Select + size="normal" + options={["default", "autoaccept"] as const} + current={accepting() ? "autoaccept" : "default"} + label={(x) => + x === "autoaccept" + ? language.t("command.permissions.autoaccept.enable") + : `${language.t("common.default")} ${language.t("command.category.permissions")}` + } + onSelect={(x) => { + if (!x) return + if (x === "autoaccept" && accepting()) return + if (x === "default" && !accepting()) return + flip() + }} + class="max-w-[220px]" + valueClass="truncate text-13-regular text-text-base" + triggerStyle={{ + height: "28px", + opacity: buttonsSpring(), + transform: `scale(${0.95 + buttonsSpring() * 0.05})`, + filter: `blur(${(1 - buttonsSpring()) * 2}px)`, + "pointer-events": buttonsSpring() > 0.5 ? "auto" : "none", + }} + variant="ghost" + /> + </TooltipKeybind> </div> </div> <div class="shrink-0"> |
