You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

middleware.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // @flow
  2. import UIUtil from '../../../modules/UI/util/UIUtil';
  3. import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
  4. import { CONFERENCE_JOINED } from '../base/conference';
  5. import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
  6. import { getParticipantById } from '../base/participants';
  7. import { MiddlewareRegistry } from '../base/redux';
  8. import { playSound, registerSound, unregisterSound } from '../base/sounds';
  9. import { isButtonEnabled, showToolbox } from '../toolbox';
  10. import { SEND_MESSAGE } from './actionTypes';
  11. import { addMessage } from './actions';
  12. import { INCOMING_MSG_SOUND_ID } from './constants';
  13. import { INCOMING_MSG_SOUND_FILE } from './sounds';
  14. declare var APP: Object;
  15. declare var interfaceConfig : Object;
  16. /**
  17. * Implements the middleware of the chat feature.
  18. *
  19. * @param {Store} store - The redux store.
  20. * @returns {Function}
  21. */
  22. MiddlewareRegistry.register(store => next => action => {
  23. switch (action.type) {
  24. case APP_WILL_MOUNT:
  25. // Register the chat message sound on Web only because there's no chat
  26. // on mobile.
  27. typeof APP === 'undefined'
  28. || store.dispatch(
  29. registerSound(INCOMING_MSG_SOUND_ID, INCOMING_MSG_SOUND_FILE));
  30. break;
  31. case APP_WILL_UNMOUNT:
  32. // Unregister the chat message sound on Web because it's registered
  33. // there only.
  34. typeof APP === 'undefined'
  35. || store.dispatch(unregisterSound(INCOMING_MSG_SOUND_ID));
  36. break;
  37. case CONFERENCE_JOINED:
  38. typeof APP === 'undefined'
  39. || _addChatMsgListener(action.conference, store);
  40. break;
  41. case SEND_MESSAGE:
  42. if (typeof APP !== 'undefined') {
  43. const { conference } = store.getState()['features/base/conference'];
  44. if (conference) {
  45. const escapedMessage = UIUtil.escapeHtml(action.message);
  46. APP.API.notifySendingChatMessage(escapedMessage);
  47. conference.sendTextMessage(escapedMessage);
  48. }
  49. }
  50. break;
  51. }
  52. return next(action);
  53. });
  54. /**
  55. * Registers listener for {@link JitsiConferenceEvents.MESSAGE_RECEIVED} which
  56. * will play a sound on the event, given that the chat is not currently visible.
  57. *
  58. * @param {JitsiConference} conference - The conference instance on which the
  59. * new event listener will be registered.
  60. * @param {Object} store - The redux store object.
  61. * @private
  62. * @returns {void}
  63. */
  64. function _addChatMsgListener(conference, { dispatch, getState }) {
  65. if ((typeof interfaceConfig === 'object' && interfaceConfig.filmStripOnly)
  66. || !isButtonEnabled('chat')) {
  67. return;
  68. }
  69. conference.on(
  70. JitsiConferenceEvents.MESSAGE_RECEIVED,
  71. (id, message, timestamp) => {
  72. const state = getState();
  73. const { isOpen: isChatOpen } = state['features/chat'];
  74. if (!isChatOpen) {
  75. dispatch(playSound(INCOMING_MSG_SOUND_ID));
  76. dispatch(showToolbox(4000));
  77. }
  78. // Provide a default for for the case when a message is being
  79. // backfilled for a participant that has left the conference.
  80. const participant = getParticipantById(state, id) || {};
  81. const displayName = participant.name
  82. || `${interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME} (${id})`;
  83. const hasRead = participant.local || isChatOpen;
  84. APP.API.notifyReceivedChatMessage({
  85. body: message,
  86. id,
  87. nick: displayName,
  88. ts: timestamp
  89. });
  90. const timestampToDate = timestamp
  91. ? new Date(timestamp) : new Date();
  92. const millisecondsTimestamp = timestampToDate.getTime();
  93. dispatch(addMessage({
  94. displayName,
  95. hasRead,
  96. id,
  97. messageType: participant.local ? 'local' : 'remote',
  98. message,
  99. timestamp: millisecondsTimestamp
  100. }));
  101. }
  102. );
  103. }