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

ParticipantView.native.js 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { Text, View } from 'react-native';
  4. import { Avatar } from '../../avatar';
  5. import { translate } from '../../i18n';
  6. import { JitsiParticipantConnectionStatus } from '../../lib-jitsi-meet';
  7. import {
  8. MEDIA_TYPE,
  9. VideoTrack
  10. } from '../../media';
  11. import { Container, TintedView } from '../../react';
  12. import { connect } from '../../redux';
  13. import type { StyleType } from '../../styles';
  14. import { TestHint } from '../../testing/components';
  15. import { getTrackByMediaTypeAndParticipant } from '../../tracks';
  16. import { shouldRenderParticipantVideo } from '../functions';
  17. import styles from './styles';
  18. /**
  19. * The type of the React {@link Component} props of {@link ParticipantView}.
  20. */
  21. type Props = {
  22. /**
  23. * The connection status of the participant. Her video will only be rendered
  24. * if the connection status is 'active'; otherwise, the avatar will be
  25. * rendered. If undefined, 'active' is presumed.
  26. *
  27. * @private
  28. */
  29. _connectionStatus: string,
  30. /**
  31. * The name of the participant which this component represents.
  32. *
  33. * @private
  34. */
  35. _participantName: string,
  36. /**
  37. * True if the video should be rendered, false otherwise.
  38. */
  39. _renderVideo: boolean,
  40. /**
  41. * The video Track of the participant with {@link #participantId}.
  42. */
  43. _videoTrack: Object,
  44. /**
  45. * The avatar size.
  46. */
  47. avatarSize: number,
  48. /**
  49. * Whether video should be disabled for his view.
  50. */
  51. disableVideo: ?boolean,
  52. /**
  53. * Callback to invoke when the {@code ParticipantView} is clicked/pressed.
  54. */
  55. onPress: Function,
  56. /**
  57. * The ID of the participant (to be) depicted by {@link ParticipantView}.
  58. *
  59. * @public
  60. */
  61. participantId: string,
  62. /**
  63. * The style, if any, to apply to {@link ParticipantView} in addition to its
  64. * default style.
  65. */
  66. style: Object,
  67. /**
  68. * The function to translate human-readable text.
  69. */
  70. t: Function,
  71. /**
  72. * If true, a tinting will be applied to the view, regardless of video or
  73. * avatar is rendered.
  74. */
  75. tintEnabled: boolean,
  76. /**
  77. * The style of the tinting when applied.
  78. */
  79. tintStyle: StyleType,
  80. /**
  81. * The test hint id which can be used to locate the {@code ParticipantView}
  82. * on the jitsi-meet-torture side. If not provided, the
  83. * {@code participantId} with the following format will be used:
  84. * {@code `org.jitsi.meet.Participant#${participantId}`}
  85. */
  86. testHintId: ?string,
  87. /**
  88. * Indicates if the connectivity info label should be shown, if appropriate.
  89. * It will be shown in case the connection is interrupted.
  90. */
  91. useConnectivityInfoLabel: boolean,
  92. /**
  93. * The z-order of the {@link Video} of {@link ParticipantView} in the
  94. * stacking space of all {@code Video}s. For more details, refer to the
  95. * {@code zOrder} property of the {@code Video} class for React Native.
  96. */
  97. zOrder: number,
  98. /**
  99. * Indicates whether zooming (pinch to zoom and/or drag) is enabled.
  100. */
  101. zoomEnabled: boolean
  102. };
  103. /**
  104. * Implements a React Component which depicts a specific participant's avatar
  105. * and video.
  106. *
  107. * @extends Component
  108. */
  109. class ParticipantView extends Component<Props> {
  110. /**
  111. * Renders the connection status label, if appropriate.
  112. *
  113. * @param {string} connectionStatus - The status of the participant's
  114. * connection.
  115. * @private
  116. * @returns {ReactElement|null}
  117. */
  118. _renderConnectionInfo(connectionStatus) {
  119. let messageKey;
  120. switch (connectionStatus) {
  121. case JitsiParticipantConnectionStatus.INACTIVE:
  122. messageKey = 'connection.LOW_BANDWIDTH';
  123. break;
  124. case JitsiParticipantConnectionStatus.INTERRUPTED:
  125. messageKey = 'connection.USER_CONNECTION_INTERRUPTED';
  126. break;
  127. default:
  128. return null;
  129. }
  130. const {
  131. avatarSize,
  132. _participantName: displayName,
  133. t
  134. } = this.props;
  135. // XXX Consider splitting this component into 2: one for the large view
  136. // and one for the thumbnail. Some of these don't apply to both.
  137. const containerStyle = {
  138. ...styles.connectionInfoContainer,
  139. width: avatarSize * 1.5
  140. };
  141. return (
  142. <View
  143. pointerEvents = 'box-none'
  144. style = { containerStyle }>
  145. <Text style = { styles.connectionInfoText }>
  146. { t(messageKey, { displayName }) }
  147. </Text>
  148. </View>
  149. );
  150. }
  151. /**
  152. * Implements React's {@link Component#render()}.
  153. *
  154. * @inheritdoc
  155. * @returns {ReactElement}
  156. */
  157. render() {
  158. const {
  159. _connectionStatus: connectionStatus,
  160. _renderVideo: renderVideo,
  161. _videoTrack: videoTrack,
  162. onPress,
  163. tintStyle
  164. } = this.props;
  165. // If the connection has problems, we will "tint" the video / avatar.
  166. const connectionProblem
  167. = connectionStatus !== JitsiParticipantConnectionStatus.ACTIVE;
  168. const useTint
  169. = connectionProblem || this.props.tintEnabled;
  170. const testHintId
  171. = this.props.testHintId
  172. ? this.props.testHintId
  173. : `org.jitsi.meet.Participant#${this.props.participantId}`;
  174. return (
  175. <Container
  176. onClick = { renderVideo ? undefined : onPress }
  177. style = {{
  178. ...styles.participantView,
  179. ...this.props.style
  180. }}
  181. touchFeedback = { false }>
  182. <TestHint
  183. id = { testHintId }
  184. onPress = { onPress }
  185. value = '' />
  186. { renderVideo
  187. && <VideoTrack
  188. onPress = { onPress }
  189. videoTrack = { videoTrack }
  190. waitForVideoStarted = { false }
  191. zOrder = { this.props.zOrder }
  192. zoomEnabled = { this.props.zoomEnabled } /> }
  193. { !renderVideo
  194. && <View style = { styles.avatarContainer }>
  195. <Avatar
  196. participantId = { this.props.participantId }
  197. size = { this.props.avatarSize } />
  198. </View> }
  199. { useTint
  200. // If the connection has problems, tint the video / avatar.
  201. && <TintedView
  202. style = {
  203. connectionProblem ? undefined : tintStyle } /> }
  204. { this.props.useConnectivityInfoLabel
  205. && this._renderConnectionInfo(connectionStatus) }
  206. </Container>
  207. );
  208. }
  209. }
  210. /**
  211. * Maps (parts of) the redux state to the associated {@link ParticipantView}'s
  212. * props.
  213. *
  214. * @param {Object} state - The redux state.
  215. * @param {Object} ownProps - The React {@code Component} props passed to the
  216. * associated (instance of) {@code ParticipantView}.
  217. * @private
  218. * @returns {Props}
  219. */
  220. function _mapStateToProps(state, ownProps) {
  221. const { disableVideo, participantId } = ownProps;
  222. let connectionStatus;
  223. let participantName;
  224. return {
  225. _connectionStatus:
  226. connectionStatus
  227. || JitsiParticipantConnectionStatus.ACTIVE,
  228. _participantName: participantName,
  229. _renderVideo: shouldRenderParticipantVideo(state, participantId) && !disableVideo,
  230. _videoTrack:
  231. getTrackByMediaTypeAndParticipant(
  232. state['features/base/tracks'],
  233. MEDIA_TYPE.VIDEO,
  234. participantId)
  235. };
  236. }
  237. export default translate(connect(_mapStateToProps)(ParticipantView));