From dcaad41e694680817f69725a25fa9a6e4eb95c78 Mon Sep 17 00:00:00 2001 From: Tudor-Ovidiu Avram Date: Thu, 28 Jan 2021 11:39:17 +0200 Subject: [PATCH] feat(external_api) add event for chat updates (unread counter, open state) --- modules/API/API.js | 15 +++++++++++++++ modules/API/external/external_api.js | 7 +++++++ react/features/chat/middleware.js | 22 ++++++++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/modules/API/API.js b/modules/API/API.js index 34598183e..0e19c5031 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -556,6 +556,21 @@ class API { } } + /** + * Notify external application (if API is enabled) that the chat state has been updated. + * + * @param {number} unreadCount - The unread messages counter. + * @param {boolean} isOpen - True if the chat panel is open. + * @returns {void} + */ + notifyChatUpdated(unreadCount: number, isOpen: boolean) { + this._sendEvent({ + name: 'chat-updated', + unreadCount, + isOpen + }); + } + /** * Notify external application (if API is enabled) that message was sent. * diff --git a/modules/API/external/external_api.js b/modules/API/external/external_api.js index 991fd5805..846f6d9be 100644 --- a/modules/API/external/external_api.js +++ b/modules/API/external/external_api.js @@ -64,6 +64,7 @@ const events = { 'audio-availability-changed': 'audioAvailabilityChanged', 'audio-mute-status-changed': 'audioMuteStatusChanged', 'camera-error': 'cameraError', + 'chat-updated': 'chatUpdated', 'content-sharing-participants-changed': 'contentSharingParticipantsChanged', 'device-list-changed': 'deviceListChanged', 'display-name-change': 'displayNameChange', @@ -572,6 +573,12 @@ export default class JitsiMeetExternalAPI extends EventEmitter { * logLevel: the message log level * arguments: an array of strings that compose the actual log message * }} + * {@code chatUpdated} - receives event notifications about chat state being + * updated. The listener will receive object with the following structure: + * {{ + * 'unreadCount': unreadCounter, // the unread message(s) counter, + * 'isOpen': isOpen, // whether the chat panel is open or not + * }} * {@code incomingMessage} - receives event notifications about incoming * messages. The listener will receive object with the following structure: * {{ diff --git a/react/features/chat/middleware.js b/react/features/chat/middleware.js index 398a42d36..12bc4240f 100644 --- a/react/features/chat/middleware.js +++ b/react/features/chat/middleware.js @@ -20,7 +20,7 @@ import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux'; import { playSound, registerSound, unregisterSound } from '../base/sounds'; import { showToolbox } from '../toolbox/actions'; -import { SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes'; +import { ADD_MESSAGE, TOGGLE_CHAT, SEND_MESSAGE, SET_PRIVATE_MESSAGE_RECIPIENT } from './actionTypes'; import { addMessage, clearMessages, toggleChat } from './actions'; import { ChatPrivacyDialog } from './components'; import { @@ -30,6 +30,7 @@ import { MESSAGE_TYPE_LOCAL, MESSAGE_TYPE_REMOTE } from './constants'; +import { getUnreadCount } from './functions'; import { INCOMING_MSG_SOUND_FILE } from './sounds'; declare var APP: Object; @@ -50,9 +51,26 @@ const PRIVACY_NOTICE_TIMEOUT = 20 * 1000; * @returns {Function} */ MiddlewareRegistry.register(store => next => action => { - const { dispatch } = store; + const { dispatch, getState } = store; + let isOpen, unreadCount; switch (action.type) { + case ADD_MESSAGE: + unreadCount = action.hasRead ? 0 : getUnreadCount(getState()) + 1; + isOpen = getState()['features/chat'].isOpen; + + if (typeof APP !== 'undefined') { + APP.API.notifyChatUpdated(unreadCount, isOpen); + } + break; + case TOGGLE_CHAT: + unreadCount = 0; + isOpen = !getState()['features/chat'].isOpen; + + if (typeof APP !== 'undefined') { + APP.API.notifyChatUpdated(unreadCount, isOpen); + } + break; case APP_WILL_MOUNT: dispatch( registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));