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.

Filmstrip.native.js 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* @flow */
  2. import PropTypes from 'prop-types';
  3. import React, { Component } from 'react';
  4. import { ScrollView } from 'react-native';
  5. import { connect } from 'react-redux';
  6. import { Container } from '../../base/react';
  7. import Thumbnail from './Thumbnail';
  8. import { styles } from './_';
  9. /**
  10. * Implements a React {@link Component} which represents the filmstrip on
  11. * mobile/React Native.
  12. *
  13. * @extends Component
  14. */
  15. class Filmstrip extends Component<*> {
  16. /**
  17. * Filmstrip component's property types.
  18. *
  19. * @static
  20. */
  21. static propTypes = {
  22. /**
  23. * The participants in the conference.
  24. *
  25. * @private
  26. * @type {Participant[]}
  27. */
  28. _participants: PropTypes.array,
  29. /**
  30. * The indicator which determines whether the filmstrip is visible.
  31. *
  32. * @private
  33. * @type {boolean}
  34. */
  35. _visible: PropTypes.bool.isRequired
  36. };
  37. /**
  38. * Implements React's {@link Component#render()}.
  39. *
  40. * @inheritdoc
  41. * @returns {ReactElement}
  42. */
  43. render() {
  44. return (
  45. <Container
  46. style = { styles.filmstrip }
  47. visible = { this.props._visible }>
  48. <ScrollView
  49. contentContainerStyle
  50. = { styles.filmstripScrollViewContentContainer }
  51. horizontal = { true }
  52. showsHorizontalScrollIndicator = { false }
  53. showsVerticalScrollIndicator = { false }>
  54. {
  55. /* eslint-disable react/jsx-wrap-multilines */
  56. this._sort(this.props._participants)
  57. .map(p =>
  58. <Thumbnail
  59. key = { p.id }
  60. participant = { p } />)
  61. /* eslint-enable react/jsx-wrap-multilines */
  62. }
  63. </ScrollView>
  64. </Container>
  65. );
  66. }
  67. /**
  68. * Sorts a specific array of {@code Participant}s in display order.
  69. *
  70. * @param {Participant[]} participants - The array of {@code Participant}s
  71. * to sort in display order.
  72. * @private
  73. * @returns {Participant[]} A new array containing the elements of the
  74. * specified {@code participants} array sorted in display order.
  75. */
  76. _sort(participants) {
  77. // XXX Array.prototype.sort() is not appropriate because (1) it operates
  78. // in place and (2) it is not necessarily stable.
  79. const sortedParticipants = [];
  80. // Group the remote participants so that the local participant does not
  81. // appear in between remote participants. Have the remote participants
  82. // from right to left with the newest added/joined to the leftmost side.
  83. for (let i = participants.length - 1; i >= 0; --i) {
  84. const p = participants[i];
  85. p.local || sortedParticipants.push(p);
  86. }
  87. // Have the local participant at the rightmost side.
  88. for (let i = participants.length - 1; i >= 0; --i) {
  89. const p = participants[i];
  90. p.local && sortedParticipants.push(p);
  91. }
  92. return sortedParticipants;
  93. }
  94. }
  95. /**
  96. * Function that maps parts of Redux state tree into component props.
  97. *
  98. * @param {Object} state - Redux state.
  99. * @private
  100. * @returns {{
  101. * _participants: Participant[],
  102. * _visible: boolean
  103. * }}
  104. */
  105. function _mapStateToProps(state) {
  106. return {
  107. /**
  108. * The participants in the conference.
  109. *
  110. * @private
  111. * @type {Participant[]}
  112. */
  113. _participants: state['features/base/participants'],
  114. /**
  115. * The indicator which determines whether the filmstrip is visible.
  116. *
  117. * XXX The React Component Filmstrip is used on mobile only at the time
  118. * of this writing and on mobile the filmstrip is visible when the
  119. * toolbar is not.
  120. *
  121. * @private
  122. * @type {boolean}
  123. */
  124. _visible: !state['features/toolbox'].visible
  125. };
  126. }
  127. export default connect(_mapStateToProps)(Filmstrip);