summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages/session/composer
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-30 08:50:42 -0500
committerGitHub <[email protected]>2026-03-30 08:50:42 -0500
commitc2f78224ae59263eada831051a6ece1c65126b1a (patch)
tree23468fdd7e2910266756944aa764f7fdcf696d25 /packages/app/src/pages/session/composer
parent14f9e21d5c3f4e853dee8ca133693dd3b915b634 (diff)
downloadopencode-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.tsx167
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>