feat(app): option to turn off sound effects
This commit is contained in:
@@ -10,8 +10,11 @@ export const settingsNotificationsAgentSelector = '[data-action="settings-notifi
|
|||||||
export const settingsNotificationsPermissionsSelector = '[data-action="settings-notifications-permissions"]'
|
export const settingsNotificationsPermissionsSelector = '[data-action="settings-notifications-permissions"]'
|
||||||
export const settingsNotificationsErrorsSelector = '[data-action="settings-notifications-errors"]'
|
export const settingsNotificationsErrorsSelector = '[data-action="settings-notifications-errors"]'
|
||||||
export const settingsSoundsAgentSelector = '[data-action="settings-sounds-agent"]'
|
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 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 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 settingsUpdatesStartupSelector = '[data-action="settings-updates-startup"]'
|
||||||
export const settingsReleaseNotesSelector = '[data-action="settings-release-notes"]'
|
export const settingsReleaseNotesSelector = '[data-action="settings-release-notes"]'
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
settingsNotificationsPermissionsSelector,
|
settingsNotificationsPermissionsSelector,
|
||||||
settingsReleaseNotesSelector,
|
settingsReleaseNotesSelector,
|
||||||
settingsSoundsAgentSelector,
|
settingsSoundsAgentSelector,
|
||||||
|
settingsSoundsAgentEnabledSelector,
|
||||||
settingsSoundsErrorsSelector,
|
settingsSoundsErrorsSelector,
|
||||||
settingsSoundsPermissionsSelector,
|
settingsSoundsPermissionsSelector,
|
||||||
settingsThemeSelector,
|
settingsThemeSelector,
|
||||||
@@ -335,6 +336,30 @@ test("changing sound agent selection persists in localStorage", async ({ page, g
|
|||||||
expect(stored?.sounds?.agent).not.toBe("staplebops-01")
|
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 }) => {
|
test("changing permissions and errors sounds updates localStorage", async ({ page, gotoSession }) => {
|
||||||
await gotoSession()
|
await gotoSession()
|
||||||
|
|
||||||
|
|||||||
@@ -306,39 +306,66 @@ export const SettingsGeneral: Component = () => {
|
|||||||
title={language.t("settings.general.sounds.agent.title")}
|
title={language.t("settings.general.sounds.agent.title")}
|
||||||
description={language.t("settings.general.sounds.agent.description")}
|
description={language.t("settings.general.sounds.agent.description")}
|
||||||
>
|
>
|
||||||
<Select
|
<div class="flex items-center gap-2">
|
||||||
data-action="settings-sounds-agent"
|
<div data-action="settings-sounds-agent-enabled">
|
||||||
{...soundSelectProps(
|
<Switch
|
||||||
() => settings.sounds.agent(),
|
checked={settings.sounds.agentEnabled()}
|
||||||
(id) => settings.sounds.setAgent(id),
|
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>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
|
|
||||||
<SettingsRow
|
<SettingsRow
|
||||||
title={language.t("settings.general.sounds.permissions.title")}
|
title={language.t("settings.general.sounds.permissions.title")}
|
||||||
description={language.t("settings.general.sounds.permissions.description")}
|
description={language.t("settings.general.sounds.permissions.description")}
|
||||||
>
|
>
|
||||||
<Select
|
<div class="flex items-center gap-2">
|
||||||
data-action="settings-sounds-permissions"
|
<div data-action="settings-sounds-permissions-enabled">
|
||||||
{...soundSelectProps(
|
<Switch
|
||||||
() => settings.sounds.permissions(),
|
checked={settings.sounds.permissionsEnabled()}
|
||||||
(id) => settings.sounds.setPermissions(id),
|
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>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
|
|
||||||
<SettingsRow
|
<SettingsRow
|
||||||
title={language.t("settings.general.sounds.errors.title")}
|
title={language.t("settings.general.sounds.errors.title")}
|
||||||
description={language.t("settings.general.sounds.errors.description")}
|
description={language.t("settings.general.sounds.errors.description")}
|
||||||
>
|
>
|
||||||
<Select
|
<div class="flex items-center gap-2">
|
||||||
data-action="settings-sounds-errors"
|
<div data-action="settings-sounds-errors-enabled">
|
||||||
{...soundSelectProps(
|
<Switch
|
||||||
() => settings.sounds.errors(),
|
checked={settings.sounds.errorsEnabled()}
|
||||||
(id) => settings.sounds.setErrors(id),
|
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>
|
||||||
</SettingsRow>
|
</SettingsRow>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -233,7 +233,9 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
|
|||||||
if (!session) return
|
if (!session) return
|
||||||
if (session.parentID) return
|
if (session.parentID) return
|
||||||
|
|
||||||
playSound(soundSrc(settings.sounds.agent()))
|
if (settings.sounds.agentEnabled()) {
|
||||||
|
playSound(soundSrc(settings.sounds.agent()))
|
||||||
|
}
|
||||||
|
|
||||||
append({
|
append({
|
||||||
directory,
|
directory,
|
||||||
@@ -260,7 +262,9 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
|
|||||||
if (meta.disposed) return
|
if (meta.disposed) return
|
||||||
if (session?.parentID) 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
|
const error = "error" in event.properties ? event.properties.error : undefined
|
||||||
append({
|
append({
|
||||||
|
|||||||
@@ -10,8 +10,11 @@ export interface NotificationSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SoundSettings {
|
export interface SoundSettings {
|
||||||
|
agentEnabled: boolean
|
||||||
agent: string
|
agent: string
|
||||||
|
permissionsEnabled: boolean
|
||||||
permissions: string
|
permissions: string
|
||||||
|
errorsEnabled: boolean
|
||||||
errors: string
|
errors: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,8 +60,11 @@ const defaultSettings: Settings = {
|
|||||||
errors: false,
|
errors: false,
|
||||||
},
|
},
|
||||||
sounds: {
|
sounds: {
|
||||||
|
agentEnabled: true,
|
||||||
agent: "staplebops-01",
|
agent: "staplebops-01",
|
||||||
|
permissionsEnabled: true,
|
||||||
permissions: "staplebops-02",
|
permissions: "staplebops-02",
|
||||||
|
errorsEnabled: true,
|
||||||
errors: "nope-03",
|
errors: "nope-03",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -168,14 +174,29 @@ export const { use: useSettings, provider: SettingsProvider } = createSimpleCont
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
sounds: {
|
sounds: {
|
||||||
|
agentEnabled: withFallback(() => store.sounds?.agentEnabled, defaultSettings.sounds.agentEnabled),
|
||||||
|
setAgentEnabled(value: boolean) {
|
||||||
|
setStore("sounds", "agentEnabled", value)
|
||||||
|
},
|
||||||
agent: withFallback(() => store.sounds?.agent, defaultSettings.sounds.agent),
|
agent: withFallback(() => store.sounds?.agent, defaultSettings.sounds.agent),
|
||||||
setAgent(value: string) {
|
setAgent(value: string) {
|
||||||
setStore("sounds", "agent", value)
|
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),
|
permissions: withFallback(() => store.sounds?.permissions, defaultSettings.sounds.permissions),
|
||||||
setPermissions(value: string) {
|
setPermissions(value: string) {
|
||||||
setStore("sounds", "permissions", value)
|
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),
|
errors: withFallback(() => store.sounds?.errors, defaultSettings.sounds.errors),
|
||||||
setErrors(value: string) {
|
setErrors(value: string) {
|
||||||
setStore("sounds", "errors", value)
|
setStore("sounds", "errors", value)
|
||||||
|
|||||||
@@ -388,7 +388,9 @@ export default function Layout(props: ParentProps) {
|
|||||||
alertedAtBySession.set(sessionKey, now)
|
alertedAtBySession.set(sessionKey, now)
|
||||||
|
|
||||||
if (e.details.type === "permission.asked") {
|
if (e.details.type === "permission.asked") {
|
||||||
playSound(soundSrc(settings.sounds.permissions()))
|
if (settings.sounds.permissionsEnabled()) {
|
||||||
|
playSound(soundSrc(settings.sounds.permissions()))
|
||||||
|
}
|
||||||
if (settings.notifications.permissions()) {
|
if (settings.notifications.permissions()) {
|
||||||
void platform.notify(title, description, href)
|
void platform.notify(title, description, href)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user