您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

middleware.web.ts 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { generateCollaborationLinkData } from '@jitsi/excalidraw';
  2. import { AnyAction } from 'redux';
  3. import { IStore } from '../app/types';
  4. import { getCurrentConference } from '../base/conference/functions';
  5. import { hideDialog, openDialog } from '../base/dialog/actions';
  6. import { isDialogOpen } from '../base/dialog/functions';
  7. import { participantJoined, participantLeft, pinParticipant } from '../base/participants/actions';
  8. import { FakeParticipant } from '../base/participants/types';
  9. import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
  10. import { getCurrentRoomId } from '../breakout-rooms/functions';
  11. import { addStageParticipant } from '../filmstrip/actions.web';
  12. import { isStageFilmstripAvailable } from '../filmstrip/functions.web';
  13. import { RESET_WHITEBOARD, SET_WHITEBOARD_OPEN } from './actionTypes';
  14. import {
  15. notifyWhiteboardLimit,
  16. restrictWhiteboard,
  17. setupWhiteboard
  18. } from './actions';
  19. import WhiteboardLimitDialog from './components/web/WhiteboardLimitDialog';
  20. import { WHITEBOARD_ID, WHITEBOARD_PARTICIPANT_NAME } from './constants';
  21. import {
  22. generateCollabServerUrl,
  23. getCollabDetails,
  24. isWhiteboardPresent,
  25. shouldEnforceUserLimit,
  26. shouldNotifyUserLimit
  27. } from './functions';
  28. import { WhiteboardStatus } from './types';
  29. import './middleware.any';
  30. const focusWhiteboard = (store: IStore) => {
  31. const { dispatch, getState } = store;
  32. const state = getState();
  33. const conference = getCurrentConference(state);
  34. const stageFilmstrip = isStageFilmstripAvailable(state);
  35. const isPresent = isWhiteboardPresent(state);
  36. if (!isPresent) {
  37. dispatch(participantJoined({
  38. conference,
  39. fakeParticipant: FakeParticipant.Whiteboard,
  40. id: WHITEBOARD_ID,
  41. name: WHITEBOARD_PARTICIPANT_NAME
  42. }));
  43. }
  44. if (stageFilmstrip) {
  45. dispatch(addStageParticipant(WHITEBOARD_ID, true));
  46. } else {
  47. dispatch(pinParticipant(WHITEBOARD_ID));
  48. }
  49. };
  50. /**
  51. * Middleware which intercepts whiteboard actions to handle changes to the related state.
  52. *
  53. * @param {Store} store - The redux store.
  54. * @returns {Function}
  55. */
  56. MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: AnyAction) => {
  57. const { dispatch, getState } = store;
  58. const state = getState();
  59. const conference = getCurrentConference(state);
  60. switch (action.type) {
  61. case SET_WHITEBOARD_OPEN: {
  62. const existingCollabDetails = getCollabDetails(state);
  63. const enforceUserLimit = shouldEnforceUserLimit(state);
  64. const notifyUserLimit = shouldNotifyUserLimit(state);
  65. const iAmRecorder = Boolean(state['features/base/config'].iAmRecorder);
  66. if (enforceUserLimit) {
  67. dispatch(restrictWhiteboard(false));
  68. dispatch(openDialog(WhiteboardLimitDialog));
  69. iAmRecorder && setTimeout(() => dispatch(hideDialog(WhiteboardLimitDialog)), 3000);
  70. return next(action);
  71. }
  72. if (!existingCollabDetails) {
  73. setNewWhiteboardOpen(store);
  74. return next(action);
  75. }
  76. if (action.isOpen) {
  77. if (enforceUserLimit) {
  78. dispatch(restrictWhiteboard());
  79. return next(action);
  80. }
  81. if (notifyUserLimit) {
  82. dispatch(notifyWhiteboardLimit());
  83. }
  84. if (isDialogOpen(state, WhiteboardLimitDialog)) {
  85. dispatch(hideDialog(WhiteboardLimitDialog));
  86. }
  87. focusWhiteboard(store);
  88. raiseWhiteboardNotification(WhiteboardStatus.SHOWN);
  89. return next(action);
  90. }
  91. dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
  92. raiseWhiteboardNotification(WhiteboardStatus.HIDDEN);
  93. break;
  94. }
  95. case RESET_WHITEBOARD: {
  96. dispatch(participantLeft(WHITEBOARD_ID, conference, { fakeParticipant: FakeParticipant.Whiteboard }));
  97. raiseWhiteboardNotification(WhiteboardStatus.RESET);
  98. break;
  99. }
  100. }
  101. return next(action);
  102. });
  103. /**
  104. * Raises the whiteboard status notifications changes (if API is enabled).
  105. *
  106. * @param {WhiteboardStatus} status - The whiteboard changed status.
  107. * @returns {Function}
  108. */
  109. function raiseWhiteboardNotification(status: WhiteboardStatus) {
  110. if (typeof APP !== 'undefined') {
  111. APP.API.notifyWhiteboardStatusChanged(status);
  112. }
  113. }
  114. /**
  115. * Sets a new whiteboard open.
  116. *
  117. * @param {IStore} store - The redux store.
  118. * @returns {Promise}
  119. */
  120. async function setNewWhiteboardOpen(store: IStore) {
  121. const { dispatch, getState } = store;
  122. const collabLinkData = await generateCollaborationLinkData();
  123. const state = getState();
  124. const conference = getCurrentConference(state);
  125. const collabServerUrl = generateCollabServerUrl(state);
  126. const roomId = getCurrentRoomId(state);
  127. const collabData = {
  128. collabDetails: {
  129. roomId,
  130. roomKey: collabLinkData.roomKey
  131. },
  132. collabServerUrl
  133. };
  134. focusWhiteboard(store);
  135. dispatch(setupWhiteboard(collabData));
  136. conference?.getMetadataHandler().setMetadata(WHITEBOARD_ID, collabData);
  137. raiseWhiteboardNotification(WhiteboardStatus.INSTANTIATED);
  138. }