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

MeetingParticipantItem.js 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. // @flow
  2. import React from 'react';
  3. import {
  4. getLocalParticipant,
  5. getParticipantByIdOrUndefined,
  6. getParticipantDisplayName
  7. } from '../../../base/participants';
  8. import { connect } from '../../../base/redux';
  9. import { isParticipantAudioMuted, isParticipantVideoMuted } from '../../../base/tracks';
  10. import { ACTION_TRIGGER, type MediaState } from '../../constants';
  11. import {
  12. getParticipantAudioMediaState,
  13. getParticipantVideoMediaState,
  14. getQuickActionButtonType
  15. } from '../../functions';
  16. import ParticipantQuickAction from '../ParticipantQuickAction';
  17. import ParticipantItem from './ParticipantItem';
  18. import { ParticipantActionEllipsis } from './styled';
  19. type Props = {
  20. /**
  21. * Media state for audio.
  22. */
  23. _audioMediaState: MediaState,
  24. /**
  25. * Media state for video.
  26. */
  27. _videoMediaState: MediaState,
  28. /**
  29. * The display name of the participant.
  30. */
  31. _displayName: string,
  32. /**
  33. * True if the participant is the local participant.
  34. */
  35. _local: Boolean,
  36. /**
  37. * Shared video local participant owner.
  38. */
  39. _localVideoOwner: boolean,
  40. /**
  41. * The participant.
  42. */
  43. _participant: Object,
  44. /**
  45. * The participant ID.
  46. *
  47. * NOTE: This ID may be different from participantID prop in the case when we pass undefined for the local
  48. * participant. In this case the local participant ID will be filled trough _participantID prop.
  49. */
  50. _participantID: string,
  51. /**
  52. * The type of button to be rendered for the quick action.
  53. */
  54. _quickActionButtonType: string,
  55. /**
  56. * True if the participant have raised hand.
  57. */
  58. _raisedHand: boolean,
  59. /**
  60. * The translated ask unmute text for the qiuck action buttons.
  61. */
  62. askUnmuteText: string,
  63. /**
  64. * Is this item highlighted
  65. */
  66. isHighlighted: boolean,
  67. /**
  68. * Callback used to open a confirmation dialog for audio muting.
  69. */
  70. muteAudio: Function,
  71. /**
  72. * The translated text for the mute participant button.
  73. */
  74. muteParticipantButtonText: string,
  75. /**
  76. * Callback for the activation of this item's context menu
  77. */
  78. onContextMenu: Function,
  79. /**
  80. * Callback for the mouse leaving this item
  81. */
  82. onLeave: Function,
  83. /**
  84. * Callback used to open an actions drawer for a participant.
  85. */
  86. openDrawerForParticipant: Function,
  87. /**
  88. * True if an overflow drawer should be displayed.
  89. */
  90. overflowDrawer: boolean,
  91. /**
  92. * The aria-label for the ellipsis action.
  93. */
  94. participantActionEllipsisLabel: string,
  95. /**
  96. * The ID of the participant.
  97. */
  98. participantID: ?string,
  99. /**
  100. * The translated "you" text.
  101. */
  102. youText: string
  103. };
  104. /**
  105. * Implements the MeetingParticipantItem component.
  106. *
  107. * @param {Props} props - The props of the component.
  108. * @returns {ReactElement}
  109. */
  110. function MeetingParticipantItem({
  111. _audioMediaState,
  112. _videoMediaState,
  113. _displayName,
  114. _local,
  115. _localVideoOwner,
  116. _participant,
  117. _participantID,
  118. _quickActionButtonType,
  119. _raisedHand,
  120. askUnmuteText,
  121. isHighlighted,
  122. muteAudio,
  123. muteParticipantButtonText,
  124. onContextMenu,
  125. onLeave,
  126. openDrawerForParticipant,
  127. overflowDrawer,
  128. participantActionEllipsisLabel,
  129. youText
  130. }: Props) {
  131. return (
  132. <ParticipantItem
  133. actionsTrigger = { ACTION_TRIGGER.HOVER }
  134. audioMediaState = { _audioMediaState }
  135. displayName = { _displayName }
  136. isHighlighted = { isHighlighted }
  137. local = { _local }
  138. onLeave = { onLeave }
  139. openDrawerForParticipant = { openDrawerForParticipant }
  140. overflowDrawer = { overflowDrawer }
  141. participantID = { _participantID }
  142. raisedHand = { _raisedHand }
  143. videoMediaState = { _videoMediaState }
  144. youText = { youText }>
  145. {!overflowDrawer && !_participant.isFakeParticipant
  146. && <>
  147. <ParticipantQuickAction
  148. askUnmuteText = { askUnmuteText }
  149. buttonType = { _quickActionButtonType }
  150. muteAudio = { muteAudio }
  151. muteParticipantButtonText = { muteParticipantButtonText }
  152. participantID = { _participantID } />
  153. <ParticipantActionEllipsis
  154. aria-label = { participantActionEllipsisLabel }
  155. onClick = { onContextMenu } />
  156. </>
  157. }
  158. {!overflowDrawer && _localVideoOwner && _participant.isFakeParticipant && (
  159. <ParticipantActionEllipsis
  160. aria-label = { participantActionEllipsisLabel }
  161. onClick = { onContextMenu } />
  162. )}
  163. </ParticipantItem>
  164. );
  165. }
  166. /**
  167. * Maps (parts of) the redux state to the associated props for this component.
  168. *
  169. * @param {Object} state - The Redux state.
  170. * @param {Object} ownProps - The own props of the component.
  171. * @private
  172. * @returns {Props}
  173. */
  174. function _mapStateToProps(state, ownProps): Object {
  175. const { participantID } = ownProps;
  176. const { ownerId } = state['features/shared-video'];
  177. const localParticipantId = getLocalParticipant(state).id;
  178. const participant = getParticipantByIdOrUndefined(state, participantID);
  179. const _isAudioMuted = isParticipantAudioMuted(participant, state);
  180. const _isVideoMuted = isParticipantVideoMuted(participant, state);
  181. const _audioMediaState = getParticipantAudioMediaState(participant, _isAudioMuted, state);
  182. const _videoMediaState = getParticipantVideoMediaState(participant, _isVideoMuted, state);
  183. const _quickActionButtonType = getQuickActionButtonType(participant, _isAudioMuted, state);
  184. return {
  185. _audioMediaState,
  186. _videoMediaState,
  187. _displayName: getParticipantDisplayName(state, participant?.id),
  188. _local: Boolean(participant?.local),
  189. _localVideoOwner: Boolean(ownerId === localParticipantId),
  190. _participant: participant,
  191. _participantID: participant?.id,
  192. _quickActionButtonType,
  193. _raisedHand: Boolean(participant?.raisedHand)
  194. };
  195. }
  196. export default connect(_mapStateToProps)(MeetingParticipantItem);