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.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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. * The name of the participant. Used for showing lobby names.
  47. */
  48. displayName: string,
  49. /**
  50. * Is this item highlighted/raised
  51. */
  52. isHighlighted?: boolean,
  53. /**
  54. * Whether or not the participant is a moderator.
  55. */
  56. isModerator: boolean,
  57. /**
  58. * True if the participant is local.
  59. */
  60. local: Boolean,
  61. /**
  62. * Opens a drawer with participant actions.
  63. */
  64. openDrawerForParticipant: Function,
  65. /**
  66. * Callback for when the mouse leaves this component
  67. */
  68. onLeave?: Function,
  69. /**
  70. * If an overflow drawer can be opened.
  71. */
  72. overflowDrawer?: boolean,
  73. /**
  74. * The ID of the participant.
  75. */
  76. participantID: string,
  77. /**
  78. * True if the participant have raised hand.
  79. */
  80. raisedHand: boolean,
  81. /**
  82. * Media state for video
  83. */
  84. videoMediaState: MediaState,
  85. /**
  86. * Invoked to obtain translated strings.
  87. */
  88. t: Function,
  89. /**
  90. * The translated "you" text.
  91. */
  92. youText: string
  93. }
  94. /**
  95. * A component representing a participant entry in ParticipantPane and Lobby.
  96. *
  97. * @param {Props} props - The props of the component.
  98. * @returns {ReactNode}
  99. */
  100. function ParticipantItem({
  101. children,
  102. isHighlighted,
  103. isModerator,
  104. onLeave,
  105. actionsTrigger = ACTION_TRIGGER.HOVER,
  106. audioMediaState = MEDIA_STATE.NONE,
  107. videoMediaState = MEDIA_STATE.NONE,
  108. displayName,
  109. participantID,
  110. local,
  111. openDrawerForParticipant,
  112. overflowDrawer,
  113. raisedHand,
  114. t,
  115. youText
  116. }: Props) {
  117. const ParticipantActions = Actions[actionsTrigger];
  118. const onClick = useCallback(
  119. () => openDrawerForParticipant({
  120. participantID,
  121. displayName
  122. }));
  123. return (
  124. <ParticipantContainer
  125. id = { `participant-item-${participantID}` }
  126. isHighlighted = { isHighlighted }
  127. local = { local }
  128. onClick = { !local && overflowDrawer ? onClick : undefined }
  129. onMouseLeave = { onLeave }
  130. trigger = { actionsTrigger }>
  131. <Avatar
  132. className = 'participant-avatar'
  133. participantId = { participantID }
  134. size = { 32 } />
  135. <ParticipantContent>
  136. <ParticipantDetailsContainer>
  137. <ParticipantNameContainer>
  138. <ParticipantName>
  139. { displayName }
  140. </ParticipantName>
  141. { local ? <span>&nbsp;({ youText })</span> : null }
  142. </ParticipantNameContainer>
  143. {isModerator && <ModeratorLabel>
  144. {t('videothumbnail.moderator')}
  145. </ModeratorLabel>}
  146. </ParticipantDetailsContainer>
  147. { !local && <ParticipantActions children = { children } /> }
  148. <ParticipantStates>
  149. { raisedHand && <RaisedHandIndicator /> }
  150. { VideoStateIcons[videoMediaState] }
  151. { AudioStateIcons[audioMediaState] }
  152. </ParticipantStates>
  153. </ParticipantContent>
  154. </ParticipantContainer>
  155. );
  156. }
  157. export default translate(ParticipantItem);