Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

middleware.js 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // @flow
  2. import {
  3. CONFERENCE_FAILED,
  4. CONFERENCE_JOINED,
  5. DATA_CHANNEL_OPENED,
  6. KICKED_OUT
  7. } from '../base/conference';
  8. import { NOTIFY_CAMERA_ERROR, NOTIFY_MIC_ERROR } from '../base/devices';
  9. import { JitsiConferenceErrors } from '../base/lib-jitsi-meet';
  10. import {
  11. DOMINANT_SPEAKER_CHANGED,
  12. PARTICIPANT_KICKED,
  13. PARTICIPANT_LEFT,
  14. PARTICIPANT_JOINED,
  15. PARTICIPANT_ROLE_CHANGED,
  16. SET_LOADABLE_AVATAR_URL,
  17. getLocalParticipant,
  18. getParticipantById
  19. } from '../base/participants';
  20. import { MiddlewareRegistry } from '../base/redux';
  21. import { getBaseUrl } from '../base/util';
  22. import { appendSuffix } from '../display-name';
  23. import { SUBMIT_FEEDBACK_ERROR, SUBMIT_FEEDBACK_SUCCESS } from '../feedback';
  24. import { SET_FILMSTRIP_VISIBLE } from '../filmstrip';
  25. import './subscriber';
  26. declare var APP: Object;
  27. declare var interfaceConfig: Object;
  28. /**
  29. * The middleware of the feature {@code external-api}.
  30. *
  31. * @returns {Function}
  32. */
  33. MiddlewareRegistry.register(store => next => action => {
  34. // We need to do these before executing the rest of the middelware chain
  35. switch (action.type) {
  36. case SET_LOADABLE_AVATAR_URL: {
  37. const { id, loadableAvatarUrl } = action.participant;
  38. const participant = getParticipantById(
  39. store.getState(),
  40. id
  41. );
  42. const result = next(action);
  43. if (participant) {
  44. if (loadableAvatarUrl) {
  45. participant.loadableAvatarUrl !== loadableAvatarUrl && APP.API.notifyAvatarChanged(
  46. id,
  47. loadableAvatarUrl
  48. );
  49. } else {
  50. // There is no loadable explicit URL. In this case the Avatar component would
  51. // decide to render initials or the default avatar, but the external API needs
  52. // a URL when it needs to be rendered, so if there is no initials, we return the default
  53. // Avatar URL as if it was a usual avatar URL. If there are (or may be) initials
  54. // we send undefined to signal the api user that it's not an URL that needs to be rendered.
  55. //
  56. // NOTE: we may implement a special URL format later to signal that the avatar is based
  57. // on initials, that API consumers can handle as they want, e.g. initials://jm
  58. APP.API.notifyAvatarChanged(
  59. id,
  60. participant.name ? undefined : _getDefaultAvatarUrl()
  61. );
  62. }
  63. }
  64. return result;
  65. }
  66. }
  67. const result = next(action);
  68. // These should happen after the rest of the middleware chain ran
  69. switch (action.type) {
  70. case CONFERENCE_FAILED: {
  71. if (action.conference
  72. && action.error.name === JitsiConferenceErrors.PASSWORD_REQUIRED) {
  73. APP.API.notifyOnPasswordRequired();
  74. }
  75. break;
  76. }
  77. case CONFERENCE_JOINED: {
  78. const state = store.getState();
  79. const { room } = state['features/base/conference'];
  80. const { loadableAvatarUrl, name, id } = getLocalParticipant(state);
  81. APP.API.notifyConferenceJoined(
  82. room,
  83. id,
  84. {
  85. displayName: name,
  86. formattedDisplayName: appendSuffix(
  87. name,
  88. interfaceConfig.DEFAULT_LOCAL_DISPLAY_NAME
  89. ),
  90. avatarURL: loadableAvatarUrl
  91. }
  92. );
  93. break;
  94. }
  95. case DATA_CHANNEL_OPENED:
  96. APP.API.notifyDataChannelOpened();
  97. break;
  98. case DOMINANT_SPEAKER_CHANGED:
  99. APP.API.notifyDominantSpeakerChanged(action.participant.id);
  100. break;
  101. case KICKED_OUT:
  102. APP.API.notifyKickedOut(
  103. {
  104. id: getLocalParticipant(store.getState()).id,
  105. local: true
  106. },
  107. { id: action.participant ? action.participant.getId() : undefined }
  108. );
  109. break;
  110. case NOTIFY_CAMERA_ERROR:
  111. if (action.error) {
  112. APP.API.notifyOnCameraError(
  113. action.error.name, action.error.message);
  114. }
  115. break;
  116. case NOTIFY_MIC_ERROR:
  117. if (action.error) {
  118. APP.API.notifyOnMicError(action.error.name, action.error.message);
  119. }
  120. break;
  121. case PARTICIPANT_KICKED:
  122. APP.API.notifyKickedOut(
  123. {
  124. id: action.kicked,
  125. local: false
  126. },
  127. { id: action.kicker });
  128. break;
  129. case PARTICIPANT_LEFT:
  130. APP.API.notifyUserLeft(action.participant.id);
  131. break;
  132. case PARTICIPANT_JOINED: {
  133. const { participant } = action;
  134. const { id, local, name } = participant;
  135. // The version of external api outside of middleware did not emit
  136. // the local participant being created.
  137. if (!local) {
  138. APP.API.notifyUserJoined(id, {
  139. displayName: name,
  140. formattedDisplayName: appendSuffix(
  141. name || interfaceConfig.DEFAULT_REMOTE_DISPLAY_NAME)
  142. });
  143. }
  144. break;
  145. }
  146. case PARTICIPANT_ROLE_CHANGED:
  147. APP.API.notifyUserRoleChanged(action.participant.id, action.participant.role);
  148. break;
  149. case SET_FILMSTRIP_VISIBLE:
  150. APP.API.notifyFilmstripDisplayChanged(action.visible);
  151. break;
  152. case SUBMIT_FEEDBACK_ERROR:
  153. APP.API.notifyFeedbackSubmitted(action.error || 'Unknown error');
  154. break;
  155. case SUBMIT_FEEDBACK_SUCCESS:
  156. APP.API.notifyFeedbackSubmitted();
  157. break;
  158. }
  159. return result;
  160. });
  161. /**
  162. * Returns the absolute URL of the default avatar.
  163. *
  164. * @returns {string}
  165. */
  166. function _getDefaultAvatarUrl() {
  167. return new URL('images/avatar.png', getBaseUrl()).href;
  168. }