diff options
| author | Adam <[email protected]> | 2026-03-30 08:50:42 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-03-30 08:50:42 -0500 |
| commit | c2f78224ae59263eada831051a6ece1c65126b1a (patch) | |
| tree | 23468fdd7e2910266756944aa764f7fdcf696d25 /packages/app/src/pages/session/composer | |
| parent | 14f9e21d5c3f4e853dee8ca133693dd3b915b634 (diff) | |
| download | opencode-c2f78224ae59263eada831051a6ece1c65126b1a.tar.gz opencode-c2f78224ae59263eada831051a6ece1c65126b1a.zip | |
chore(app): cleanup (#20062)
Diffstat (limited to 'packages/app/src/pages/session/composer')
| -rw-r--r-- | packages/app/src/pages/session/composer/session-question-dock.tsx | 167 |
1 files changed, 89 insertions, 78 deletions
diff --git a/packages/app/src/pages/session/composer/session-question-dock.tsx b/packages/app/src/pages/session/composer/session-question-dock.tsx index 7ba07b15d..ef1e52d26 100644 --- a/packages/app/src/pages/session/composer/session-question-dock.tsx +++ b/packages/app/src/pages/session/composer/session-question-dock.tsx @@ -11,6 +11,47 @@ import { useSDK } from "@/context/sdk" const cache = new Map<string, { tab: number; answers: QuestionAnswer[]; custom: string[]; customOn: boolean[] }>() +function Mark(props: { multi: boolean; picked: boolean; onClick?: (event: MouseEvent) => void }) { + return ( + <span data-slot="question-option-check" aria-hidden="true" onClick={props.onClick}> + <span data-slot="question-option-box" data-type={props.multi ? "checkbox" : "radio"} data-picked={props.picked}> + <Show when={props.multi} fallback={<span data-slot="question-option-radio-dot" />}> + <Icon name="check-small" size="small" /> + </Show> + </span> + </span> + ) +} + +function Option(props: { + multi: boolean + picked: boolean + label: string + description?: string + disabled: boolean + onClick: VoidFunction +}) { + return ( + <button + type="button" + data-slot="question-option" + data-picked={props.picked} + role={props.multi ? "checkbox" : "radio"} + aria-checked={props.picked} + disabled={props.disabled} + onClick={props.onClick} + > + <Mark multi={props.multi} picked={props.picked} /> + <span data-slot="question-option-main"> + <span data-slot="option-label">{props.label}</span> + <Show when={props.description}> + <span data-slot="option-description">{props.description}</span> + </Show> + </span> + </button> + ) +} + export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit: () => void }> = (props) => { const sdk = useSDK() const language = useLanguage() @@ -41,6 +82,9 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit return language.t("session.question.progress", { current: n, total: total() }) }) + const customLabel = () => language.t("ui.messagePart.option.typeOwnAnswer") + const customPlaceholder = () => language.t("ui.question.custom.placeholder") + const last = createMemo(() => store.tab >= total() - 1) const customUpdate = (value: string, selected: boolean = on()) => { @@ -164,6 +208,13 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit const submit = () => void reply(questions().map((_, i) => store.answers[i] ?? [])) + const answered = (i: number) => { + if ((store.answers[i]?.length ?? 0) > 0) return true + return store.customOn[i] === true && (store.custom[i] ?? "").trim().length > 0 + } + + const picked = (answer: string) => store.answers[store.tab]?.includes(answer) ?? false + const pick = (answer: string, custom: boolean = false) => { setStore("answers", store.tab, [answer]) if (custom) setStore("custom", store.tab, answer) @@ -230,6 +281,24 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit customUpdate(input()) } + const resizeInput = (el: HTMLTextAreaElement) => { + el.style.height = "0px" + el.style.height = `${el.scrollHeight}px` + } + + const focusCustom = (el: HTMLTextAreaElement) => { + setTimeout(() => { + el.focus() + resizeInput(el) + }, 0) + } + + const toggleCustomMark = (event: MouseEvent) => { + event.preventDefault() + event.stopPropagation() + customToggle() + } + const next = () => { if (sending()) return if (store.editing) commitCustom() @@ -270,10 +339,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit type="button" data-slot="question-progress-segment" data-active={i() === store.tab} - data-answered={ - (store.answers[i()]?.length ?? 0) > 0 || - (store.customOn[i()] === true && (store.custom[i()] ?? "").trim().length > 0) - } + data-answered={answered(i())} disabled={sending()} onClick={() => jump(i())} aria-label={`${language.t("ui.tool.questions")} ${i() + 1}`} @@ -307,43 +373,23 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit </Show> <div data-slot="question-options"> <For each={options()}> - {(opt, i) => { - const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false - return ( - <button - data-slot="question-option" - data-picked={picked()} - role={multi() ? "checkbox" : "radio"} - aria-checked={picked()} - disabled={sending()} - onClick={() => selectOption(i())} - > - <span data-slot="question-option-check" aria-hidden="true"> - <span - data-slot="question-option-box" - data-type={multi() ? "checkbox" : "radio"} - data-picked={picked()} - > - <Show when={multi()} fallback={<span data-slot="question-option-radio-dot" />}> - <Icon name="check-small" size="small" /> - </Show> - </span> - </span> - <span data-slot="question-option-main"> - <span data-slot="option-label">{opt.label}</span> - <Show when={opt.description}> - <span data-slot="option-description">{opt.description}</span> - </Show> - </span> - </button> - ) - }} + {(opt, i) => ( + <Option + multi={multi()} + picked={picked(opt.label)} + label={opt.label} + description={opt.description} + disabled={sending()} + onClick={() => selectOption(i())} + /> + )} </For> <Show when={store.editing} fallback={ <button + type="button" data-slot="question-option" data-custom="true" data-picked={on()} @@ -352,24 +398,10 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit disabled={sending()} onClick={customOpen} > - <span - data-slot="question-option-check" - aria-hidden="true" - onClick={(e) => { - e.preventDefault() - e.stopPropagation() - customToggle() - }} - > - <span data-slot="question-option-box" data-type={multi() ? "checkbox" : "radio"} data-picked={on()}> - <Show when={multi()} fallback={<span data-slot="question-option-radio-dot" />}> - <Icon name="check-small" size="small" /> - </Show> - </span> - </span> + <Mark multi={multi()} picked={on()} onClick={toggleCustomMark} /> <span data-slot="question-option-main"> - <span data-slot="option-label">{language.t("ui.messagePart.option.typeOwnAnswer")}</span> - <span data-slot="option-description">{input() || language.t("ui.question.custom.placeholder")}</span> + <span data-slot="option-label">{customLabel()}</span> + <span data-slot="option-description">{input() || customPlaceholder()}</span> </span> </button> } @@ -394,33 +426,13 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit commitCustom() }} > - <span - data-slot="question-option-check" - aria-hidden="true" - onClick={(e) => { - e.preventDefault() - e.stopPropagation() - customToggle() - }} - > - <span data-slot="question-option-box" data-type={multi() ? "checkbox" : "radio"} data-picked={on()}> - <Show when={multi()} fallback={<span data-slot="question-option-radio-dot" />}> - <Icon name="check-small" size="small" /> - </Show> - </span> - </span> + <Mark multi={multi()} picked={on()} onClick={toggleCustomMark} /> <span data-slot="question-option-main"> - <span data-slot="option-label">{language.t("ui.messagePart.option.typeOwnAnswer")}</span> + <span data-slot="option-label">{customLabel()}</span> <textarea - ref={(el) => - setTimeout(() => { - el.focus() - el.style.height = "0px" - el.style.height = `${el.scrollHeight}px` - }, 0) - } + ref={focusCustom} data-slot="question-custom-input" - placeholder={language.t("ui.question.custom.placeholder")} + placeholder={customPlaceholder()} value={input()} rows={1} disabled={sending()} @@ -436,8 +448,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit }} onInput={(e) => { customUpdate(e.currentTarget.value) - e.currentTarget.style.height = "0px" - e.currentTarget.style.height = `${e.currentTarget.scrollHeight}px` + resizeInput(e.currentTarget) }} /> </span> |
