summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-20 11:24:02 -0600
committerAdam <[email protected]>2026-02-20 16:05:41 -0600
commitce2763720e499ba7e7ca8021f2cbf6d62596a6e8 (patch)
treea4ba3b0029210e0cbdbf8e888491dc95cf7189e6
parent950df3de19e63e17040035ad02dec7ed680b04ac (diff)
downloadopencode-ce2763720e499ba7e7ca8021f2cbf6d62596a6e8.tar.gz
opencode-ce2763720e499ba7e7ca8021f2cbf6d62596a6e8.zip
fix(app): better sound effect disabling ux
-rw-r--r--packages/app/src/components/settings-general.tsx102
-rw-r--r--packages/app/src/i18n/ar.ts1
-rw-r--r--packages/app/src/i18n/br.ts1
-rw-r--r--packages/app/src/i18n/bs.ts1
-rw-r--r--packages/app/src/i18n/da.ts1
-rw-r--r--packages/app/src/i18n/de.ts1
-rw-r--r--packages/app/src/i18n/en.ts1
-rw-r--r--packages/app/src/i18n/es.ts1
-rw-r--r--packages/app/src/i18n/fr.ts1
-rw-r--r--packages/app/src/i18n/ja.ts1
-rw-r--r--packages/app/src/i18n/ko.ts1
-rw-r--r--packages/app/src/i18n/no.ts1
-rw-r--r--packages/app/src/i18n/pl.ts1
-rw-r--r--packages/app/src/i18n/ru.ts1
-rw-r--r--packages/app/src/i18n/th.ts1
-rw-r--r--packages/app/src/i18n/zh.ts1
-rw-r--r--packages/app/src/i18n/zht.ts1
17 files changed, 65 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>
diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts
index 69a3a86cb..e860a7e5d 100644
--- a/packages/app/src/i18n/ar.ts
+++ b/packages/app/src/i18n/ar.ts
@@ -565,6 +565,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "بلا",
"sound.option.alert01": "تنبيه 01",
"sound.option.alert02": "تنبيه 02",
"sound.option.alert03": "تنبيه 03",
diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts
index 1c37317a3..e96a0195d 100644
--- a/packages/app/src/i18n/br.ts
+++ b/packages/app/src/i18n/br.ts
@@ -571,6 +571,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Nenhum",
"sound.option.alert01": "Alerta 01",
"sound.option.alert02": "Alerta 02",
"sound.option.alert03": "Alerta 03",
diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts
index 59bab1eb8..1852afcd1 100644
--- a/packages/app/src/i18n/bs.ts
+++ b/packages/app/src/i18n/bs.ts
@@ -639,6 +639,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Nijedan",
"sound.option.alert01": "Upozorenje 01",
"sound.option.alert02": "Upozorenje 02",
"sound.option.alert03": "Upozorenje 03",
diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts
index ce33ceec3..c5d2dc25f 100644
--- a/packages/app/src/i18n/da.ts
+++ b/packages/app/src/i18n/da.ts
@@ -635,6 +635,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Ingen",
"sound.option.alert01": "Alarm 01",
"sound.option.alert02": "Alarm 02",
"sound.option.alert03": "Alarm 03",
diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts
index cf3416be2..34a80ee4c 100644
--- a/packages/app/src/i18n/de.ts
+++ b/packages/app/src/i18n/de.ts
@@ -580,6 +580,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Keine",
"sound.option.alert01": "Alarm 01",
"sound.option.alert02": "Alarm 02",
"sound.option.alert03": "Alarm 03",
diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts
index a8c27cc63..7ba82066c 100644
--- a/packages/app/src/i18n/en.ts
+++ b/packages/app/src/i18n/en.ts
@@ -642,6 +642,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "None",
"sound.option.alert01": "Alert 01",
"sound.option.alert02": "Alert 02",
"sound.option.alert03": "Alert 03",
diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts
index d741bb138..28988bba1 100644
--- a/packages/app/src/i18n/es.ts
+++ b/packages/app/src/i18n/es.ts
@@ -643,6 +643,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Ninguno",
"sound.option.alert01": "Alerta 01",
"sound.option.alert02": "Alerta 02",
"sound.option.alert03": "Alerta 03",
diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts
index 686539df4..643c5e821 100644
--- a/packages/app/src/i18n/fr.ts
+++ b/packages/app/src/i18n/fr.ts
@@ -579,6 +579,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Aucun",
"sound.option.alert01": "Alerte 01",
"sound.option.alert02": "Alerte 02",
"sound.option.alert03": "Alerte 03",
diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts
index 288351c8b..5f6e92402 100644
--- a/packages/app/src/i18n/ja.ts
+++ b/packages/app/src/i18n/ja.ts
@@ -569,6 +569,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "なし",
"sound.option.alert01": "アラート 01",
"sound.option.alert02": "アラート 02",
"sound.option.alert03": "アラート 03",
diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts
index 72a46ca7e..d5a0b090b 100644
--- a/packages/app/src/i18n/ko.ts
+++ b/packages/app/src/i18n/ko.ts
@@ -570,6 +570,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "없음",
"sound.option.alert01": "알림 01",
"sound.option.alert02": "알림 02",
"sound.option.alert03": "알림 03",
diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts
index c099fe61f..10a8c1042 100644
--- a/packages/app/src/i18n/no.ts
+++ b/packages/app/src/i18n/no.ts
@@ -642,6 +642,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Ingen",
"sound.option.alert01": "Varsel 01",
"sound.option.alert02": "Varsel 02",
"sound.option.alert03": "Varsel 03",
diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts
index 67c9dda2a..9038fd1ad 100644
--- a/packages/app/src/i18n/pl.ts
+++ b/packages/app/src/i18n/pl.ts
@@ -570,6 +570,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Brak",
"sound.option.alert01": "Alert 01",
"sound.option.alert02": "Alert 02",
"sound.option.alert03": "Alert 03",
diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts
index 57ef82fd6..69fee5c89 100644
--- a/packages/app/src/i18n/ru.ts
+++ b/packages/app/src/i18n/ru.ts
@@ -640,6 +640,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "Нет",
"sound.option.alert01": "Alert 01",
"sound.option.alert02": "Alert 02",
"sound.option.alert03": "Alert 03",
diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts
index e67db0465..d66c8f607 100644
--- a/packages/app/src/i18n/th.ts
+++ b/packages/app/src/i18n/th.ts
@@ -634,6 +634,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "ไม่มี",
"sound.option.alert01": "เสียงเตือน 01",
"sound.option.alert02": "เสียงเตือน 02",
"sound.option.alert03": "เสียงเตือน 03",
diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts
index 42740fa77..46daeb701 100644
--- a/packages/app/src/i18n/zh.ts
+++ b/packages/app/src/i18n/zh.ts
@@ -633,6 +633,7 @@ export const dict = {
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "无",
"sound.option.alert01": "警报 01",
"sound.option.alert02": "警报 02",
"sound.option.alert03": "警报 03",
diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts
index f47fdede8..bbb00727b 100644
--- a/packages/app/src/i18n/zht.ts
+++ b/packages/app/src/i18n/zht.ts
@@ -629,6 +629,7 @@ export const dict = {
"font.option.sourceCodePro": "Source Code Pro",
"font.option.ubuntuMono": "Ubuntu Mono",
"font.option.geistMono": "Geist Mono",
+ "sound.option.none": "無",
"sound.option.alert01": "警報 01",
"sound.option.alert02": "警報 02",
"sound.option.alert03": "警報 03",