feat: add toggle for showing draft starters on new sessions

Persists draft starter visibility across desktop and web settings
Adds a new OpenChamber visual setting with localization and search support
Hides the draft starter chips when the setting is off
This commit is contained in:
Bohdan Triapitsyn
2026-07-24 23:07:39 +03:00
parent 9ea1a2a728
commit d265a38365
20 changed files with 84 additions and 9 deletions
@@ -32,6 +32,7 @@ import { useI18n } from '@/lib/i18n';
import { useThemeSystem } from '@/contexts/useThemeSystem';
import { useDeviceInfo } from '@/lib/device';
import { cn } from '@/lib/utils';
import { useUIStore } from '@/stores/useUIStore';
import {
useDraftStarters,
type ResolvedStarter,
@@ -254,7 +255,7 @@ const AddStarterPicker: React.FC<{
* Reorder is constrained to within a chip's own group; cross-group hovers are
* ignored.
*/
export const DraftPresetChips: React.FC<DraftPresetChipsProps> = ({ onSubmit, className }) => {
const DraftPresetChipsContent: React.FC<DraftPresetChipsProps> = ({ onSubmit, className }) => {
const { global, project, pinnable, ensureLoaded, addStarter, removeStarter, reorder } = useDraftStarters();
const { isMobile } = useDeviceInfo();
const [isDragging, setIsDragging] = React.useState(false);
@@ -331,3 +332,8 @@ export const DraftPresetChips: React.FC<DraftPresetChipsProps> = ({ onSubmit, cl
</DndContext>
);
};
export const DraftPresetChips: React.FC<DraftPresetChipsProps> = (props) => {
const visible = useUIStore((state) => state.draftStartersVisible);
return visible ? <DraftPresetChipsContent {...props} /> : null;
};
@@ -381,6 +381,8 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
const setShowSplitAssistantMessageActions = useUIStore(state => state.setShowSplitAssistantMessageActions);
const allowPromptingSubagentSessions = useUIStore(state => state.allowPromptingSubagentSessions);
const setAllowPromptingSubagentSessions = useUIStore(state => state.setAllowPromptingSubagentSessions);
const draftStartersVisible = useUIStore(state => state.draftStartersVisible);
const setDraftStartersVisible = useUIStore(state => state.setDraftStartersVisible);
const messageStreamTransport = useConfigStore((state) => state.settingsMessageStreamTransport);
const setMessageStreamTransport = useConfigStore((state) => state.setSettingsMessageStreamTransport);
const effectiveMessageStreamTransport = messageStreamTransport;
@@ -500,6 +502,11 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
void updateDesktopSettings({ promptNavigatorEnabled: enabled });
}, [setPromptNavigatorEnabled]);
const handleDraftStartersVisibleChange = React.useCallback((enabled: boolean) => {
setDraftStartersVisible(enabled);
void updateDesktopSettings({ draftStartersVisible: enabled });
}, [setDraftStartersVisible]);
const handleExpandedEditorToolbarChange = React.useCallback((enabled: boolean) => {
setExpandedEditorToolbar(enabled);
void updateDesktopSettings({ expandedEditorToolbar: enabled });
@@ -1766,12 +1773,18 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
/>
</SettingsSection>
)}
{(shouldShow('sessionAssist') || shouldShow('subagentReadOnlyBanner')) && (
<SettingsSection
title={t('settings.openchamber.visual.section.sessionAssistance')}
settingsItem="chat.session-assistance"
contentClassName={SETTINGS_OPTION_STACK_CLASS}
>
<SettingsSection
title={t('settings.openchamber.visual.section.sessionAssistance')}
settingsItem="chat.session-assistance"
contentClassName={SETTINGS_OPTION_STACK_CLASS}
>
<SettingsCheckboxRow
checked={draftStartersVisible}
onChange={handleDraftStartersVisibleChange}
label={t('settings.openchamber.visual.field.draftStartersVisible')}
ariaLabel={t('settings.openchamber.visual.field.draftStartersVisibleAria')}
settingsItem="chat.draft-starters-visible"
/>
{shouldShow('sessionAssist') && (
<>
<SettingsCheckboxRow
@@ -1799,8 +1812,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
settingsItem="chat.subagent-read-only-banner"
/>
)}
</SettingsSection>
)}
</SettingsSection>
{/* 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 && (