diff options
| author | Adam <[email protected]> | 2026-02-20 11:24:02 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-02-20 16:05:41 -0600 |
| commit | ce2763720e499ba7e7ca8021f2cbf6d62596a6e8 (patch) | |
| tree | a4ba3b0029210e0cbdbf8e888491dc95cf7189e6 /packages/app/src/components | |
| parent | 950df3de19e63e17040035ad02dec7ed680b04ac (diff) | |
| download | opencode-ce2763720e499ba7e7ca8021f2cbf6d62596a6e8.tar.gz opencode-ce2763720e499ba7e7ca8021f2cbf6d62596a6e8.zip | |
fix(app): better sound effect disabling ux
Diffstat (limited to 'packages/app/src/components')
| -rw-r--r-- | packages/app/src/components/settings-general.tsx | 102 |
1 files changed, 49 insertions, 53 deletions
diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index beb39b355..cf993840d 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -20,12 +20,17 @@ let demoSoundState = { // To prevent audio from overlapping/playing very quickly when navigating the settings menus, // delay the playback by 100ms during quick selection changes and pause existing sounds. -const playDemoSound = (src: string) => { +const stopDemoSound = () => { if (demoSoundState.cleanup) { demoSoundState.cleanup() } - clearTimeout(demoSoundState.timeout) + demoSoundState.cleanup = undefined +} + +const playDemoSound = (src: string | undefined) => { + stopDemoSound() + if (!src) return demoSoundState.timeout = setTimeout(() => { demoSoundState.cleanup = playSound(src) @@ -132,11 +137,17 @@ export const SettingsGeneral: Component = () => { ] as const const fontOptionsList = [...fontOptions] - const soundOptions = [...SOUND_OPTIONS] + const noneSound = { id: "none", label: "sound.option.none", src: undefined } as const + const soundOptions = [noneSound, ...SOUND_OPTIONS] - const soundSelectProps = (current: () => string, set: (id: string) => void) => ({ + const soundSelectProps = ( + enabled: () => boolean, + current: () => string, + setEnabled: (value: boolean) => void, + set: (id: string) => void, + ) => ({ options: soundOptions, - current: soundOptions.find((o) => o.id === current()), + current: enabled() ? (soundOptions.find((o) => o.id === current()) ?? noneSound) : noneSound, value: (o: (typeof soundOptions)[number]) => o.id, label: (o: (typeof soundOptions)[number]) => language.t(o.label), onHighlight: (option: (typeof soundOptions)[number] | undefined) => { @@ -145,6 +156,12 @@ export const SettingsGeneral: Component = () => { }, onSelect: (option: (typeof soundOptions)[number] | undefined) => { if (!option) return + if (option.id === "none") { + setEnabled(false) + stopDemoSound() + return + } + setEnabled(true) set(option.id) playDemoSound(option.src) }, @@ -319,66 +336,45 @@ export const SettingsGeneral: Component = () => { title={language.t("settings.general.sounds.agent.title")} description={language.t("settings.general.sounds.agent.description")} > - <div class="flex items-center gap-2"> - <div data-action="settings-sounds-agent-enabled"> - <Switch - checked={settings.sounds.agentEnabled()} - onChange={(checked) => settings.sounds.setAgentEnabled(checked)} - /> - </div> - <Select - disabled={!settings.sounds.agentEnabled()} - data-action="settings-sounds-agent" - {...soundSelectProps( - () => settings.sounds.agent(), - (id) => settings.sounds.setAgent(id), - )} - /> - </div> + <Select + data-action="settings-sounds-agent" + {...soundSelectProps( + () => settings.sounds.agentEnabled(), + () => settings.sounds.agent(), + (value) => settings.sounds.setAgentEnabled(value), + (id) => settings.sounds.setAgent(id), + )} + /> </SettingsRow> <SettingsRow title={language.t("settings.general.sounds.permissions.title")} description={language.t("settings.general.sounds.permissions.description")} > - <div class="flex items-center gap-2"> - <div data-action="settings-sounds-permissions-enabled"> - <Switch - checked={settings.sounds.permissionsEnabled()} - onChange={(checked) => settings.sounds.setPermissionsEnabled(checked)} - /> - </div> - <Select - disabled={!settings.sounds.permissionsEnabled()} - data-action="settings-sounds-permissions" - {...soundSelectProps( - () => settings.sounds.permissions(), - (id) => settings.sounds.setPermissions(id), - )} - /> - </div> + <Select + data-action="settings-sounds-permissions" + {...soundSelectProps( + () => settings.sounds.permissionsEnabled(), + () => settings.sounds.permissions(), + (value) => settings.sounds.setPermissionsEnabled(value), + (id) => settings.sounds.setPermissions(id), + )} + /> </SettingsRow> <SettingsRow title={language.t("settings.general.sounds.errors.title")} description={language.t("settings.general.sounds.errors.description")} > - <div class="flex items-center gap-2"> - <div data-action="settings-sounds-errors-enabled"> - <Switch - checked={settings.sounds.errorsEnabled()} - onChange={(checked) => settings.sounds.setErrorsEnabled(checked)} - /> - </div> - <Select - disabled={!settings.sounds.errorsEnabled()} - data-action="settings-sounds-errors" - {...soundSelectProps( - () => settings.sounds.errors(), - (id) => settings.sounds.setErrors(id), - )} - /> - </div> + <Select + data-action="settings-sounds-errors" + {...soundSelectProps( + () => settings.sounds.errorsEnabled(), + () => settings.sounds.errors(), + (value) => settings.sounds.setErrorsEnabled(value), + (id) => settings.sounds.setErrors(id), + )} + /> </SettingsRow> </div> </div> |
