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.

ParticipantItem.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. // @flow
  2. import React, { type Node, useCallback } from 'react';
  3. import { Avatar } from '../../../base/avatar';
  4. import { translate } from '../../../base/i18n';
  5. import {
  6. ACTION_TRIGGER,
  7. AudioStateIcons,
  8. MEDIA_STATE,
  9. type ActionTrigger,
  10. type MediaState,
  11. VideoStateIcons
  12. } from '../../constants';
  13. import { RaisedHandIndicator } from './RaisedHandIndicator';
  14. import {
  15. ModeratorLabel,
  16. ParticipantActionsHover,
  17. ParticipantActionsPermanent,
  18. ParticipantContainer,
  19. ParticipantContent,
  20. ParticipantDetailsContainer,
  21. ParticipantName,
  22. ParticipantNameContainer,
  23. ParticipantStates
  24. } from './styled';
  25. /**
  26. * Participant actions component mapping depending on trigger type.
  27. */
  28. const Actions = {
  29. [ACTION_TRIGGER.HOVER]: ParticipantActionsHover,
  30. [ACTION_TRIGGER.PERMANENT]: ParticipantActionsPermanent
  31. };
  32. type Props = {
  33. /**
  34. * Type of trigger for the participant actions
  35. */
  36. actionsTrigger: ActionTrigger,
  37. /**
  38. * Media state for audio
  39. */
  40. audioMediaState: MediaState,
  41. /**
  42. * React children
  43. */
  44. children: Node,
  45. /**
  46. * Whether or not to disable the moderator indicator.
  47. */
  48. disableModeratorIndicator: boolean,
  49. /**
  50. * The name of the participant. Used for showing lobby names.
  51. */
  52. displayName: string,
  53. /**
  54. * Is this item highlighted/raised
  55. */
  56. isHighlighted?: boolean,
  57. /**
  58. * Whether or not the participant is a moderator.
  59. */
  60. isModerator: boolean,
  61. /**
  62. * True if the participant is local.
  63. */
  64. local: Boolean,
  65. /**
  66. * Opens a drawer with participant actions.
  67. */
  68. openDrawerForParticipant: Function,
  69. /**
  70. * Callback for when the mouse leaves this component
  71. */
  72. onLeave?: Function,
  73. /**
  74. * If an overflow drawer can be opened.
  75. */
  76. overflowDrawer?: boolean,
  77. /**
  78. * The ID of the participant.
  79. */
  80. participantID: string,
  81. /**
  82. * True if the participant have raised hand.
  83. */
  84. raisedHand: boolean,
  85. /**
  86. * Media state for video
  87. */
  88. videoMediaState: MediaState,
  89. /**
  90. * Invoked to obtain translated strings.
  91. */
  92. t: Function,
  93. /**
  94. * The translated "you" text.
  95. */
  96. youText: string
  97. }
  98. /**
  99. * A component representing a participant entry in ParticipantPane and Lobby.
  100. *
  101. * @param {Props} props - The props of the component.
  102. * @returns {ReactNode}
  103. */
  104. function ParticipantItem({
  105. actionsTrigger = ACTION_TRIGGER.HOVER,
  106. audioMediaState = MEDIA_STATE.NONE,
  107. children,
  108. disableModeratorIndicator,
  109. displayName,
  110. isHighlighted,
  111. isModerator,
  112. local,
  113. onLeave,
  114. openDrawerForParticipant,
  115. overflowDrawer,
  116. participantID,
  117. raisedHand,
  118. t,
  119. videoMediaState = MEDIA_STATE.NONE,
  120. youText
  121. }: Props) {
  122. const ParticipantActions = Actions[actionsTrigger];
  123. const onClick = useCallback(
  124. () => openDrawerForParticipant({
  125. participantID,
  126. displayName
  127. }));
  128. return (
  129. <ParticipantContainer
  130. id = { `participant-item-${participantID}` }
  131. isHighlighted = { isHighlighted }
  132. local = { local }
  133. onClick = { !local && overflowDrawer ? onClick : undefined }
  134. onMouseLeave = { onLeave }
  135. trigger = { actionsTrigger }>
  136. <Avatar
  137. className = 'participant-avatar'
  138. participantId = { participantID }
  139. size = { 32 } />
  140. <ParticipantContent>
  141. <ParticipantDetailsContainer>
  142. <ParticipantNameContainer>
  143. <ParticipantName>
  144. { displayName }
  145. </ParticipantName>
  146. { local ? <span>&nbsp;({ youText })</span> : null }
  147. </ParticipantNameContainer>
  148. {isModerator && !disableModeratorIndicator && <ModeratorLabel>
  149. {t('videothumbnail.moderator')}
  150. </ModeratorLabel>}
  151. </ParticipantDetailsContainer>
  152. { !local && <ParticipantActions children = { children } /> }
  153. <ParticipantStates>
  154. { raisedHand && <RaisedHandIndicator /> }
  155. { VideoStateIcons[videoMediaState] }
  156. { AudioStateIcons[audioMediaState] }
  157. </ParticipantStates>
  158. </ParticipantContent>
  159. </ParticipantContainer>
  160. );
  161. }
  162. export default translate(ParticipantItem);