fix(desktop): restore notification sounds (#2582)
Restore desktop notification sounds by default, add a persisted Play sound setting, and group notification permission and testing in a dedicated Notifications section.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import path from "node:path";
|
||||
import { existsSync } from "node:fs";
|
||||
import { app, BrowserWindow, Notification, ipcMain, nativeImage } from "electron";
|
||||
import { getDesktopSettingsStore } from "../settings/desktop-settings-electron.js";
|
||||
|
||||
interface NotificationInput {
|
||||
title?: unknown;
|
||||
@@ -95,11 +96,12 @@ export function registerNotificationHandlers(): void {
|
||||
const body = toTrimmedString(rawInput?.body) ?? undefined;
|
||||
const data = toRecord(rawInput?.data);
|
||||
const icon = getNotificationIcon();
|
||||
const settings = await getDesktopSettingsStore().get();
|
||||
const notification = new Notification({
|
||||
title,
|
||||
...(body ? { body } : {}),
|
||||
...(icon ? { icon } : {}),
|
||||
silent: true,
|
||||
silent: !settings.notifications.playSound,
|
||||
});
|
||||
|
||||
activeNotifications.add(notification);
|
||||
|
||||
@@ -81,6 +81,7 @@ describe("desktop-settings", () => {
|
||||
|
||||
expect(settings).toEqual({
|
||||
releaseChannel: "stable",
|
||||
notifications: { playSound: true },
|
||||
daemon: {
|
||||
manageBuiltInDaemon: true,
|
||||
keepRunningAfterQuit: false,
|
||||
@@ -102,6 +103,7 @@ describe("desktop-settings", () => {
|
||||
|
||||
expect(next).toEqual({
|
||||
releaseChannel: "beta",
|
||||
notifications: { playSound: true },
|
||||
daemon: {
|
||||
manageBuiltInDaemon: true,
|
||||
keepRunningAfterQuit: false,
|
||||
@@ -110,6 +112,45 @@ describe("desktop-settings", () => {
|
||||
expect(files).toEqual(["desktop-settings.json"]);
|
||||
});
|
||||
|
||||
it("defaults notification sounds on for existing settings documents", async () => {
|
||||
const userDataPath = await createTempUserDataDir();
|
||||
directories.add(userDataPath);
|
||||
await writeFile(
|
||||
settingsFilePath(userDataPath),
|
||||
JSON.stringify({
|
||||
version: 1,
|
||||
settings: {
|
||||
releaseChannel: "stable",
|
||||
daemon: {
|
||||
manageBuiltInDaemon: true,
|
||||
keepRunningAfterQuit: false,
|
||||
},
|
||||
},
|
||||
migrations: {
|
||||
legacyRendererSettingsImported: true,
|
||||
daemonStopOnQuitDefaultApplied: true,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const settings = await createDesktopSettingsStore({ userDataPath }).get();
|
||||
|
||||
expect(settings.notifications.playSound).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps an explicit notification sound choice across restarts", async () => {
|
||||
const userDataPath = await createTempUserDataDir();
|
||||
directories.add(userDataPath);
|
||||
|
||||
await createDesktopSettingsStore({ userDataPath }).patch({
|
||||
notifications: { playSound: false },
|
||||
});
|
||||
|
||||
const settings = await createDesktopSettingsStore({ userDataPath }).get();
|
||||
|
||||
expect(settings.notifications.playSound).toBe(false);
|
||||
});
|
||||
|
||||
it("does not let stale legacy renderer settings override an explicit desktop patch", async () => {
|
||||
const userDataPath = await createTempUserDataDir();
|
||||
directories.add(userDataPath);
|
||||
@@ -229,6 +270,7 @@ describe("desktop-settings", () => {
|
||||
|
||||
expect(migrated).toEqual({
|
||||
releaseChannel: "beta",
|
||||
notifications: { playSound: true },
|
||||
daemon: {
|
||||
manageBuiltInDaemon: false,
|
||||
keepRunningAfterQuit: false,
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { AppReleaseChannel } from "../features/auto-updater.js";
|
||||
|
||||
export interface DesktopSettings {
|
||||
releaseChannel: AppReleaseChannel;
|
||||
notifications: {
|
||||
playSound: boolean;
|
||||
};
|
||||
daemon: {
|
||||
manageBuiltInDaemon: boolean;
|
||||
keepRunningAfterQuit: boolean;
|
||||
@@ -14,6 +17,7 @@ export interface DesktopSettings {
|
||||
|
||||
interface DesktopSettingsPatch {
|
||||
releaseChannel?: AppReleaseChannel;
|
||||
notifications?: Partial<DesktopSettings["notifications"]>;
|
||||
daemon?: Partial<DesktopSettings["daemon"]>;
|
||||
}
|
||||
|
||||
@@ -38,6 +42,9 @@ export interface DesktopSettingsStore {
|
||||
|
||||
export const DEFAULT_DESKTOP_SETTINGS: DesktopSettings = {
|
||||
releaseChannel: "stable",
|
||||
notifications: {
|
||||
playSound: true,
|
||||
},
|
||||
daemon: {
|
||||
manageBuiltInDaemon: true,
|
||||
keepRunningAfterQuit: false,
|
||||
@@ -73,6 +80,7 @@ function buildDefaultDocument(): PersistedDesktopSettingsDocument {
|
||||
version: 1,
|
||||
settings: {
|
||||
releaseChannel: DEFAULT_DESKTOP_SETTINGS.releaseChannel,
|
||||
notifications: { ...DEFAULT_DESKTOP_SETTINGS.notifications },
|
||||
daemon: { ...DEFAULT_DESKTOP_SETTINGS.daemon },
|
||||
},
|
||||
migrations: {
|
||||
@@ -85,6 +93,7 @@ function buildDefaultDocument(): PersistedDesktopSettingsDocument {
|
||||
function coerceDesktopSettings(input: unknown): DesktopSettings {
|
||||
const result: DesktopSettings = {
|
||||
releaseChannel: DEFAULT_DESKTOP_SETTINGS.releaseChannel,
|
||||
notifications: { ...DEFAULT_DESKTOP_SETTINGS.notifications },
|
||||
daemon: { ...DEFAULT_DESKTOP_SETTINGS.daemon },
|
||||
};
|
||||
|
||||
@@ -97,6 +106,13 @@ function coerceDesktopSettings(input: unknown): DesktopSettings {
|
||||
result.releaseChannel = releaseChannel;
|
||||
}
|
||||
|
||||
if (isRecord(input.notifications)) {
|
||||
const playSound = coerceBoolean(input.notifications.playSound);
|
||||
if (playSound !== null) {
|
||||
result.notifications.playSound = playSound;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRecord(input.daemon)) {
|
||||
const manageBuiltInDaemon = coerceBoolean(input.daemon.manageBuiltInDaemon);
|
||||
if (manageBuiltInDaemon !== null) {
|
||||
@@ -124,6 +140,13 @@ function coerceDesktopSettingsPatch(input: unknown): DesktopSettingsPatch {
|
||||
patch.releaseChannel = releaseChannel;
|
||||
}
|
||||
|
||||
if (isRecord(input.notifications)) {
|
||||
const playSound = coerceBoolean(input.notifications.playSound);
|
||||
if (playSound !== null) {
|
||||
patch.notifications = { playSound };
|
||||
}
|
||||
}
|
||||
|
||||
if (isRecord(input.daemon)) {
|
||||
const daemonPatch: Partial<DesktopSettings["daemon"]> = {};
|
||||
const manageBuiltInDaemon = coerceBoolean(input.daemon.manageBuiltInDaemon);
|
||||
@@ -169,6 +192,7 @@ function mergeDesktopSettings(
|
||||
): DesktopSettings {
|
||||
return {
|
||||
releaseChannel: patch.releaseChannel ?? current.releaseChannel,
|
||||
notifications: { ...current.notifications, ...patch.notifications },
|
||||
daemon: { ...current.daemon, ...patch.daemon },
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user