feat: group chat visual settings into labeled sections

Adds section headers and tooltip help for the goal settings area
Reorganizes chat settings into Session Assistance, Reasoning, Message Appearance, Tools & Files, and Composer groups
Adds localized labels and search entries for the new section headings
This commit is contained in:
Bohdan Triapitsyn
2026-07-13 01:33:19 +03:00
parent 9b645f0e53
commit 9dd389fe8e
12 changed files with 143 additions and 34 deletions
@@ -1824,11 +1824,18 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
{/* The goal loop runs in the web server — VS Code only renders
goal state, so the settings section is hidden there too. */}
{shouldShow('sessionGoal') && !isVSCode && (
<div className="mb-8">
<div className="mb-1 px-1">
<section className="p-2 mb-6 space-y-0.5">
<div className="flex items-center gap-1.5 py-1.5">
<h3 className="typography-ui-header font-medium text-foreground">{t('settings.openchamber.visual.goal.sectionTitle')}</h3>
<Tooltip>
<TooltipTrigger asChild>
<Icon name="information" className="h-3.5 w-3.5 cursor-help text-muted-foreground/60" />
</TooltipTrigger>
<TooltipContent sideOffset={8} className="max-w-sm">
{t('settings.openchamber.visual.goal.description')}
</TooltipContent>
</Tooltip>
</div>
<section className="p-2 space-y-0.5">
<div
data-settings-item="chat.session-goal"
className="group flex cursor-pointer items-center gap-2 py-0.5"
@@ -1891,14 +1898,15 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
/>
) : null}
</div>
<p className="typography-meta text-muted-foreground/70 px-0.5 pt-0.5">{t('settings.openchamber.visual.goal.description')}</p>
</section>
</div>
</section>
)}
{(shouldShow('sessionAssist') || shouldShow('collapsibleUserMessages') || shouldShow('stickyUserHeader') || shouldShow('wideChatLayout') || shouldShow('codeBlockLineWrap') || shouldShow('splitAssistantMessageActions') || shouldShow('subagentReadOnlyBanner') || shouldShow('dotfiles') || shouldShow('fileViewerPreview') || shouldShow('persistDraft') || shouldShow('showToolFileIcons') || shouldShow('showTurnChangedFiles') || (!isMobile && shouldShow('inputSpellcheck')) || shouldShow('reasoning')) && (
<section className="p-2 space-y-0.5">
{shouldShow('sessionAssist') && (
<div className="space-y-6">
{(shouldShow('sessionAssist') || shouldShow('subagentReadOnlyBanner')) && (
<section className="p-2 space-y-0.5">
<h3 data-settings-item="chat.session-assistance" className="typography-ui-header font-medium text-foreground py-1.5">{t('settings.openchamber.visual.section.sessionAssistance')}</h3>
{shouldShow('sessionAssist') && (
<>
<div
data-settings-item="chat.session-recap"
@@ -1943,7 +1951,35 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.sessionSuggestion')}</span>
</div>
</>
)}
{shouldShow('subagentReadOnlyBanner') && (
<div
data-settings-item="chat.subagent-read-only-banner"
className="group flex cursor-pointer items-center gap-2 py-0.5"
role="button"
tabIndex={0}
aria-pressed={allowPromptingSubagentSessions}
onClick={() => setAllowPromptingSubagentSessions(!allowPromptingSubagentSessions)}
onKeyDown={(event) => {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
setAllowPromptingSubagentSessions(!allowPromptingSubagentSessions);
}
}}
>
<Checkbox
checked={allowPromptingSubagentSessions}
onChange={setAllowPromptingSubagentSessions}
ariaLabel={t('settings.openchamber.visual.field.allowPromptingSubagentSessionsAria')}
/>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.allowPromptingSubagentSessions')}</span>
</div>
)}
</section>
)}
{shouldShow('reasoning') && (
<section className="p-2 space-y-0.5">
<h3 data-settings-item="chat.reasoning" className="typography-ui-header font-medium text-foreground py-1.5">{t('settings.openchamber.visual.section.reasoning')}</h3>
{shouldShow('reasoning') && (
<div
data-settings-item="chat.reasoning-traces"
@@ -1990,7 +2026,12 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.collapsibleThinkingBlocks')}</span>
</div>
)}
</section>
)}
{(shouldShow('collapsibleUserMessages') || shouldShow('stickyUserHeader') || shouldShow('wideChatLayout') || shouldShow('splitAssistantMessageActions') || shouldShow('codeBlockLineWrap')) && (
<section className="p-2 space-y-0.5">
<h3 data-settings-item="chat.message-appearance" className="typography-ui-header font-medium text-foreground py-1.5">{t('settings.openchamber.visual.section.messageAppearance')}</h3>
{shouldShow('collapsibleUserMessages') && (
<div
data-settings-item="chat.collapsible-user-messages"
@@ -2097,30 +2138,6 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
</div>
)}
{shouldShow('subagentReadOnlyBanner') && (
<div
data-settings-item="chat.subagent-read-only-banner"
className="group flex cursor-pointer items-center gap-2 py-0.5"
role="button"
tabIndex={0}
aria-pressed={allowPromptingSubagentSessions}
onClick={() => setAllowPromptingSubagentSessions(!allowPromptingSubagentSessions)}
onKeyDown={(event) => {
if (event.key === ' ' || event.key === 'Enter') {
event.preventDefault();
setAllowPromptingSubagentSessions(!allowPromptingSubagentSessions);
}
}}
>
<Checkbox
checked={allowPromptingSubagentSessions}
onChange={setAllowPromptingSubagentSessions}
ariaLabel={t('settings.openchamber.visual.field.allowPromptingSubagentSessionsAria')}
/>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.allowPromptingSubagentSessions')}</span>
</div>
)}
{shouldShow('codeBlockLineWrap') && (
<div
data-settings-item="chat.code-block-line-wrap"
@@ -2144,7 +2161,12 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.codeBlockLineWrap')}</span>
</div>
)}
</section>
)}
{(shouldShow('showToolFileIcons') || shouldShow('showTurnChangedFiles') || shouldShow('dotfiles') || shouldShow('fileViewerPreview')) && (
<section className="p-2 space-y-0.5">
<h3 data-settings-item="chat.tools-and-files" className="typography-ui-header font-medium text-foreground py-1.5">{t('settings.openchamber.visual.section.toolsAndFiles')}</h3>
{shouldShow('showToolFileIcons') && (
<div
data-settings-item="chat.tool-file-icons"
@@ -2241,7 +2263,12 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.defaults.field.openFilesPreview')}</span>
</div>
)}
</section>
)}
{(shouldShow('persistDraft') || (!isMobile && shouldShow('inputSpellcheck'))) && (
<section className="p-2 space-y-0.5">
<h3 data-settings-item="chat.composer" className="typography-ui-header font-medium text-foreground py-1.5">{t('settings.openchamber.visual.section.composer')}</h3>
{shouldShow('persistDraft') && (
<div
data-settings-item="chat.persist-drafts"
@@ -2269,7 +2296,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
{!isMobile && shouldShow('inputSpellcheck') && (
<div
data-settings-item="chat.spellcheck"
className="group flex cursor-pointer items-center gap-2 py-1.5"
className="group flex cursor-pointer items-center gap-2 py-0.5"
role="button"
tabIndex={0}
aria-pressed={inputSpellcheckEnabled}
@@ -2289,8 +2316,10 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.enableSpellcheckInTextInputs')}</span>
</div>
)}
</section>
)}
</section>
</div>
)}
</div>
@@ -1702,6 +1702,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.activityDefault': 'Activity Default',
'settings.openchamber.visual.section.activityDefaultAria': 'Activity default mode',
'settings.openchamber.visual.section.showToolsOpenedByDefault': 'Show tools opened by default:',
'settings.openchamber.visual.section.sessionAssistance': 'Session Assistance',
'settings.openchamber.visual.section.reasoning': 'Reasoning',
'settings.openchamber.visual.section.messageAppearance': 'Message Appearance',
'settings.openchamber.visual.section.toolsAndFiles': 'Tools & Files',
'settings.openchamber.visual.section.composer': 'Composer',
'settings.openchamber.visual.section.userMessageRendering': 'User Message Rendering',
'settings.openchamber.visual.section.userMessageRenderingAria': 'User message rendering mode',
'settings.openchamber.visual.section.mermaidRendering': 'Mermaid Rendering',
@@ -1669,6 +1669,11 @@ export const settingsDict = {
"settings.openchamber.visual.section.activityDefault": "Modo predeterminado de actividad",
"settings.openchamber.visual.section.activityDefaultAria": "Modo predeterminado de actividad",
"settings.openchamber.visual.section.showToolsOpenedByDefault": "Mostrar herramientas abiertas por defecto:",
"settings.openchamber.visual.section.sessionAssistance": "Asistencia de sesión",
"settings.openchamber.visual.section.reasoning": "Razonamiento",
"settings.openchamber.visual.section.messageAppearance": "Apariencia de los mensajes",
"settings.openchamber.visual.section.toolsAndFiles": "Herramientas y archivos",
"settings.openchamber.visual.section.composer": "Compositor",
"settings.openchamber.visual.section.userMessageRendering": "Renderizado de mensajes del usuario",
"settings.openchamber.visual.section.userMessageRenderingAria": "Modo de Renderizado de mensajes del usuario",
"settings.openchamber.visual.section.mermaidRendering": "Renderizado de Mermaid",
@@ -1587,6 +1587,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.activityDefault': 'Activité par défaut',
'settings.openchamber.visual.section.activityDefaultAria': 'Mode d\'activité par défaut',
'settings.openchamber.visual.section.showToolsOpenedByDefault': 'Afficher les outils ouverts par défaut :',
'settings.openchamber.visual.section.sessionAssistance': 'Assistance de session',
'settings.openchamber.visual.section.reasoning': 'Raisonnement',
'settings.openchamber.visual.section.messageAppearance': 'Apparence des messages',
'settings.openchamber.visual.section.toolsAndFiles': 'Outils et fichiers',
'settings.openchamber.visual.section.composer': 'Zone de saisie',
'settings.openchamber.visual.section.userMessageRendering': 'Rendu des messages utilisateur',
'settings.openchamber.visual.section.userMessageRenderingAria': 'Mode de rendu des messages utilisateur',
'settings.openchamber.visual.section.mermaidRendering': 'Rendu Mermaid',
@@ -1702,6 +1702,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.activityDefault': 'アクティビティデフォルト',
'settings.openchamber.visual.section.activityDefaultAria': 'アクティビティデフォルトモード',
'settings.openchamber.visual.section.showToolsOpenedByDefault': 'デフォルトで開くツールを表示:',
'settings.openchamber.visual.section.sessionAssistance': 'セッション支援',
'settings.openchamber.visual.section.reasoning': '推論',
'settings.openchamber.visual.section.messageAppearance': 'メッセージの外観',
'settings.openchamber.visual.section.toolsAndFiles': 'ツールとファイル',
'settings.openchamber.visual.section.composer': '入力欄',
'settings.openchamber.visual.section.userMessageRendering': 'ユーザーメッセージ表示',
'settings.openchamber.visual.section.userMessageRenderingAria': 'ユーザーメッセージ表示モード',
'settings.openchamber.visual.section.mermaidRendering': 'Mermaid 表示',
@@ -1669,6 +1669,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.activityDefault': 'Activity 기본값',
'settings.openchamber.visual.section.activityDefaultAria': 'Activity 기본 모드',
'settings.openchamber.visual.section.showToolsOpenedByDefault': '도구를 기본으로 펼쳐 표시:',
'settings.openchamber.visual.section.sessionAssistance': '세션 지원',
'settings.openchamber.visual.section.reasoning': '추론',
'settings.openchamber.visual.section.messageAppearance': '메시지 모양',
'settings.openchamber.visual.section.toolsAndFiles': '도구 및 파일',
'settings.openchamber.visual.section.composer': '입력창',
'settings.openchamber.visual.section.userMessageRendering': '사용자 메시지 렌더링',
'settings.openchamber.visual.section.userMessageRenderingAria': '사용자 메시지 렌더링 모드',
'settings.openchamber.visual.section.mermaidRendering': 'Mermaid 렌더링',
@@ -1110,6 +1110,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.navigation': 'Nawigacja',
'settings.openchamber.visual.section.privacy': 'Prywatność',
'settings.openchamber.visual.section.showToolsOpenedByDefault': 'Pokaż narzędzia domyślnie otwarte:',
'settings.openchamber.visual.section.sessionAssistance': 'Wsparcie sesji',
'settings.openchamber.visual.section.reasoning': 'Rozumowanie',
'settings.openchamber.visual.section.messageAppearance': 'Wygląd wiadomości',
'settings.openchamber.visual.section.toolsAndFiles': 'Narzędzia i pliki',
'settings.openchamber.visual.section.composer': 'Pole wiadomości',
'settings.openchamber.visual.section.spacingAndLayout': 'Odstępy i układ',
'settings.openchamber.visual.section.userMessageRendering': 'Renderowanie wiadomości użytkownika',
'settings.openchamber.visual.section.userMessageRenderingAria': 'Tryb renderowania wiadomości użytkownika',
@@ -1669,6 +1669,11 @@ export const settingsDict = {
"settings.openchamber.visual.section.activityDefault": "Modo padrão de atividade",
"settings.openchamber.visual.section.activityDefaultAria": "Modo padrão de atividade",
"settings.openchamber.visual.section.showToolsOpenedByDefault": "Mostrar ferramentas abertas por padrão:",
"settings.openchamber.visual.section.sessionAssistance": "Assistência da sessão",
"settings.openchamber.visual.section.reasoning": "Raciocínio",
"settings.openchamber.visual.section.messageAppearance": "Aparência das mensagens",
"settings.openchamber.visual.section.toolsAndFiles": "Ferramentas e arquivos",
"settings.openchamber.visual.section.composer": "Campo de mensagem",
"settings.openchamber.visual.section.userMessageRendering": "Renderizado de mensagens do usuário",
"settings.openchamber.visual.section.userMessageRenderingAria": "Modo de Renderizado de mensagens do usuário",
"settings.openchamber.visual.section.mermaidRendering": "Renderizado de Mermaid",
@@ -1669,6 +1669,11 @@ export const settingsDict = {
"settings.openchamber.visual.section.activityDefault": "Активність за замовчуванням",
"settings.openchamber.visual.section.activityDefaultAria": "Режим активності за замовчуванням",
"settings.openchamber.visual.section.showToolsOpenedByDefault": "Показувати інструменти відкритими за замовчуванням:",
"settings.openchamber.visual.section.sessionAssistance": "Допомога із сесією",
"settings.openchamber.visual.section.reasoning": "Міркування",
"settings.openchamber.visual.section.messageAppearance": "Вигляд повідомлень",
"settings.openchamber.visual.section.toolsAndFiles": "Інструменти та файли",
"settings.openchamber.visual.section.composer": "Поле вводу",
"settings.openchamber.visual.section.userMessageRendering": "Відображення повідомлень користувача",
"settings.openchamber.visual.section.userMessageRenderingAria": "Режим відтворення повідомлень користувача",
"settings.openchamber.visual.section.mermaidRendering": "Візуалізація Mermaid",
@@ -1669,6 +1669,11 @@ export const settingsDict = {
'settings.openchamber.visual.section.activityDefault': '活动默认状态',
'settings.openchamber.visual.section.activityDefaultAria': '活动默认模式',
'settings.openchamber.visual.section.showToolsOpenedByDefault': '默认展开以下工具:',
'settings.openchamber.visual.section.sessionAssistance': '会话辅助',
'settings.openchamber.visual.section.reasoning': '推理',
'settings.openchamber.visual.section.messageAppearance': '消息外观',
'settings.openchamber.visual.section.toolsAndFiles': '工具和文件',
'settings.openchamber.visual.section.composer': '输入框',
'settings.openchamber.visual.section.userMessageRendering': '用户消息渲染',
'settings.openchamber.visual.section.userMessageRenderingAria': '用户消息渲染模式',
'settings.openchamber.visual.section.mermaidRendering': 'Mermaid 渲染',
@@ -1578,6 +1578,11 @@
'settings.openchamber.visual.section.activityDefault': '活動預設狀態',
'settings.openchamber.visual.section.activityDefaultAria': '活動預設模式',
'settings.openchamber.visual.section.showToolsOpenedByDefault': '預設展開以下工具:',
'settings.openchamber.visual.section.sessionAssistance': '工作階段輔助',
'settings.openchamber.visual.section.reasoning': '推理',
'settings.openchamber.visual.section.messageAppearance': '訊息外觀',
'settings.openchamber.visual.section.toolsAndFiles': '工具與檔案',
'settings.openchamber.visual.section.composer': '輸入框',
'settings.openchamber.visual.section.userMessageRendering': '使用者訊息渲染',
'settings.openchamber.visual.section.userMessageRenderingAria': '使用者訊息渲染模式',
'settings.openchamber.visual.section.mermaidRendering': 'Mermaid 渲染',
+30
View File
@@ -180,6 +180,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.sessionRecap',
keywords: ['recap', 'assist', 'small model', 'summary'],
},
{
id: 'chat.session-assistance',
page: 'chat',
titleKey: 'settings.openchamber.visual.section.sessionAssistance',
keywords: ['recap', 'suggestion', 'subagent'],
},
{
id: 'chat.session-suggestion',
page: 'chat',
@@ -206,6 +212,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.showReasoningTraces',
keywords: ['thinking', 'reasoning'],
},
{
id: 'chat.reasoning',
page: 'chat',
titleKey: 'settings.openchamber.visual.section.reasoning',
keywords: ['thinking', 'traces'],
},
{
id: 'chat.sticky-user-header',
page: 'chat',
@@ -224,6 +236,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.wideChatLayout',
keywords: ['layout', 'wide', 'messages'],
},
{
id: 'chat.message-appearance',
page: 'chat',
titleKey: 'settings.openchamber.visual.section.messageAppearance',
keywords: ['layout', 'messages', 'appearance'],
},
{
id: 'chat.code-block-line-wrap',
page: 'chat',
@@ -249,6 +267,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.showToolFileIcons',
keywords: ['tools', 'files', 'icons'],
},
{
id: 'chat.tools-and-files',
page: 'chat',
titleKey: 'settings.openchamber.visual.section.toolsAndFiles',
keywords: ['tools', 'files', 'dotfiles'],
},
{
id: 'chat.changed-files',
page: 'chat',
@@ -275,6 +299,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.openchamber.visual.field.persistDraftMessages',
keywords: ['draft', 'message'],
},
{
id: 'chat.composer',
page: 'chat',
titleKey: 'settings.openchamber.visual.section.composer',
keywords: ['input', 'draft', 'spellcheck'],
},
{
id: 'chat.spellcheck',
page: 'chat',