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

Filmstrip.native.js 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // @flow
  2. import React, { Component } from 'react';
  3. import { ScrollView } from 'react-native';
  4. import { connect } from 'react-redux';
  5. import { Container } from '../../base/react';
  6. import {
  7. isNarrowAspectRatio,
  8. makeAspectRatioAware
  9. } from '../../base/responsive-ui';
  10. import LocalThumbnail from './LocalThumbnail';
  11. import styles from './styles';
  12. import Thumbnail from './Thumbnail';
  13. /**
  14. * Filmstrip component's property types.
  15. */
  16. type Props = {
  17. /**
  18. * The indicator which determines whether the filmstrip is enabled.
  19. *
  20. * @private
  21. */
  22. _enabled: boolean,
  23. /**
  24. * The participants in the conference.
  25. *
  26. * @private
  27. */
  28. _participants: Array<any>,
  29. /**
  30. * The indicator which determines whether the filmstrip is visible.
  31. *
  32. * @private
  33. */
  34. _visible: boolean
  35. };
  36. /**
  37. * Implements a React {@link Component} which represents the filmstrip on
  38. * mobile/React Native.
  39. *
  40. * @extends Component
  41. */
  42. class Filmstrip extends Component<Props> {
  43. /**
  44. * Implements React's {@link Component#render()}.
  45. *
  46. * @inheritdoc
  47. * @returns {ReactElement}
  48. */
  49. render() {
  50. if (!this.props._enabled) {
  51. return null;
  52. }
  53. const isNarrowAspectRatio_ = isNarrowAspectRatio(this);
  54. const filmstripStyle
  55. = isNarrowAspectRatio_
  56. ? styles.filmstripNarrow
  57. : styles.filmstripWide;
  58. return (
  59. <Container
  60. style = { filmstripStyle }
  61. visible = { this.props._visible }>
  62. {
  63. !isNarrowAspectRatio_ && <LocalThumbnail />
  64. }
  65. <ScrollView
  66. horizontal = { isNarrowAspectRatio_ }
  67. showsHorizontalScrollIndicator = { false }
  68. showsVerticalScrollIndicator = { false }
  69. style = { styles.scrollView } >
  70. {
  71. /* eslint-disable react/jsx-wrap-multilines */
  72. this._sort(
  73. this.props._participants,
  74. isNarrowAspectRatio_)
  75. .map(p =>
  76. <Thumbnail
  77. key = { p.id }
  78. participant = { p } />)
  79. /* eslint-enable react/jsx-wrap-multilines */
  80. }
  81. </ScrollView>
  82. {
  83. isNarrowAspectRatio_ && <LocalThumbnail />
  84. }
  85. </Container>
  86. );
  87. }
  88. /**
  89. * Sorts a specific array of {@code Participant}s in display order.
  90. *
  91. * @param {Participant[]} participants - The array of {@code Participant}s
  92. * to sort in display order.
  93. * @param {boolean} isNarrowAspectRatio_ - Indicates if the aspect ratio is
  94. * wide or narrow.
  95. * @private
  96. * @returns {Participant[]} A new array containing the elements of the
  97. * specified {@code participants} array sorted in display order.
  98. */
  99. _sort(participants, isNarrowAspectRatio_) {
  100. // XXX Array.prototype.sort() is not appropriate because (1) it operates
  101. // in place and (2) it is not necessarily stable.
  102. const sortedParticipants = [
  103. ...participants
  104. ];
  105. if (isNarrowAspectRatio_) {
  106. // When the narrow aspect ratio is used, we want to have the remote
  107. // participants from right to left with the newest added/joined to
  108. // the leftmost side. The local participant is the leftmost item.
  109. sortedParticipants.reverse();
  110. }
  111. return sortedParticipants;
  112. }
  113. }
  114. /**
  115. * Maps (parts of) the redux state to the associated {@code Filmstrip}'s props.
  116. *
  117. * @param {Object} state - The redux state.
  118. * @private
  119. * @returns {{
  120. * _participants: Participant[],
  121. * _visible: boolean
  122. * }}
  123. */
  124. function _mapStateToProps(state) {
  125. const participants = state['features/base/participants'];
  126. const { enabled, visible } = state['features/filmstrip'];
  127. return {
  128. /**
  129. * The indicator which determines whether the filmstrip is enabled.
  130. *
  131. * @private
  132. * @type {boolean}
  133. */
  134. _enabled: enabled,
  135. /**
  136. * The remote participants in the conference.
  137. *
  138. * @private
  139. * @type {Participant[]}
  140. */
  141. _participants: participants.filter(p => !p.local),
  142. /**
  143. * The indicator which determines whether the filmstrip is visible. The
  144. * mobile/react-native Filmstrip is visible when there are at least 2
  145. * participants in the conference (including the local one).
  146. *
  147. * @private
  148. * @type {boolean}
  149. */
  150. _visible: visible && participants.length > 1
  151. };
  152. }
  153. export default connect(_mapStateToProps)(makeAspectRatioAware(Filmstrip));