import { For, Show, createMemo, type Component } from "solid-js" import { createStore } from "solid-js/store" import { Button } from "@opencode-ai/ui/button" import { Icon } from "@opencode-ai/ui/icon" import { showToast } from "@opencode-ai/ui/toast" import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" import { useLanguage } from "@/context/language" import { useSDK } from "@/context/sdk" export const QuestionDock: Component<{ request: QuestionRequest }> = (props) => { const sdk = useSDK() const language = useLanguage() const questions = createMemo(() => props.request.questions) const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true) const [store, setStore] = createStore({ tab: 0, answers: [] as QuestionAnswer[], custom: [] as string[], editing: false, sending: false, }) const question = createMemo(() => questions()[store.tab]) const confirm = createMemo(() => !single() && store.tab === questions().length) const options = createMemo(() => question()?.options ?? []) const input = createMemo(() => store.custom[store.tab] ?? "") const multi = createMemo(() => question()?.multiple === true) const customPicked = createMemo(() => { const value = input() if (!value) return false return store.answers[store.tab]?.includes(value) ?? false }) const fail = (err: unknown) => { const message = err instanceof Error ? err.message : String(err) showToast({ title: language.t("common.requestFailed"), description: message }) } const reply = (answers: QuestionAnswer[]) => { if (store.sending) return setStore("sending", true) sdk.client.question .reply({ requestID: props.request.id, answers }) .catch(fail) .finally(() => setStore("sending", false)) } const reject = () => { if (store.sending) return setStore("sending", true) sdk.client.question .reject({ requestID: props.request.id }) .catch(fail) .finally(() => setStore("sending", false)) } const submit = () => { reply(questions().map((_, i) => store.answers[i] ?? [])) } const pick = (answer: string, custom: boolean = false) => { const answers = [...store.answers] answers[store.tab] = [answer] setStore("answers", answers) if (custom) { const inputs = [...store.custom] inputs[store.tab] = answer setStore("custom", inputs) } if (single()) { reply([[answer]]) return } setStore("tab", store.tab + 1) } const toggle = (answer: string) => { const existing = store.answers[store.tab] ?? [] const next = [...existing] const index = next.indexOf(answer) if (index === -1) next.push(answer) if (index !== -1) next.splice(index, 1) const answers = [...store.answers] answers[store.tab] = next setStore("answers", answers) } const selectTab = (index: number) => { setStore("tab", index) setStore("editing", false) } const selectOption = (optIndex: number) => { if (store.sending) return if (optIndex === options().length) { setStore("editing", true) return } const opt = options()[optIndex] if (!opt) return if (multi()) { toggle(opt.label) return } pick(opt.label) } const handleCustomSubmit = (e: Event) => { e.preventDefault() if (store.sending) return const value = input().trim() if (!value) { setStore("editing", false) return } if (multi()) { const existing = store.answers[store.tab] ?? [] const next = [...existing] if (!next.includes(value)) next.push(value) const answers = [...store.answers] answers[store.tab] = next setStore("answers", answers) setStore("editing", false) return } pick(value, true) setStore("editing", false) } return (