// @flow import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; import { Button, withTheme } from 'react-native-paper'; import { translate } from '../../../base/i18n'; import { Icon, IconInviteMore } from '../../../base/icons'; import { getLocalParticipant, getParticipantCountWithFake, getRemoteParticipants } from '../../../base/participants'; import { connect } from '../../../base/redux'; import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions'; import { doInvitePeople } from '../../../invite/actions.native'; import { participantMatchesSearch, shouldRenderInviteButton } from '../../functions'; import ClearableInput from './ClearableInput'; import CollapsibleList from './CollapsibleList'; import MeetingParticipantItem from './MeetingParticipantItem'; import styles from './styles'; type Props = { /** * Current breakout room, if we are in one. */ _currentRoom: ?Object, /** * The local participant. */ _localParticipant: Object, /** * The number of participants in the conference. */ _participantsCount: number, /** * The remote participants. */ _remoteParticipants: Map, /** * Whether or not to show the invite button. */ _showInviteButton: boolean, /** * The remote participants. */ _sortedRemoteParticipants: Map, /** * The redux dispatch function. */ dispatch: Function, /** * Participants search string. */ searchString: string, /** * Function to update the search string. */ setSearchString: Function, /** * Translation function. */ t: Function, /** * Theme used for styles. */ theme: Object } /** * The meeting participant list component. */ class MeetingParticipantList extends PureComponent { /** * Creates new MeetingParticipantList instance. * * @param {Props} props - The props of the component. */ constructor(props: Props) { super(props); this._keyExtractor = this._keyExtractor.bind(this); this._onInvite = this._onInvite.bind(this); this._renderParticipant = this._renderParticipant.bind(this); this._onSearchStringChange = this._onSearchStringChange.bind(this); } _keyExtractor: Function; /** * Returns a key for a passed item of the list. * * @param {string} item - The user ID. * @returns {string} - The user ID. */ _keyExtractor(item) { return item; } _onInvite: () => void; /** * Handles ivite button presses. * * @returns {void} */ _onInvite() { this.props.dispatch(doInvitePeople()); } /** * Renders the "invite more" icon. * * @returns {ReactElement} */ _renderInviteMoreIcon() { return ( ); } _renderParticipant: Object => Object; /** * Renders a participant. * * @param {Object} flatListItem - Information about the item to be rendered. * @param {string} flatListItem.item - The ID of the participant. * @returns {ReactElement} */ _renderParticipant({ item/* , index, separators */ }) { const { _localParticipant, _remoteParticipants, searchString } = this.props; const participant = item === _localParticipant?.id ? _localParticipant : _remoteParticipants.get(item); if (participantMatchesSearch(participant, searchString)) { return ( ); } return null; } _onSearchStringChange: (text: string) => void; /** * Handles search string changes. * * @param {string} text - New value of the search string. * @returns {void} */ _onSearchStringChange(text: string) { this.props.setSearchString(text); } /** * Implements React's {@link Component#render()}. * * @inheritdoc * @returns {ReactElement} */ render() { const { _currentRoom, _localParticipant, _participantsCount, _showInviteButton, _sortedRemoteParticipants, t } = this.props; const title = _currentRoom?.name // $FlowExpectedError ? `${_currentRoom.name} (${_participantsCount})` : t('participantsPane.headings.participantsList', { count: _participantsCount }); const containerStyle = _participantsCount > 3 && styles.meetingListContainer; return ( { _showInviteButton &&