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

ParticipantItem.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // @flow
  2. import React, { type Node } from 'react';
  3. import { useTranslation } from 'react-i18next';
  4. import { Avatar } from '../../base/avatar';
  5. import {
  6. Icon,
  7. IconCameraEmpty,
  8. IconCameraEmptyDisabled,
  9. IconMicrophoneEmpty,
  10. IconMicrophoneEmptySlash
  11. } from '../../base/icons';
  12. import { ActionTrigger, MediaState } from '../constants';
  13. import { RaisedHandIndicator } from './RaisedHandIndicator';
  14. import {
  15. ParticipantActionsHover,
  16. ParticipantActionsPermanent,
  17. ParticipantContainer,
  18. ParticipantContent,
  19. ParticipantName,
  20. ParticipantNameContainer,
  21. ParticipantStates
  22. } from './styled';
  23. /**
  24. * Participant actions component mapping depending on trigger type.
  25. */
  26. const Actions = {
  27. [ActionTrigger.Hover]: ParticipantActionsHover,
  28. [ActionTrigger.Permanent]: ParticipantActionsPermanent
  29. };
  30. /**
  31. * Icon mapping for possible participant audio states.
  32. */
  33. const AudioStateIcons = {
  34. [MediaState.ForceMuted]: (
  35. <Icon
  36. size = { 16 }
  37. src = { IconMicrophoneEmptySlash } />
  38. ),
  39. [MediaState.Muted]: (
  40. <Icon
  41. size = { 16 }
  42. src = { IconMicrophoneEmptySlash } />
  43. ),
  44. [MediaState.Unmuted]: (
  45. <Icon
  46. size = { 16 }
  47. src = { IconMicrophoneEmpty } />
  48. ),
  49. [MediaState.None]: null
  50. };
  51. /**
  52. * Icon mapping for possible participant video states.
  53. */
  54. const VideoStateIcons = {
  55. [MediaState.ForceMuted]: (
  56. <Icon
  57. size = { 16 }
  58. src = { IconCameraEmptyDisabled } />
  59. ),
  60. [MediaState.Muted]: (
  61. <Icon
  62. size = { 16 }
  63. src = { IconCameraEmptyDisabled } />
  64. ),
  65. [MediaState.Unmuted]: (
  66. <Icon
  67. size = { 16 }
  68. src = { IconCameraEmpty } />
  69. ),
  70. [MediaState.None]: null
  71. };
  72. type Props = {
  73. /**
  74. * Type of trigger for the participant actions
  75. */
  76. actionsTrigger: ActionTrigger,
  77. /**
  78. * Media state for audio
  79. */
  80. audioMuteState: MediaState,
  81. /**
  82. * React children
  83. */
  84. children: Node,
  85. /**
  86. * Is this item highlighted/raised
  87. */
  88. isHighlighted?: boolean,
  89. /**
  90. * Callback for when the mouse leaves this component
  91. */
  92. onLeave?: Function,
  93. /**
  94. * Participant reference
  95. */
  96. participant: Object,
  97. /**
  98. * Media state for video
  99. */
  100. videoMuteState: MediaState
  101. }
  102. export const ParticipantItem = ({
  103. children,
  104. isHighlighted,
  105. onLeave,
  106. actionsTrigger = ActionTrigger.Hover,
  107. audioMuteState = MediaState.None,
  108. videoMuteState = MediaState.None,
  109. participant: p
  110. }: Props) => {
  111. const ParticipantActions = Actions[actionsTrigger];
  112. const { t } = useTranslation();
  113. return (
  114. <ParticipantContainer
  115. isHighlighted = { isHighlighted }
  116. onMouseLeave = { onLeave }
  117. trigger = { actionsTrigger }>
  118. <Avatar
  119. className = 'participant-avatar'
  120. participantId = { p.id }
  121. size = { 32 } />
  122. <ParticipantContent>
  123. <ParticipantNameContainer>
  124. <ParticipantName>
  125. { p.name }
  126. </ParticipantName>
  127. { p.local ? <span>&nbsp;({t('chat.you')})</span> : null }
  128. </ParticipantNameContainer>
  129. { !p.local && <ParticipantActions children = { children } /> }
  130. <ParticipantStates>
  131. {p.raisedHand && <RaisedHandIndicator />}
  132. {VideoStateIcons[videoMuteState]}
  133. {AudioStateIcons[audioMuteState]}
  134. </ParticipantStates>
  135. </ParticipantContent>
  136. </ParticipantContainer>
  137. );
  138. };