From 4e0f509e7b7d84395a541bdfa658f6c98f588221 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 12 Feb 2026 15:03:02 -0600 Subject: [PATCH] feat(app): option to turn off sound effects --- packages/app/e2e/selectors.ts | 3 + packages/app/e2e/settings/settings.spec.ts | 25 +++++++ .../app/src/components/settings-general.tsx | 69 +++++++++++++------ packages/app/src/context/notification.tsx | 8 ++- packages/app/src/context/settings.tsx | 21 ++++++ packages/app/src/pages/layout.tsx | 4 +- 6 files changed, 106 insertions(+), 24 deletions(-) diff --git a/packages/app/e2e/selectors.ts b/packages/app/e2e/selectors.ts index 842433891..52c9007ea 100644 --- a/packages/app/e2e/selectors.ts +++ b/packages/app/e2e/selectors.ts @@ -10,8 +10,11 @@ export const settingsNotificationsAgentSelector = '[data-action="settings-notifi export const settingsNotificationsPermissionsSelector = '[data-action="settings-notifications-permissions"]' export const settingsNotificationsErrorsSelector = '[data-action="settings-notifications-errors"]' export const settingsSoundsAgentSelector = '[data-action="settings-sounds-agent"]' +export const settingsSoundsAgentEnabledSelector = '[data-action="settings-sounds-agent-enabled"]' export const settingsSoundsPermissionsSelector = '[data-action="settings-sounds-permissions"]' +export const settingsSoundsPermissionsEnabledSelector = '[data-action="settings-sounds-permissions-enabled"]' export const settingsSoundsErrorsSelector = '[data-action="settings-sounds-errors"]' +export const settingsSoundsErrorsEnabledSelector = '[data-action="settings-sounds-errors-enabled"]' export const settingsUpdatesStartupSelector = '[data-action="settings-updates-startup"]' export const settingsReleaseNotesSelector = '[data-action="settings-release-notes"]' diff --git a/packages/app/e2e/settings/settings.spec.ts b/packages/app/e2e/settings/settings.spec.ts index 42534968b..9fbcf79f5 100644 --- a/packages/app/e2e/settings/settings.spec.ts +++ b/packages/app/e2e/settings/settings.spec.ts @@ -9,6 +9,7 @@ import { settingsNotificationsPermissionsSelector, settingsReleaseNotesSelector, settingsSoundsAgentSelector, + settingsSoundsAgentEnabledSelector, settingsSoundsErrorsSelector, settingsSoundsPermissionsSelector, settingsThemeSelector, @@ -335,6 +336,30 @@ test("changing sound agent selection persists in localStorage", async ({ page, g expect(stored?.sounds?.agent).not.toBe("staplebops-01") }) +test("disabling agent sound disables sound selection", async ({ page, gotoSession }) => { + await gotoSession() + + const dialog = await openSettings(page) + const select = dialog.locator(settingsSoundsAgentSelector) + const switchContainer = dialog.locator(settingsSoundsAgentEnabledSelector) + const trigger = select.locator('[data-slot="select-select-trigger"]') + await expect(select).toBeVisible() + await expect(switchContainer).toBeVisible() + await expect(trigger).toBeEnabled() + + await switchContainer.locator('[data-slot="switch-control"]').click() + await page.waitForTimeout(100) + + await expect(trigger).toBeDisabled() + + const stored = await page.evaluate((key) => { + const raw = localStorage.getItem(key) + return raw ? JSON.parse(raw) : null + }, settingsKey) + + expect(stored?.sounds?.agentEnabled).toBe(false) +}) + test("changing permissions and errors sounds updates localStorage", async ({ page, gotoSession }) => { await gotoSession() diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx index c673cab80..439f542bb 100644 --- a/packages/app/src/components/settings-general.tsx +++ b/packages/app/src/components/settings-general.tsx @@ -306,39 +306,66 @@ export const SettingsGeneral: Component = () => { title={language.t("settings.general.sounds.agent.title")} description={language.t("settings.general.sounds.agent.description")} > - settings.sounds.agent(), + (id) => settings.sounds.setAgent(id), + )} + /> + - settings.sounds.permissions(), + (id) => settings.sounds.setPermissions(id), + )} + /> + - settings.sounds.errors(), + (id) => settings.sounds.setErrors(id), + )} + /> + diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index bf880d115..04bc2fdaa 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -233,7 +233,9 @@ export const { use: useNotification, provider: NotificationProvider } = createSi if (!session) return if (session.parentID) return - playSound(soundSrc(settings.sounds.agent())) + if (settings.sounds.agentEnabled()) { + playSound(soundSrc(settings.sounds.agent())) + } append({ directory, @@ -260,7 +262,9 @@ export const { use: useNotification, provider: NotificationProvider } = createSi if (meta.disposed) return if (session?.parentID) return - playSound(soundSrc(settings.sounds.errors())) + if (settings.sounds.errorsEnabled()) { + playSound(soundSrc(settings.sounds.errors())) + } const error = "error" in event.properties ? event.properties.error : undefined append({ diff --git a/packages/app/src/context/settings.tsx b/packages/app/src/context/settings.tsx index a8efb1eac..d72d4ceb1 100644 --- a/packages/app/src/context/settings.tsx +++ b/packages/app/src/context/settings.tsx @@ -10,8 +10,11 @@ export interface NotificationSettings { } export interface SoundSettings { + agentEnabled: boolean agent: string + permissionsEnabled: boolean permissions: string + errorsEnabled: boolean errors: string } @@ -57,8 +60,11 @@ const defaultSettings: Settings = { errors: false, }, sounds: { + agentEnabled: true, agent: "staplebops-01", + permissionsEnabled: true, permissions: "staplebops-02", + errorsEnabled: true, errors: "nope-03", }, } @@ -168,14 +174,29 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont }, }, sounds: { + agentEnabled: withFallback(() => store.sounds?.agentEnabled, defaultSettings.sounds.agentEnabled), + setAgentEnabled(value: boolean) { + setStore("sounds", "agentEnabled", value) + }, agent: withFallback(() => store.sounds?.agent, defaultSettings.sounds.agent), setAgent(value: string) { setStore("sounds", "agent", value) }, + permissionsEnabled: withFallback( + () => store.sounds?.permissionsEnabled, + defaultSettings.sounds.permissionsEnabled, + ), + setPermissionsEnabled(value: boolean) { + setStore("sounds", "permissionsEnabled", value) + }, permissions: withFallback(() => store.sounds?.permissions, defaultSettings.sounds.permissions), setPermissions(value: string) { setStore("sounds", "permissions", value) }, + errorsEnabled: withFallback(() => store.sounds?.errorsEnabled, defaultSettings.sounds.errorsEnabled), + setErrorsEnabled(value: boolean) { + setStore("sounds", "errorsEnabled", value) + }, errors: withFallback(() => store.sounds?.errors, defaultSettings.sounds.errors), setErrors(value: string) { setStore("sounds", "errors", value) diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 5f001177f..7eb064f42 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -388,7 +388,9 @@ export default function Layout(props: ParentProps) { alertedAtBySession.set(sessionKey, now) if (e.details.type === "permission.asked") { - playSound(soundSrc(settings.sounds.permissions())) + if (settings.sounds.permissionsEnabled()) { + playSound(soundSrc(settings.sounds.permissions())) + } if (settings.notifications.permissions()) { void platform.notify(title, description, href) }