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.

ParticipantView.native.js 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import React, { Component } from 'react';
  2. import { connect } from 'react-redux';
  3. import {
  4. MEDIA_TYPE,
  5. shouldRenderVideoTrack,
  6. VideoTrack
  7. } from '../../media';
  8. import { Container } from '../../react';
  9. import { getTrackByMediaTypeAndParticipant } from '../../tracks';
  10. import Avatar from './Avatar';
  11. import { getAvatarURL, getParticipantById } from '../functions';
  12. import { styles } from './styles';
  13. /**
  14. * Implements a React Component which depicts a specific participant's avatar
  15. * and video.
  16. *
  17. * @extends Component
  18. */
  19. class ParticipantView extends Component {
  20. /**
  21. * ParticipantView component's property types.
  22. *
  23. * @static
  24. */
  25. static propTypes = {
  26. /**
  27. * The source (e.g. URI, URL) of the avatar image of the participant
  28. * with {@link #participantId}.
  29. *
  30. * @private
  31. */
  32. _avatar: React.PropTypes.string,
  33. /**
  34. * True if the participant is in the last N endpoints set, false if he
  35. * isn't. If undefined, we have no indication, so the same course of
  36. * action as true is taken.
  37. */
  38. _isInLastN: React.PropTypes.bool,
  39. /**
  40. * The video Track of the participant with {@link #participantId}.
  41. */
  42. _videoTrack: React.PropTypes.object,
  43. /**
  44. * The style, if any, of the avatar in addition to the default style.
  45. */
  46. avatarStyle: React.PropTypes.object,
  47. /**
  48. * The ID of the participant (to be) depicted by ParticipantView.
  49. *
  50. * @public
  51. */
  52. participantId: React.PropTypes.string,
  53. /**
  54. * True if the avatar of the depicted participant is to be shown should
  55. * the avatar be available and the video of the participant is not to be
  56. * shown; otherwise, false. If undefined, defaults to true.
  57. */
  58. showAvatar: React.PropTypes.bool,
  59. /**
  60. * True if the video of the depicted participant is to be shown should
  61. * the video be available. If undefined, defaults to true.
  62. */
  63. showVideo: React.PropTypes.bool,
  64. /**
  65. * The style, if any, to apply to ParticipantView in addition to its
  66. * default style.
  67. */
  68. style: React.PropTypes.object,
  69. /**
  70. * The z-order of the Video of ParticipantView in the stacking space of
  71. * all Videos. For more details, refer to the zOrder property of the
  72. * Video class for React Native.
  73. */
  74. zOrder: React.PropTypes.number
  75. }
  76. /**
  77. * Implements React's {@link Component#render()}.
  78. *
  79. * @inheritdoc
  80. * @returns {ReactElement}
  81. */
  82. render() {
  83. const {
  84. _avatar: avatar,
  85. _isInLastN: isInLastN,
  86. _videoTrack: videoTrack
  87. } = this.props;
  88. // Is the video to be rendered?
  89. // FIXME It's currently impossible to have true as the value of
  90. // waitForVideoStarted because videoTrack's state videoStarted will be
  91. // updated only after videoTrack is rendered.
  92. const waitForVideoStarted = false;
  93. const renderVideo
  94. = shouldRenderVideoTrack(videoTrack, waitForVideoStarted)
  95. && (typeof isInLastN === 'undefined' || isInLastN);
  96. // Is the avatar to be rendered?
  97. const renderAvatar = Boolean(!renderVideo && avatar);
  98. return (
  99. <Container
  100. style = {{
  101. ...styles.participantView,
  102. ...this.props.style
  103. }}>
  104. { renderVideo
  105. // The consumer of this ParticipantView is allowed to forbid
  106. // showing the video if the private logic of this
  107. // ParticipantView determines that the video could be
  108. // rendered.
  109. && _toBoolean(this.props.showVideo, true)
  110. && <VideoTrack
  111. videoTrack = { videoTrack }
  112. waitForVideoStarted = { waitForVideoStarted }
  113. zOrder = { this.props.zOrder } /> }
  114. { renderAvatar
  115. // The consumer of this ParticipantView is allowed to forbid
  116. // showing the avatar if the private logic of this
  117. // ParticipantView determines that the avatar could be
  118. // rendered.
  119. && _toBoolean(this.props.showAvatar, true)
  120. && <Avatar
  121. style = { this.props.avatarStyle }
  122. uri = { avatar } /> }
  123. </Container>
  124. );
  125. }
  126. }
  127. /**
  128. * Converts the specified value to a boolean value. If the specified value is
  129. * undefined, returns the boolean value of undefinedValue.
  130. *
  131. * @param {any} value - The value to convert to a boolean value should it not be
  132. * undefined.
  133. * @param {any} undefinedValue - The value to convert to a boolean value should
  134. * the specified value be undefined.
  135. * @private
  136. * @returns {boolean}
  137. */
  138. function _toBoolean(value, undefinedValue) {
  139. return Boolean(typeof value === 'undefined' ? undefinedValue : value);
  140. }
  141. /**
  142. * Maps (parts of) the Redux state to the associated ParticipantView's props.
  143. *
  144. * @param {Object} state - The Redux state.
  145. * @param {Object} ownProps - The React Component props passed to the associated
  146. * (instance of) ParticipantView.
  147. * @private
  148. * @returns {{
  149. * _avatar: string,
  150. * _isInLastN: boolean,
  151. * _videoTrack: Track
  152. * }}
  153. */
  154. function _mapStateToProps(state, ownProps) {
  155. const { participantId } = ownProps;
  156. const participant
  157. = getParticipantById(
  158. state['features/base/participants'],
  159. participantId);
  160. return {
  161. _avatar: participant && getAvatarURL(participant),
  162. _isInLastN: participant && participant.isInLastN,
  163. _videoTrack:
  164. getTrackByMediaTypeAndParticipant(
  165. state['features/base/tracks'],
  166. MEDIA_TYPE.VIDEO,
  167. participantId)
  168. };
  169. }
  170. export default connect(_mapStateToProps)(ParticipantView);