From de66486e41cf647743154e8e45e36fe9fcf0f33b Mon Sep 17 00:00:00 2001 From: Evan Hahn <69474926+EvanHahn-Signal@users.noreply.github.com> Date: Fri, 11 Sep 2020 16:23:11 -0500 Subject: [PATCH] Add sound effect for notifications in Linux --- js/notifications.js | 4 - sounds/notification.ogg | Bin 0 -> 11295 bytes ts/notifications/getStatus.ts | 13 +- ts/services/notify.ts | 23 ++- ts/state/ducks/calling.ts | 1 - ts/test/types/Settings_test.ts | 320 +++++++++++---------------------- ts/types/Settings.ts | 19 +- 7 files changed, 146 insertions(+), 234 deletions(-) create mode 100755 sounds/notification.ogg diff --git a/js/notifications.js b/js/notifications.js index 1244feb84353..24997ea0ab71 100644 --- a/js/notifications.js +++ b/js/notifications.js @@ -10,7 +10,6 @@ // eslint-disable-next-line func-names (function() { window.Whisper = window.Whisper || {}; - const { Settings } = Signal.Types; // The keys and values don't match here. This is because the values correspond to old // setting names. In the future, we may wish to migrate these to match. @@ -76,13 +75,11 @@ const isAppFocused = window.isActive(); const isAudioNotificationEnabled = storage.get('audio-notification') || false; - const isAudioNotificationSupported = Settings.isAudioNotificationSupported(); const userSetting = this.getUserSetting(); const status = Signal.Notifications.getStatus({ isAppFocused, isAudioNotificationEnabled, - isAudioNotificationSupported, isEnabled, hasNotifications: Boolean(this.notificationData), userSetting, @@ -157,7 +154,6 @@ } this.lastNotification = window.Signal.Services.notify({ - platform: window.platform, title: notificationTitle, icon: notificationIconUrl, message: notificationMessage, diff --git a/sounds/notification.ogg b/sounds/notification.ogg new file mode 100755 index 0000000000000000000000000000000000000000..93b3a0144e69dc584f2e08e52e5547d6d9fa3f59 GIT binary patch literal 11295 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 Qi;41!p~6RfexMEh4-yrmW&i*H literal 0 HcmV?d00001 diff --git a/ts/notifications/getStatus.ts b/ts/notifications/getStatus.ts index 75faaefad881..2d83e54e7c5c 100644 --- a/ts/notifications/getStatus.ts +++ b/ts/notifications/getStatus.ts @@ -1,7 +1,6 @@ interface Environment { isAppFocused: boolean; isAudioNotificationEnabled: boolean; - isAudioNotificationSupported: boolean; isEnabled: boolean; hasNotifications: boolean; userSetting: UserSetting; @@ -26,7 +25,6 @@ type Type = export const getStatus = ({ isAppFocused, isAudioNotificationEnabled, - isAudioNotificationSupported, isEnabled, hasNotifications, userSetting, @@ -51,15 +49,10 @@ export const getStatus = ({ return 'ok'; })(); - const shouldPlayNotificationSound = - isAudioNotificationSupported && isAudioNotificationEnabled; - const shouldShowNotifications = type === 'ok'; - const shouldClearNotifications = type === 'appIsFocused'; - return { - shouldClearNotifications, - shouldPlayNotificationSound, - shouldShowNotifications, + shouldClearNotifications: type === 'appIsFocused', + shouldPlayNotificationSound: isAudioNotificationEnabled, + shouldShowNotifications: type === 'ok', type, }; }; diff --git a/ts/services/notify.ts b/ts/services/notify.ts index 2d490e2eddb6..974aa14ec0ab 100644 --- a/ts/services/notify.ts +++ b/ts/services/notify.ts @@ -1,3 +1,10 @@ +import { Sound } from '../util/Sound'; +import { + AudioNotificationSupport, + getAudioNotificationSupport, +} from '../types/Settings'; +import * as OS from '../OS'; + function filter(text: string) { return (text || '') .replace(/&/g, '&') @@ -8,7 +15,6 @@ function filter(text: string) { } type NotificationType = { - platform: string; icon: string; message: string; onNotificationClick: () => void; @@ -17,18 +23,27 @@ type NotificationType = { }; export function notify({ - platform, icon, message, onNotificationClick, silent, title, }: NotificationType): Notification { + const audioNotificationSupport = getAudioNotificationSupport(); + const notification = new window.Notification(title, { - body: platform === 'linux' ? filter(message) : message, + body: OS.isLinux() ? filter(message) : message, icon, - silent, + silent: + silent || audioNotificationSupport !== AudioNotificationSupport.Native, }); notification.onclick = onNotificationClick; + + if (!silent && audioNotificationSupport === AudioNotificationSupport.Custom) { + // We kick off the sound to be played. No neet to await it. + // tslint:disable-next-line no-floating-promises + new Sound({ src: 'sounds/notification.ogg' }).play(); + } + return notification; } diff --git a/ts/state/ducks/calling.ts b/ts/state/ducks/calling.ts index d0eb95de6f63..f1f45c8a09c0 100644 --- a/ts/state/ducks/calling.ts +++ b/ts/state/ducks/calling.ts @@ -277,7 +277,6 @@ async function showCallNotification(callDetails: CallDetailsType) { } const { title, isVideoCall } = callDetails; notify({ - platform: window.platform, title, icon: isVideoCall ? 'images/icons/v2/video-solid-24.svg' diff --git a/ts/test/types/Settings_test.ts b/ts/test/types/Settings_test.ts index 3772b5abb3a0..f5e684d5e917 100644 --- a/ts/test/types/Settings_test.ts +++ b/ts/test/types/Settings_test.ts @@ -5,251 +5,145 @@ import { assert } from 'chai'; import * as Settings from '../../../ts/types/Settings'; describe('Settings', () => { - const sandbox = Sinon.createSandbox(); + let sandbox: Sinon.SinonSandbox; + + beforeEach(() => { + sandbox = Sinon.createSandbox(); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('getAudioNotificationSupport', () => { + it('returns native support on macOS', () => { + sandbox.stub(process, 'platform').value('darwin'); + assert.strictEqual( + Settings.getAudioNotificationSupport(), + Settings.AudioNotificationSupport.Native + ); + }); + + it('returns no support on Windows 7', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('7.0.0'); + assert.strictEqual( + Settings.getAudioNotificationSupport(), + Settings.AudioNotificationSupport.None + ); + }); + + it('returns native support on Windows 8', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('8.0.0'); + assert.strictEqual( + Settings.getAudioNotificationSupport(), + Settings.AudioNotificationSupport.Native + ); + }); + + it('returns custom support on Linux', () => { + sandbox.stub(process, 'platform').value('linux'); + assert.strictEqual( + Settings.getAudioNotificationSupport(), + Settings.AudioNotificationSupport.Custom + ); + }); + }); describe('isAudioNotificationSupported', () => { - context('on macOS', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('darwin'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isAudioNotificationSupported()); - }); + it('returns true on macOS', () => { + sandbox.stub(process, 'platform').value('darwin'); + assert.isTrue(Settings.isAudioNotificationSupported()); }); - context('on Windows', () => { - context('version 7', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('7.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return false', () => { - assert.isFalse(Settings.isAudioNotificationSupported()); - }); - }); - - context('version 8+', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('8.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isAudioNotificationSupported()); - }); - }); + it('returns false on Windows 7', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('7.0.0'); + assert.isFalse(Settings.isAudioNotificationSupported()); }); - context('on Linux', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('linux'); - }); + it('returns true on Windows 8', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('8.0.0'); + assert.isTrue(Settings.isAudioNotificationSupported()); + }); - afterEach(() => { - sandbox.restore(); - }); - - it('should return false', () => { - assert.isFalse(Settings.isAudioNotificationSupported()); - }); + it('returns true on Linux', () => { + sandbox.stub(process, 'platform').value('linux'); + assert.isTrue(Settings.isAudioNotificationSupported()); }); }); describe('isNotificationGroupingSupported', () => { - context('on macOS', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('darwin'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isNotificationGroupingSupported()); - }); + it('returns true on macOS', () => { + sandbox.stub(process, 'platform').value('darwin'); + assert.isTrue(Settings.isNotificationGroupingSupported()); }); - context('on Windows', () => { - context('version 7', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('7.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return false', () => { - assert.isFalse(Settings.isNotificationGroupingSupported()); - }); - }); - - context('version 8+', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('8.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isNotificationGroupingSupported()); - }); - }); + it('returns true on Windows 7', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('7.0.0'); + assert.isFalse(Settings.isNotificationGroupingSupported()); }); - context('on Linux', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('linux'); - }); + it('returns true on Windows 8', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('8.0.0'); + assert.isTrue(Settings.isNotificationGroupingSupported()); + }); - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isNotificationGroupingSupported()); - }); + it('returns true on Linux', () => { + sandbox.stub(process, 'platform').value('linux'); + assert.isTrue(Settings.isNotificationGroupingSupported()); }); }); + describe('isHideMenuBarSupported', () => { - context('on macOS', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('darwin'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return false', () => { - assert.isFalse(Settings.isHideMenuBarSupported()); - }); + it('returns false on macOS', () => { + sandbox.stub(process, 'platform').value('darwin'); + assert.isFalse(Settings.isHideMenuBarSupported()); }); - context('on Windows', () => { - context('version 7', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('7.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isHideMenuBarSupported()); - }); - }); - - context('version 8+', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('8.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isHideMenuBarSupported()); - }); - }); + it('returns true on Windows 7', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('7.0.0'); + assert.isTrue(Settings.isHideMenuBarSupported()); }); - context('on Linux', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('linux'); - }); + it('returns true on Windows 8', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('8.0.0'); + assert.isTrue(Settings.isHideMenuBarSupported()); + }); - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isHideMenuBarSupported()); - }); + it('returns true on Linux', () => { + sandbox.stub(process, 'platform').value('linux'); + assert.isTrue(Settings.isHideMenuBarSupported()); }); }); + describe('isDrawAttentionSupported', () => { - context('on macOS', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('darwin'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return false', () => { - assert.isFalse(Settings.isDrawAttentionSupported()); - }); + it('returns false on macOS', () => { + sandbox.stub(process, 'platform').value('darwin'); + assert.isFalse(Settings.isDrawAttentionSupported()); }); - context('on Windows', () => { - context('version 7', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('7.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isDrawAttentionSupported()); - }); - }); - - context('version 8+', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('win32'); - sandbox.stub(os, 'release').returns('8.0.0'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isDrawAttentionSupported()); - }); - }); + it('returns true on Windows 7', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('7.0.0'); + assert.isTrue(Settings.isDrawAttentionSupported()); }); - context('on Linux', () => { - beforeEach(() => { - sandbox.stub(process, 'platform').value('linux'); - }); + it('returns true on Windows 8', () => { + sandbox.stub(process, 'platform').value('win32'); + sandbox.stub(os, 'release').returns('8.0.0'); + assert.isTrue(Settings.isDrawAttentionSupported()); + }); - afterEach(() => { - sandbox.restore(); - }); - - it('should return true', () => { - assert.isTrue(Settings.isDrawAttentionSupported()); - }); + it('returns true on Linux', () => { + sandbox.stub(process, 'platform').value('linux'); + assert.isTrue(Settings.isDrawAttentionSupported()); }); }); }); diff --git a/ts/types/Settings.ts b/ts/types/Settings.ts index 0d6ca05d9270..71a738e60553 100644 --- a/ts/types/Settings.ts +++ b/ts/types/Settings.ts @@ -2,8 +2,23 @@ import * as OS from '../OS'; const MIN_WINDOWS_VERSION = '8.0.0'; -export const isAudioNotificationSupported = () => - OS.isWindows(MIN_WINDOWS_VERSION) || OS.isMacOS(); +export enum AudioNotificationSupport { + None, + Native, + Custom, +} + +export function getAudioNotificationSupport(): AudioNotificationSupport { + if (OS.isWindows(MIN_WINDOWS_VERSION) || OS.isMacOS()) { + return AudioNotificationSupport.Native; + } else if (OS.isLinux()) { + return AudioNotificationSupport.Custom; + } + return AudioNotificationSupport.None; +} + +export const isAudioNotificationSupported = (): boolean => + getAudioNotificationSupport() !== AudioNotificationSupport.None; // Using `Notification::tag` has a bug on Windows 7: // https://github.com/electron/electron/issues/11189