feat(P3-6): configurable composer toolbar buttons
Each button (Format, Emoji, Sticker, GIF, Location, Poll, Voice, Schedule) can be individually hidden in Settings → Editor. All default to on, stored in composerToolbarButtons object. getSettings deep-merges the nested object so new buttons default to true for existing users with saved settings. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,7 @@ import { SequenceCard } from '../../../components/sequence-card';
|
||||
import { useSetting } from '../../../state/hooks/settings';
|
||||
import {
|
||||
ChatBackground,
|
||||
ComposerToolbarSettings,
|
||||
DateFormat,
|
||||
MessageLayout,
|
||||
MessageSpacing,
|
||||
@@ -855,6 +856,14 @@ function Editor() {
|
||||
const [enterForNewline, setEnterForNewline] = useSetting(settingsAtom, 'enterForNewline');
|
||||
const [isMarkdown, setIsMarkdown] = useSetting(settingsAtom, 'isMarkdown');
|
||||
const [editorToolbar, setEditorToolbar] = useSetting(settingsAtom, 'editorToolbar');
|
||||
const [composerToolbarButtons, setComposerToolbarButtons] = useSetting(
|
||||
settingsAtom,
|
||||
'composerToolbarButtons',
|
||||
);
|
||||
|
||||
const toggleToolbarButton = (key: keyof ComposerToolbarSettings) => {
|
||||
setComposerToolbarButtons({ ...composerToolbarButtons, [key]: !composerToolbarButtons[key] });
|
||||
};
|
||||
|
||||
return (
|
||||
<Box direction="Column" gap="100">
|
||||
@@ -881,6 +890,90 @@ function Editor() {
|
||||
after={<Switch variant="Primary" value={editorToolbar} onChange={setEditorToolbar} />}
|
||||
/>
|
||||
</SequenceCard>
|
||||
<Text size="L400" style={{ marginTop: '8px' }}>Composer Toolbar Buttons</Text>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SettingTile
|
||||
title="Format Toggle"
|
||||
description="Button to show/hide the text formatting toolbar."
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showFormat ?? true}
|
||||
onChange={() => toggleToolbarButton('showFormat')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Emoji"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showEmoji ?? true}
|
||||
onChange={() => toggleToolbarButton('showEmoji')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Sticker"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showSticker ?? true}
|
||||
onChange={() => toggleToolbarButton('showSticker')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="GIF"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showGif ?? true}
|
||||
onChange={() => toggleToolbarButton('showGif')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Location"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showLocation ?? true}
|
||||
onChange={() => toggleToolbarButton('showLocation')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Poll"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showPoll ?? true}
|
||||
onChange={() => toggleToolbarButton('showPoll')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Voice Message"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showVoice ?? true}
|
||||
onChange={() => toggleToolbarButton('showVoice')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Schedule Message"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showSchedule ?? true}
|
||||
onChange={() => toggleToolbarButton('showSchedule')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</SequenceCard>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user