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

subscriber.ts 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import { IReduxState, IStore } from '../app/types';
  2. import { getCurrentConference } from '../base/conference/functions';
  3. import {
  4. getPinnedParticipant,
  5. isLocalParticipantModerator
  6. } from '../base/participants/functions';
  7. import StateListenerRegistry from '../base/redux/StateListenerRegistry';
  8. import { getPinnedActiveParticipants, isStageFilmstripEnabled } from '../filmstrip/functions';
  9. import { shouldDisplayTileView } from '../video-layout/functions';
  10. import { FOLLOW_ME_COMMAND } from './constants';
  11. /**
  12. * Subscribes to changes to the Follow Me setting for the local participant to
  13. * notify remote participants of current user interface status.
  14. * Changing newSelectedValue param to off, when feature is turned of so we can
  15. * notify all listeners.
  16. */
  17. StateListenerRegistry.register(
  18. /* selector */ state => state['features/base/conference'].followMeEnabled,
  19. /* listener */ (newSelectedValue, store) => _sendFollowMeCommand(newSelectedValue || 'off', store));
  20. /**
  21. * Subscribes to changes to the currently pinned participant in the user
  22. * interface of the local participant.
  23. */
  24. StateListenerRegistry.register(
  25. /* selector */ state => {
  26. const pinnedParticipant = getPinnedParticipant(state);
  27. return pinnedParticipant ? pinnedParticipant.id : null;
  28. },
  29. /* listener */ _sendFollowMeCommand);
  30. /**
  31. * Subscribes to changes to the shared document (etherpad) visibility in the
  32. * user interface of the local participant.
  33. *
  34. * @param sharedDocumentVisible - {Boolean} {true} If the shared document was
  35. * shown (as a result of the toggle) or {false} if it was hidden.
  36. */
  37. StateListenerRegistry.register(
  38. /* selector */ state => state['features/etherpad'].editing,
  39. /* listener */ _sendFollowMeCommand);
  40. /**
  41. * Subscribes to changes to the filmstrip visibility in the user interface of
  42. * the local participant.
  43. */
  44. StateListenerRegistry.register(
  45. /* selector */ state => state['features/filmstrip'].visible,
  46. /* listener */ _sendFollowMeCommand);
  47. /**
  48. * Subscribes to changes to the stage filmstrip participants.
  49. */
  50. StateListenerRegistry.register(
  51. /* selector */ getPinnedActiveParticipants,
  52. /* listener */ _sendFollowMeCommand,
  53. {
  54. deepEquals: true
  55. });
  56. /**
  57. * Subscribes to changes to the tile view setting in the user interface of the
  58. * local participant.
  59. */
  60. StateListenerRegistry.register(
  61. /* selector */ state => state['features/video-layout'].tileViewEnabled,
  62. /* listener */ _sendFollowMeCommand);
  63. /**
  64. * Subscribes to changes to the max number of stage participants setting.
  65. */
  66. StateListenerRegistry.register(
  67. /* selector */ state => state['features/base/settings'].maxStageParticipants,
  68. /* listener */ _sendFollowMeCommand);
  69. /**
  70. * Private selector for returning state from redux that should be respected by
  71. * other participants while follow me is enabled.
  72. *
  73. * @param {Object} state - The redux state.
  74. * @returns {Object}
  75. */
  76. function _getFollowMeState(state: IReduxState) {
  77. const pinnedParticipant = getPinnedParticipant(state);
  78. const stageFilmstrip = isStageFilmstripEnabled(state);
  79. return {
  80. recorder: state['features/base/conference'].followMeRecorderEnabled,
  81. filmstripVisible: state['features/filmstrip'].visible,
  82. maxStageParticipants: stageFilmstrip ? state['features/base/settings'].maxStageParticipants : undefined,
  83. nextOnStage: pinnedParticipant?.id,
  84. pinnedStageParticipants: stageFilmstrip ? JSON.stringify(getPinnedActiveParticipants(state)) : undefined,
  85. sharedDocumentVisible: state['features/etherpad'].editing,
  86. tileViewEnabled: shouldDisplayTileView(state)
  87. };
  88. }
  89. /**
  90. * Sends the follow-me command, when a local property change occurs.
  91. *
  92. * @param {*} newSelectedValue - The changed selected value from the selector.
  93. * @param {Object} store - The redux store.
  94. * @private
  95. * @returns {void}
  96. */
  97. function _sendFollowMeCommand(
  98. newSelectedValue: any, store: IStore) {
  99. const state = store.getState();
  100. const conference = getCurrentConference(state);
  101. if (!conference) {
  102. return;
  103. }
  104. // Only a moderator is allowed to send commands.
  105. if (!isLocalParticipantModerator(state)) {
  106. return;
  107. }
  108. if (newSelectedValue === 'off') {
  109. // if the change is to off, local user turned off follow me and
  110. // we want to signal this
  111. conference.sendCommandOnce(
  112. FOLLOW_ME_COMMAND,
  113. { attributes: { off: true } }
  114. );
  115. return;
  116. } else if (!state['features/base/conference'].followMeEnabled) {
  117. return;
  118. }
  119. conference.sendCommand(
  120. FOLLOW_ME_COMMAND,
  121. { attributes: _getFollowMeState(state) }
  122. );
  123. }