diff --git a/src/assets/sounds/bing.mp3 b/src/assets/sounds/bing.mp3 new file mode 100644 index 00000000..2827addd Binary files /dev/null and b/src/assets/sounds/bing.mp3 differ diff --git a/src/assets/sounds/crackle.mp3 b/src/assets/sounds/crackle.mp3 new file mode 100644 index 00000000..90025f2e Binary files /dev/null and b/src/assets/sounds/crackle.mp3 differ diff --git a/src/assets/ding.mp3 b/src/assets/sounds/ding.mp3 similarity index 100% rename from src/assets/ding.mp3 rename to src/assets/sounds/ding.mp3 diff --git a/src/assets/sounds/down.mp3 b/src/assets/sounds/down.mp3 new file mode 100644 index 00000000..71f754cc Binary files /dev/null and b/src/assets/sounds/down.mp3 differ diff --git a/src/assets/sounds/hello.mp3 b/src/assets/sounds/hello.mp3 new file mode 100644 index 00000000..4e013bd6 Binary files /dev/null and b/src/assets/sounds/hello.mp3 differ diff --git a/src/assets/sounds/ripple.mp3 b/src/assets/sounds/ripple.mp3 new file mode 100644 index 00000000..49102a3e Binary files /dev/null and b/src/assets/sounds/ripple.mp3 differ diff --git a/src/assets/sounds/upstairs.mp3 b/src/assets/sounds/upstairs.mp3 new file mode 100644 index 00000000..2e4366b8 Binary files /dev/null and b/src/assets/sounds/upstairs.mp3 differ diff --git a/src/browser/components/MattermostView.jsx b/src/browser/components/MattermostView.jsx index f756cb1c..bf8f7935 100644 --- a/src/browser/components/MattermostView.jsx +++ b/src/browser/components/MattermostView.jsx @@ -161,8 +161,8 @@ export default class MattermostView extends React.Component { break; } case 'dispatchNotification': { - const [title, body, channel, teamId, silent] = event.args; - Utils.dispatchNotification(title, body, silent, () => this.webviewRef.current.send('notification-clicked', {channel, teamId})); + const [title, body, channel, teamId, silent, data] = event.args; + Utils.dispatchNotification(title, body, silent, data, () => this.webviewRef.current.send('notification-clicked', {channel, teamId})); break; } case 'onNotificationClick': diff --git a/src/browser/js/notification.js b/src/browser/js/notification.js index a8ba3030..ce503e22 100644 --- a/src/browser/js/notification.js +++ b/src/browser/js/notification.js @@ -5,17 +5,34 @@ const OriginalNotification = Notification; import {throttle} from 'underscore'; - import {ipcRenderer, remote} from 'electron'; import osVersion from '../../common/osVersion'; -import dingDataURL from '../../assets/ding.mp3'; // https://github.com/mattermost/platform/blob/v3.7.3/webapp/images/ding.mp3 + +import ding from '../../assets/sounds/ding.mp3'; +import bing from '../../assets/sounds/bing.mp3'; +import crackle from '../../assets/sounds/crackle.mp3'; +import down from '../../assets/sounds/down.mp3'; +import hello from '../../assets/sounds/hello.mp3'; +import ripple from '../../assets/sounds/ripple.mp3'; +import upstairs from '../../assets/sounds/upstairs.mp3'; + +const DEFAULT_WIN7 = 'Ding'; +const notificationSounds = new Map([ + [DEFAULT_WIN7, ding], + ['Bing', bing], + ['Crackle', crackle], + ['Down', down], + ['Hello', hello], + ['Ripple', ripple], + ['Upstairs', upstairs], +]); const appIconURL = `file:///${remote.app.getAppPath()}/assets/appicon_48.png`; -const playDing = throttle(() => { - const ding = new Audio(dingDataURL); - ding.play(); +const playSound = throttle((soundName) => { + const audio = new Audio(notificationSounds.get(soundName)); + audio.play(); }, 3000, {trailing: false}); export default class EnhancedNotification extends OriginalNotification { @@ -28,6 +45,13 @@ export default class EnhancedNotification extends OriginalNotification { Reflect.deleteProperty(options, 'icon'); } + const isWin7 = (process.platform === 'win32' && osVersion.isLowerThanOrEqualWindows8_1() && DEFAULT_WIN7); + const customSound = !options.silent && ((options.data.soundName !== 'None' && options.data.soundName) || isWin7); + if (customSound) { + // disable native sound + options.silent = true; + } + super(title, options); ipcRenderer.send('notified', { @@ -35,10 +59,8 @@ export default class EnhancedNotification extends OriginalNotification { options, }); - if (process.platform === 'win32' && osVersion.isLowerThanOrEqualWindows8_1()) { - if (!options.silent) { - playDing(); - } + if (customSound) { + playSound(customSound); } } diff --git a/src/browser/webview/mattermost.js b/src/browser/webview/mattermost.js index 19d824bb..5b68f365 100644 --- a/src/browser/webview/mattermost.js +++ b/src/browser/webview/mattermost.js @@ -76,8 +76,8 @@ window.addEventListener('message', ({origin, data: {type, message = {}} = {}} = break; } case 'dispatch-notification': { - const {title, body, channel, teamId, silent} = message; - ipcRenderer.sendToHost('dispatchNotification', title, body, channel, teamId, silent, () => handleNotificationClick({teamId, channel})); + const {title, body, channel, teamId, silent, data} = message; + ipcRenderer.sendToHost('dispatchNotification', title, body, channel, teamId, silent, data, () => handleNotificationClick({teamId, channel})); break; } } diff --git a/src/utils/util.js b/src/utils/util.js index b34aa35a..42fd53f8 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -185,7 +185,7 @@ function equalUrlsIgnoringSubpath(url1, url2) { return url1.origin.toLowerCase() === url2.origin.toLowerCase(); } -const dispatchNotification = async (title, body, silent, handleClick) => { +const dispatchNotification = async (title, body, silent, data, handleClick) => { let permission; const appIconURL = `file:///${remote.app.getAppPath()}/assets/appicon_48.png`; if (Notification.permission === 'default') { @@ -204,7 +204,8 @@ const dispatchNotification = async (title, body, silent, handleClick) => { tag: body, icon: appIconURL, requireInteraction: false, - silent + silent, + data, }); notification.onclick = handleClick;