123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- // @flow
-
- import UIUtil from '../../../modules/UI/util/UIUtil';
-
- import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
- import { CONFERENCE_JOINED, CONFERENCE_WILL_LEAVE } from '../base/conference';
- import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
- import { getParticipantById } from '../base/participants';
- import { MiddlewareRegistry } from '../base/redux';
- import { playSound, registerSound, unregisterSound } from '../base/sounds';
- import { isButtonEnabled, showToolbox } from '../toolbox';
-
- import { SEND_MESSAGE } from './actionTypes';
- import { addMessage, clearMessages } from './actions';
- import { INCOMING_MSG_SOUND_ID } from './constants';
- import { INCOMING_MSG_SOUND_FILE } from './sounds';
-
- declare var APP: Object;
- declare var interfaceConfig : 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 the chat message sound on Web only because there's no chat
- // on mobile.
- typeof APP === 'undefined'
- || store.dispatch(
- registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
- break;
-
- case APP_WILL_UNMOUNT:
- // Unregister the chat message sound on Web because it's registered
- // there only.
- typeof APP === 'undefined'
- || store.dispatch(unregisterSound(INCOMING_MSG_SOUND_ID));
- break;
-
- case CONFERENCE_JOINED:
- typeof APP === 'undefined'
- || _addChatMsgListener(action.conference, store);
- break;
-
- case CONFERENCE_WILL_LEAVE:
- store.dispatch(clearMessages());
- break;
-
- case SEND_MESSAGE:
- if (typeof APP !== 'undefined') {
- const { conference } = store.getState()['features/base/conference'];
-
- if (conference) {
- const escapedMessage = UIUtil.escapeHtml(action.message);
-
- APP.API.notifySendingChatMessage(escapedMessage);
- conference.sendTextMessage(escapedMessage);
- }
- }
- 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 {Object} store - The redux store object.
- * @private
- * @returns {void}
- */
- function _addChatMsgListener(conference, { dispatch, getState }) {
- if ((typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly)
- || !isButtonEnabled('chat')) {
- return;
- }
-
- conference.on(
- JitsiConferenceEvents.MESSAGE_RECEIVED,
- (id, message, timestamp) => {
- const state = getState();
- const { isOpen: isChatOpen } = state['features/chat'];
-
- if (!isChatOpen) {
- dispatch(playSound(INCOMING_MSG_SOUND_ID));
- dispatch(showToolbox(4000));
- }
-
- // Provide a default for for the case when a message is being
- // backfilled for a participant that has left the conference.
- const participant = getParticipantById(state, id) || {};
- const displayName = participant.name
- || `${interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME} (${id})`;
- const hasRead = participant.local || isChatOpen;
-
- APP.API.notifyReceivedChatMessage({
- body: message,
- id,
- nick: displayName,
- ts: timestamp
- });
-
- const timestampToDate = timestamp
- ? new Date(timestamp) : new Date();
- const millisecondsTimestamp = timestampToDate.getTime();
-
- dispatch(addMessage({
- displayName,
- hasRead,
- id,
- messageType: participant.local ? 'local' : 'remote',
- message,
- timestamp: millisecondsTimestamp
- }));
- }
- );
- }
|