From f21778fcf30fa50a022e8ed7bacf66493964cfb5 Mon Sep 17 00:00:00 2001 From: James Pine Date: Thu, 23 Apr 2026 19:33:14 -0700 Subject: [PATCH] feat(captures): mirror readiness checklist into the settings sidebar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The six-gate checklist only rendered in the CapturesTab empty state, so a user already on the settings page had no single surface showing which gate was red — the inline InputMonitoringNotice covered one, the model pickers covered another, and Accessibility was only hinted at by the auto-paste toggle. Mirror the same component into the right sidebar of the settings page so every gate (STT model, LLM model, Input Monitoring, Accessibility, plus the hotkey toggle in the main column) is always visible while the user configures dictation. New compact prop on DictationReadinessChecklist drops the centered header and empty-state max-width so it fits the 280 px sidebar next to the existing About / Differences blocks. Callers in compact mode own the heading — CapturesPage reuses the existing captures.readiness.title key (present in en / ja / zh-CN / zh-TW already) as an h3 matching the sibling sidebar sections. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../DictationReadinessChecklist.tsx | 34 +++++++++++++------ app/src/components/ServerTab/CapturesPage.tsx | 10 ++++++ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/app/src/components/CapturesTab/DictationReadinessChecklist.tsx b/app/src/components/CapturesTab/DictationReadinessChecklist.tsx index a26e9655..0fd6279f 100644 --- a/app/src/components/CapturesTab/DictationReadinessChecklist.tsx +++ b/app/src/components/CapturesTab/DictationReadinessChecklist.tsx @@ -73,8 +73,20 @@ function progressPercent(task: ActiveDownloadTask | undefined): number | null { * * The chord stays disarmed until every row is green; this is what stops the * "stuck pill" failure mode of pressing the chord with a missing model. + * + * ``compact`` drops the centered title/subheading block and the + * empty-state max-width so the checklist can be embedded in a narrow + * sidebar alongside other settings. Callers own their own heading in + * that mode (typically an ``

`` that matches the surrounding sidebar + * section style). */ -export function DictationReadinessChecklist({ readiness }: { readiness: DictationReadiness }) { +export function DictationReadinessChecklist({ + readiness, + compact = false, +}: { + readiness: DictationReadiness; + compact?: boolean; +}) { const { t } = useTranslation(); const queryClient = useQueryClient(); const { toast } = useToast(); @@ -176,15 +188,17 @@ export function DictationReadinessChecklist({ readiness }: { readiness: Dictatio } return ( -
-
-

- {t('captures.readiness.title')} -

-

- {t('captures.readiness.subheading')} -

-
+
+ {!compact && ( +
+

+ {t('captures.readiness.title')} +

+

+ {t('captures.readiness.subheading')} +

+
+ )} {readiness.stt && (
+ {/* Same six-gate checklist the CapturesTab empty state uses. + Surfaces missing models / permissions persistently while + users configure this page, so a red gate can't hide behind + a green toggle. */} +
+

{t('captures.readiness.title')}

+ +
+

{t('settings.captures.sidebar.differencesTitle')}