Add sound effect for notifications in Linux

This commit is contained in:
Evan Hahn 2020-09-11 16:23:11 -05:00 committed by Josh Perez
parent 6d2e994f9f
commit de66486e41
7 changed files with 146 additions and 234 deletions

View file

@ -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,

BIN
sounds/notification.ogg Executable file

Binary file not shown.

View file

@ -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,
};
};

View file

@ -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;
}

View file

@ -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'

View file

@ -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());
});
});
});

View file

@ -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