diff --git a/modules/UI/side_pannels/chat/Chat.js b/modules/UI/side_pannels/chat/Chat.js index f68f82f19..e335771ee 100644 --- a/modules/UI/side_pannels/chat/Chat.js +++ b/modules/UI/side_pannels/chat/Chat.js @@ -25,8 +25,6 @@ const htmlStr = `
-
@@ -285,7 +283,6 @@ const Chat = { if (!Chat.isVisible()) { unreadMessages++; - UIUtil.playSoundNotification('chatNotification'); updateVisualNotification(); } } diff --git a/modules/UI/util/UIUtil.js b/modules/UI/util/UIUtil.js index edb2567ce..d6cf7412f 100644 --- a/modules/UI/util/UIUtil.js +++ b/modules/UI/util/UIUtil.js @@ -66,15 +66,6 @@ const UIUtil = { return el.clientHeight + 1; }, - /** - * Plays the sound given by id. - * - * @param id the identifier of the audio element. - */ - playSoundNotification(id) { - document.getElementById(id).play(); - }, - /** * Escapes the given text. */ diff --git a/react/features/app/components/App.web.js b/react/features/app/components/App.web.js index 615564cb2..aaa8c18ef 100644 --- a/react/features/app/components/App.web.js +++ b/react/features/app/components/App.web.js @@ -3,6 +3,7 @@ import React from 'react'; import '../../base/responsive-ui'; import { getLocationContextRoot } from '../../base/util'; +import '../../chat'; import '../../room-lock'; import { AbstractApp } from './AbstractApp'; diff --git a/react/features/chat/constants.js b/react/features/chat/constants.js new file mode 100644 index 000000000..699a4a61f --- /dev/null +++ b/react/features/chat/constants.js @@ -0,0 +1,9 @@ +/* eslint-disable no-unused-vars */ +import { playAudio } from '../base/media'; + +/** + * The audio ID of the audio element for which the {@link playAudio} action is + * triggered when new chat message is received. + * @type {string} + */ +export const INCOMING_MSG_SOUND_ID = 'INCOMING_MSG_SOUND'; diff --git a/react/features/chat/index.js b/react/features/chat/index.js new file mode 100644 index 000000000..5d43fae60 --- /dev/null +++ b/react/features/chat/index.js @@ -0,0 +1,3 @@ +export * from './constants'; + +import './middleware'; diff --git a/react/features/chat/middleware.js b/react/features/chat/middleware.js new file mode 100644 index 000000000..f8b0440b6 --- /dev/null +++ b/react/features/chat/middleware.js @@ -0,0 +1,66 @@ +// @flow + +import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app'; +import { CONFERENCE_JOINED } from '../base/conference'; +import { JitsiConferenceEvents } from '../base/lib-jitsi-meet'; +import { MiddlewareRegistry } from '../base/redux'; +import { playSound, registerSound, unregisterSound } from '../base/sounds'; + +import { INCOMING_MSG_SOUND_ID } from './constants'; +import { INCOMING_MSG_SOUND_SRC } from './sounds'; + +declare var APP: Object; + +/** + * Implements the middleware of the chat feature. + * + * @param {Store} store - The redux store. + * @returns {Function} + */ +MiddlewareRegistry.register(store => next => action => { + switch (action.type) { + case APP_WILL_MOUNT: { + // Register chat msg sound only on web + typeof APP !== 'undefined' + && store.dispatch( + registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_SRC)); + break; + } + case APP_WILL_UNMOUNT: { + // Register chat msg sound only on web + typeof APP !== 'undefined' + && store.dispatch(unregisterSound(INCOMING_MSG_SOUND_ID)); + break; + } + case CONFERENCE_JOINED: + typeof APP !== 'undefined' + && _addChatMsgListener(action.conference, store); + break; + } + + return next(action); +}); + +/** + * Registers listener for {@link JitsiConferenceEvents.MESSAGE_RECEIVED} which + * will play a sound on the event, given that the chat is not currently visible. + * + * @param {JitsiConference} conference - The conference instance on which the + * new event listener will be registered. + * @param {Dispatch} next - The redux dispatch function to dispatch the + * specified action to the specified store. + * @returns {void} + * @private + */ +function _addChatMsgListener(conference, { dispatch }) { + // XXX Currently there's no need to remove the listener, because + // conference instance can not be re-used. Listener will be gone with + // the conference instance. + conference.on( + JitsiConferenceEvents.MESSAGE_RECEIVED, + () => { + if (!APP.UI.isChatVisible()) { + dispatch(playSound(INCOMING_MSG_SOUND_ID)); + } + }); +} diff --git a/react/features/chat/sounds.web.js b/react/features/chat/sounds.web.js new file mode 100644 index 000000000..980276081 --- /dev/null +++ b/react/features/chat/sounds.web.js @@ -0,0 +1,5 @@ +/** + * The audio source for the incoming chat message sound. + * @type {string} + */ +export const INCOMING_MSG_SOUND_SRC = 'sounds/incomingMessage.wav';