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 = async (answers: QuestionAnswer[]) => { if (store.sending) return setStore("sending", true) try { await sdk.client.question.reply({ requestID: props.request.id, answers }) } catch (err) { fail(err) } finally { setStore("sending", false) } } const reject = async () => { if (store.sending) return setStore("sending", true) try { await sdk.client.question.reject({ requestID: props.request.id }) } catch (err) { fail(err) } finally { setStore("sending", false) } } const submit = () => { void reply(questions().map((_, i) => store.answers[i] ?? [])) } const pick = (answer: string, custom: boolean = false) => { setStore("answers", store.tab, [answer]) if (custom) { setStore("custom", store.tab, answer) } if (single()) { void reply([[answer]]) return } setStore("tab", store.tab + 1) } const toggle = (answer: string) => { setStore("answers", store.tab, (current = []) => { if (current.includes(answer)) return current.filter((item) => item !== answer) return [...current, answer] }) } 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()) { setStore("answers", store.tab, (current = []) => { if (current.includes(value)) return current return [...current, value] }) setStore("editing", false) return } pick(value, true) setStore("editing", false) } return (