diff --git a/lib/notification-sound.ts b/lib/notification-sound.ts index 36589e318..f3ab179ea 100644 --- a/lib/notification-sound.ts +++ b/lib/notification-sound.ts @@ -3,6 +3,8 @@ import { withBasePath } from '@/lib/browser-navigation'; export type NotificationSoundChoice = 'default' | 'cheerful' | 'involved' | 'swift' | 'relax'; +// 'default' is the beep. It was the default sound until Involved replaced +// it, and keeps its id so stored and synced choices still match. export const NOTIFICATION_SOUNDS: { id: NotificationSoundChoice; file?: string }[] = [ { id: 'default' }, { id: 'cheerful', file: '/notification/cheerful-527.mp3' }, @@ -53,7 +55,7 @@ function playFile(file: string) { export function playNotificationSound(sound?: NotificationSoundChoice) { try { - const choice = sound ?? 'default'; + const choice = sound ?? 'involved'; const entry = NOTIFICATION_SOUNDS.find((s) => s.id === choice); if (entry?.file) { diff --git a/locales/ar/common.json b/locales/ar/common.json index 96ad8aefc..abb0b3c3a 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "اختبار صوت الإشعار", "sounds": { - "default": "افتراضي (تنبيه)", + "default": "تنبيه", "cheerful": "مرح", "involved": "متفاعل", "swift": "إيماءة سريعة", diff --git a/locales/ca/common.json b/locales/ca/common.json index b61af665e..7a79939d2 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Prova el so de notificació", "sounds": { - "default": "Per defecte (bip)", + "default": "Bip", "cheerful": "Alegre", "involved": "Elaborat", "swift": "Gest ràpid", diff --git a/locales/cs/common.json b/locales/cs/common.json index a12b48d06..2bb0818cc 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Otestovat zvuk oznámení", "sounds": { - "default": "Výchozí (Pípnutí)", + "default": "Pípnutí", "cheerful": "Veselý", "involved": "Dynamický", "swift": "Rychlý", diff --git a/locales/da/common.json b/locales/da/common.json index d46d60f9e..dad06620e 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Test notifikationslyd", "sounds": { - "default": "Standard (Bip)", + "default": "Bip", "cheerful": "Glad", "involved": "Engageret", "swift": "Hurtig gestus", diff --git a/locales/de/common.json b/locales/de/common.json index 9a484997d..5f0adf407 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Benachrichtigungston testen", "sounds": { - "default": "Standard (Piepton)", + "default": "Piepton", "cheerful": "Fröhlich", "involved": "Aufwendig", "swift": "Schnelle Geste", diff --git a/locales/en/common.json b/locales/en/common.json index e30e2d5c8..243c1a1f8 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Test notification sound", "sounds": { - "default": "Default (Beep)", + "default": "Beep", "cheerful": "Cheerful", "involved": "Involved", "swift": "Swift Gesture", diff --git a/locales/es/common.json b/locales/es/common.json index b910bc0d2..ae9bda45e 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Probar sonido de notificación", "sounds": { - "default": "Predeterminado (Pitido)", + "default": "Pitido", "cheerful": "Alegre", "involved": "Elaborado", "swift": "Gesto rápido", diff --git a/locales/et/common.json b/locales/et/common.json index 4513dcc2d..1e4d42b81 100644 --- a/locales/et/common.json +++ b/locales/et/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Testi teavitusheli", "sounds": { - "default": "Vaikimisi (piiks)", + "default": "Piiks", "cheerful": "Rõõmus", "involved": "Elav", "swift": "Kiire liigutus", diff --git a/locales/fa/common.json b/locales/fa/common.json index 03c0d0667..65663686c 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "تست صدای اعلان", "sounds": { - "default": "پیش‌فرض (بیپ)", + "default": "بیپ", "cheerful": "شاد", "involved": "درگیر", "swift": "سریع", diff --git a/locales/fr/common.json b/locales/fr/common.json index 2f8d73ee6..514b20378 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Tester le son de notification", "sounds": { - "default": "Par défaut (Bip)", + "default": "Bip", "cheerful": "Joyeux", "involved": "Élaboré", "swift": "Geste rapide", diff --git a/locales/he/common.json b/locales/he/common.json index 0988e6910..a7baace39 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -1595,7 +1595,7 @@ "notifications": { "test_sound": "צליל הודעת בדיקה", "sounds": { - "default": "ברירת מחדל (ביפ)", + "default": "ביפ", "cheerful": "עליז", "involved": "מעורב", "swift": "מחווה מהירה", diff --git a/locales/hu/common.json b/locales/hu/common.json index 12db95bfd..d719d7f79 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Értesítési hang tesztelése", "sounds": { - "default": "Alapértelmezett (sípolás)", + "default": "Sípolás", "cheerful": "Vidám", "involved": "Lelkes", "swift": "Gyors mozdulat", diff --git a/locales/it/common.json b/locales/it/common.json index 446b82fe7..fd2423aa8 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Testa il suono di notifica", "sounds": { - "default": "Predefinito (Bip)", + "default": "Bip", "cheerful": "Allegro", "involved": "Elaborato", "swift": "Gesto veloce", diff --git a/locales/ja/common.json b/locales/ja/common.json index 637a4fcc2..e077191e5 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "通知音をテスト", "sounds": { - "default": "デフォルト(ビープ)", + "default": "ビープ", "cheerful": "チアフル", "involved": "インボルブド", "swift": "スウィフトジェスチャー", diff --git a/locales/ko/common.json b/locales/ko/common.json index d0cd27ff6..bf85cc43c 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "알림음 테스트", "sounds": { - "default": "기본 (비프음)", + "default": "비프음", "cheerful": "밝게", "involved": "경쾌하게", "swift": "빠르게", diff --git a/locales/lv/common.json b/locales/lv/common.json index b58366a1f..1d670880b 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Pārbaudīt paziņojuma skaņu", "sounds": { - "default": "Noklusējuma (Signāls)", + "default": "Signāls", "cheerful": "Priecīgs", "involved": "Iesaistošs", "swift": "Ātrs", diff --git a/locales/mn/common.json b/locales/mn/common.json index 9a8b94dc7..d9759deed 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Туршилтын мэдэгдлийн дуу", "sounds": { - "default": "Өгөгдмөл (Дохио)", + "default": "Дохио", "cheerful": "Хөгжилтэй", "involved": "Оролцсон", "swift": "Шуурхай зангаа", diff --git a/locales/nb/common.json b/locales/nb/common.json index 0df5cb3bd..2fafd10a2 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Test varslingslyden", "sounds": { - "default": "Standard (pip)", + "default": "Pip", "cheerful": "Munter", "involved": "Engasjert", "swift": "Rask", diff --git a/locales/nl/common.json b/locales/nl/common.json index 609f28101..27e3bfcee 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Meldingsgeluid testen", "sounds": { - "default": "Standaard (Pieptoon)", + "default": "Pieptoon", "cheerful": "Vrolijk", "involved": "Uitgebreid", "swift": "Snel gebaar", diff --git a/locales/pl/common.json b/locales/pl/common.json index 09942dce0..be06b4fda 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Przetestuj dźwięk powiadomienia", "sounds": { - "default": "Domyślny (Beep)", + "default": "Beep", "cheerful": "Pogodny", "involved": "Dynamiczny", "swift": "Szybki gest", diff --git a/locales/pt/common.json b/locales/pt/common.json index e160a52d4..596a7a982 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Testar som de notificação", "sounds": { - "default": "Padrão (Bipe)", + "default": "Bipe", "cheerful": "Alegre", "involved": "Elaborado", "swift": "Gesto rápido", diff --git a/locales/ro/common.json b/locales/ro/common.json index 1abc36a8e..b1d462048 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Testați sunetul de notificare", "sounds": { - "default": "Implicit (Bip)", + "default": "Bip", "cheerful": "Vesel", "involved": "Implicat", "swift": "Gest rapid", diff --git a/locales/ru/common.json b/locales/ru/common.json index cd07676b6..a5e3acf71 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Проверить звук уведомления", "sounds": { - "default": "По умолчанию (Сигнал)", + "default": "Сигнал", "cheerful": "Радостный", "involved": "Вовлечённый", "swift": "Быстрый жест", diff --git a/locales/sk/common.json b/locales/sk/common.json index 3bfd4da76..dcb14ff6a 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "Otestovať zvuk oznámenia", "sounds": { - "default": "Predvolený (Pípnutie)", + "default": "Pípnutie", "cheerful": "Veselý", "involved": "Dynamický", "swift": "Rýchly", diff --git a/locales/th/common.json b/locales/th/common.json index d70543745..881359531 100644 --- a/locales/th/common.json +++ b/locales/th/common.json @@ -4070,7 +4070,7 @@ "notifications": { "test_sound": "ทดสอบเสียงแจ้งเตือน", "sounds": { - "default": "ค่าเริ่มต้น (เสียงบี๊บ)", + "default": "เสียงบี๊บ", "cheerful": "ร่าเริง (Cheerful)", "involved": "กระตือรือร้น (Involved)", "swift": "รวดเร็ว (Swift Gesture)", diff --git a/locales/tr/common.json b/locales/tr/common.json index 752227bec..50e40029e 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Bildirim sesini test et", "sounds": { - "default": "Varsayılan (Bip)", + "default": "Bip", "cheerful": "Neşeli", "involved": "Odaklı", "swift": "Hızlı Jest", diff --git a/locales/uk/common.json b/locales/uk/common.json index cc6369150..25c7531de 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "Тестовий звук сповіщення", "sounds": { - "default": "За замовчуванням (звуковий сигнал)", + "default": "Звуковий сигнал", "cheerful": "Веселий", "involved": "Залучений", "swift": "Швидкий жест", diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index 9e1232a72..031e647f1 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -1633,7 +1633,7 @@ "notifications": { "test_sound": "測試通知聲音", "sounds": { - "default": "預設(蜂鳴聲)", + "default": "蜂鳴聲", "cheerful": "快樂", "involved": "沉浸", "swift": "輕快手勢", diff --git a/locales/zh/common.json b/locales/zh/common.json index 260c4c941..bc30a8250 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -1630,7 +1630,7 @@ "notifications": { "test_sound": "测试通知声音", "sounds": { - "default": "默认(蜂鸣声)", + "default": "蜂鸣声", "cheerful": "快乐", "involved": "沉浸", "swift": "轻快手势", diff --git a/stores/__tests__/settings-notification-sound.test.ts b/stores/__tests__/settings-notification-sound.test.ts new file mode 100644 index 000000000..7a65b43f3 --- /dev/null +++ b/stores/__tests__/settings-notification-sound.test.ts @@ -0,0 +1,50 @@ +import { beforeEach, describe, it, expect } from 'vitest'; +import { useSettingsStore, migrateSettings } from '../settings-store'; + +// The new mail sound defaults to Involved; 'default' is the beep, which was +// the default before. + +const migrate = (state: Record, version: number) => + migrateSettings(state, version) as unknown as Record; + +describe('notification sound default', () => { + beforeEach(() => { + useSettingsStore.getState().resetToDefaults(); + }); + + it('plays Involved on a fresh install', () => { + expect(useSettingsStore.getState().notificationSoundChoice).toBe('involved'); + }); + + it('moves a beep the user never picked to Involved', () => { + expect(migrate({ notificationSoundChoice: 'default', explicitSettings: [] }, 9).notificationSoundChoice).toBe('involved'); + }); + + it('keeps a beep the user picked', () => { + const out = migrate({ notificationSoundChoice: 'default', explicitSettings: ['notificationSoundChoice'] }, 9); + expect(out.notificationSoundChoice).toBe('default'); + }); + + it('keeps any other sound the user picked', () => { + expect(migrate({ notificationSoundChoice: 'relax', explicitSettings: [] }, 9).notificationSoundChoice).toBe('relax'); + }); + + it('does not take the beep from before explicitSettings existed as chosen', () => { + const out = migrate({ notificationSoundChoice: 'default' }, 7); + expect(out.notificationSoundChoice).toBe('involved'); + expect(out.explicitSettings).not.toContain('notificationSoundChoice'); + }); + + it('moves the beep along in a server copy or export from an older build', () => { + const store = useSettingsStore.getState(); + expect(store.importSettings(JSON.stringify({ notificationSoundChoice: 'default', explicitSettings: [] }))).toBe(true); + expect(useSettingsStore.getState().notificationSoundChoice).toBe('involved'); + + expect(store.importSettings(JSON.stringify({ notificationSoundChoice: 'default' }))).toBe(true); + expect(useSettingsStore.getState().notificationSoundChoice).toBe('involved'); + expect(useSettingsStore.getState().explicitSettings).not.toContain('notificationSoundChoice'); + + expect(store.importSettings(JSON.stringify({ notificationSoundChoice: 'default', explicitSettings: ['notificationSoundChoice'] }))).toBe(true); + expect(useSettingsStore.getState().notificationSoundChoice).toBe('default'); + }); +}); diff --git a/stores/settings-store.ts b/stores/settings-store.ts index 66dc7edcf..810d45a85 100644 --- a/stores/settings-store.ts +++ b/stores/settings-store.ts @@ -942,7 +942,7 @@ const DEFAULT_SETTINGS = { // Email Notifications emailNotificationsEnabled: true, emailNotificationSound: true, - notificationSoundChoice: 'default' as NotificationSoundChoice, + notificationSoundChoice: 'involved' as NotificationSoundChoice, pushNotifyInboxOnly: false, notificationMutes: EMPTY_NOTIFICATION_MUTES, pushRelayUrl: '', @@ -1495,6 +1495,7 @@ export const useSettingsStore = create()( settings.protocolOpenMode = settings.protocolMailtoOpenMode; } migrateAnimationsSetting(settings); + migrateNotificationSoundDefault(settings); // Apply settings, noting which keys were taken over for the // onSettingsImport hook. @@ -1896,7 +1897,7 @@ export const useSettingsStore = create()( }, { name: 'settings-storage', - version: 9, + version: 10, migrate: migrateSettings, onRehydrateStorage: () => { return (state) => { @@ -1994,6 +1995,9 @@ export function migrateSettings(persisted: unknown, version: number): SettingsSt if (version < 6 || !isPlainRecord(state.preferredIdentityIds)) { state.preferredIdentityIds = {}; } + // Before the v8 step: a beep from before explicitSettings existed was + // the default then, and must not be taken as chosen below. + migrateNotificationSoundDefault(state); // v8: admin policy defaults (#1248) skip settings the user chose. // Earlier builds did not record that, so a setting that differs from // the build default is taken as chosen. @@ -2020,6 +2024,18 @@ export function migrateAnimationsSetting(state: Record): void { } } +/** + * v10: the new mail sound defaults to Involved instead of the beep. A beep + * the user never picked was only the old default and moves to Involved; one + * they picked stays. Imports and server copies from older builds still + * carry the beep and go through this too. + */ +export function migrateNotificationSoundDefault(state: Record): void { + if (state.notificationSoundChoice !== 'default') return; + const chosen = Array.isArray(state.explicitSettings) && state.explicitSettings.includes('notificationSoundChoice'); + if (!chosen) state.notificationSoundChoice = 'involved'; +} + // Helper functions to apply settings to DOM /** The settings applyAccessibilityTo() writes onto . */