2021-05-26 07:15:37 +00:00
|
|
|
// @flow
|
|
|
|
|
2021-09-01 23:13:16 +00:00
|
|
|
import React, { PureComponent } from 'react';
|
2021-05-26 07:15:37 +00:00
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
import { translate } from '../../../base/i18n';
|
2021-05-26 07:15:37 +00:00
|
|
|
import {
|
2021-09-01 23:13:16 +00:00
|
|
|
getLocalParticipant,
|
2021-11-24 07:46:01 +00:00
|
|
|
getParticipantById,
|
2021-09-22 14:05:42 +00:00
|
|
|
getParticipantDisplayName,
|
2021-10-21 09:40:57 +00:00
|
|
|
hasRaisedHand,
|
2021-09-22 14:05:42 +00:00
|
|
|
isParticipantModerator
|
2021-07-12 15:14:38 +00:00
|
|
|
} from '../../../base/participants';
|
|
|
|
import { connect } from '../../../base/redux';
|
|
|
|
import {
|
|
|
|
isParticipantAudioMuted,
|
|
|
|
isParticipantVideoMuted
|
2021-05-26 07:15:37 +00:00
|
|
|
} from '../../../base/tracks';
|
2021-09-01 23:13:16 +00:00
|
|
|
import { showConnectionStatus, showContextMenuDetails, showSharedVideoMenu } from '../../actions.native';
|
2021-07-12 15:14:38 +00:00
|
|
|
import type { MediaState } from '../../constants';
|
2021-09-22 14:05:42 +00:00
|
|
|
import { getParticipantAudioMediaState, getParticipantVideoMediaState } from '../../functions';
|
2021-05-26 07:15:37 +00:00
|
|
|
|
|
|
|
import ParticipantItem from './ParticipantItem';
|
|
|
|
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
|
|
|
|
/**
|
2021-07-12 15:14:38 +00:00
|
|
|
* Media state for audio.
|
|
|
|
*/
|
|
|
|
_audioMediaState: MediaState,
|
|
|
|
|
2021-09-28 08:46:20 +00:00
|
|
|
/**
|
|
|
|
* Whether or not to disable the moderator indicator.
|
|
|
|
*/
|
|
|
|
_disableModeratorIndicator: boolean,
|
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
/**
|
|
|
|
* The display name of the participant.
|
|
|
|
*/
|
|
|
|
_displayName: string,
|
|
|
|
|
2021-09-01 23:13:16 +00:00
|
|
|
/**
|
|
|
|
* True if the participant is fake.
|
|
|
|
*/
|
|
|
|
_isFakeParticipant: boolean,
|
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
/**
|
2021-09-22 14:05:42 +00:00
|
|
|
* Whether or not the user is a moderator.
|
2021-07-12 15:14:38 +00:00
|
|
|
*/
|
2021-09-22 14:05:42 +00:00
|
|
|
_isModerator: boolean,
|
2021-07-12 15:14:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* True if the participant is the local participant.
|
|
|
|
*/
|
|
|
|
_local: boolean,
|
|
|
|
|
2021-09-01 23:13:16 +00:00
|
|
|
/**
|
|
|
|
* Shared video local participant owner.
|
|
|
|
*/
|
|
|
|
_localVideoOwner: boolean,
|
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
/**
|
|
|
|
* The participant ID.
|
|
|
|
*/
|
|
|
|
_participantID: string,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* True if the participant have raised hand.
|
|
|
|
*/
|
|
|
|
_raisedHand: boolean,
|
|
|
|
|
2021-09-22 14:05:42 +00:00
|
|
|
/**
|
|
|
|
* Media state for video.
|
|
|
|
*/
|
|
|
|
_videoMediaState: MediaState,
|
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
/**
|
2021-09-01 23:13:16 +00:00
|
|
|
* The redux dispatch function.
|
2021-07-12 15:14:38 +00:00
|
|
|
*/
|
2021-09-01 23:13:16 +00:00
|
|
|
dispatch: Function,
|
2021-07-12 15:14:38 +00:00
|
|
|
|
|
|
|
/**
|
2021-10-21 11:58:44 +00:00
|
|
|
* The participant.
|
2021-05-26 07:15:37 +00:00
|
|
|
*/
|
2021-10-21 11:58:44 +00:00
|
|
|
participant: ?Object
|
2021-05-26 07:15:37 +00:00
|
|
|
};
|
|
|
|
|
2021-07-13 13:17:20 +00:00
|
|
|
/**
|
|
|
|
* Implements the MeetingParticipantItem component.
|
|
|
|
*/
|
2021-09-01 23:13:16 +00:00
|
|
|
class MeetingParticipantItem extends PureComponent<Props> {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates new MeetingParticipantItem instance.
|
|
|
|
*
|
|
|
|
* @param {Props} props - The props of the component.
|
|
|
|
*/
|
|
|
|
constructor(props: Props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this._onPress = this._onPress.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
_onPress: () => void;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles MeetingParticipantItem press events.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
_onPress() {
|
|
|
|
const {
|
|
|
|
_local,
|
|
|
|
_localVideoOwner,
|
|
|
|
_isFakeParticipant,
|
|
|
|
_participantID,
|
|
|
|
dispatch
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
if (_isFakeParticipant && _localVideoOwner) {
|
|
|
|
dispatch(showSharedVideoMenu(_participantID));
|
|
|
|
} else if (!_isFakeParticipant) {
|
|
|
|
if (_local) {
|
|
|
|
dispatch(showConnectionStatus(_participantID));
|
|
|
|
} else {
|
|
|
|
dispatch(showContextMenuDetails(_participantID));
|
|
|
|
}
|
|
|
|
} // else no-op
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React's {@link Component#render()}.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
* @returns {ReactElement}
|
|
|
|
*/
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
_audioMediaState,
|
2021-09-28 08:46:20 +00:00
|
|
|
_disableModeratorIndicator,
|
2021-09-01 23:13:16 +00:00
|
|
|
_displayName,
|
2021-09-22 14:05:42 +00:00
|
|
|
_isModerator,
|
2021-09-01 23:13:16 +00:00
|
|
|
_local,
|
|
|
|
_participantID,
|
2021-09-22 14:05:42 +00:00
|
|
|
_raisedHand,
|
|
|
|
_videoMediaState
|
2021-09-01 23:13:16 +00:00
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ParticipantItem
|
|
|
|
audioMediaState = { _audioMediaState }
|
2021-09-28 08:46:20 +00:00
|
|
|
disableModeratorIndicator = { _disableModeratorIndicator }
|
2021-09-01 23:13:16 +00:00
|
|
|
displayName = { _displayName }
|
|
|
|
isKnockingParticipant = { false }
|
2021-09-22 14:05:42 +00:00
|
|
|
isModerator = { _isModerator }
|
2021-09-01 23:13:16 +00:00
|
|
|
local = { _local }
|
|
|
|
onPress = { this._onPress }
|
|
|
|
participantID = { _participantID }
|
|
|
|
raisedHand = { _raisedHand }
|
2021-09-22 14:05:42 +00:00
|
|
|
videoMediaState = { _videoMediaState } />
|
2021-09-01 23:13:16 +00:00
|
|
|
);
|
|
|
|
}
|
2021-07-13 13:17:20 +00:00
|
|
|
}
|
2021-06-29 14:05:11 +00:00
|
|
|
|
2021-07-12 15:14:38 +00:00
|
|
|
/**
|
|
|
|
* Maps (parts of) the redux state to the associated props for this component.
|
|
|
|
*
|
|
|
|
* @param {Object} state - The Redux state.
|
|
|
|
* @param {Object} ownProps - The own props of the component.
|
|
|
|
* @private
|
|
|
|
* @returns {Props}
|
|
|
|
*/
|
|
|
|
function mapStateToProps(state, ownProps): Object {
|
2021-10-21 11:58:44 +00:00
|
|
|
const { participant } = ownProps;
|
2021-09-01 23:13:16 +00:00
|
|
|
const { ownerId } = state['features/shared-video'];
|
|
|
|
const localParticipantId = getLocalParticipant(state).id;
|
2021-07-12 15:14:38 +00:00
|
|
|
const _isAudioMuted = isParticipantAudioMuted(participant, state);
|
2021-09-22 14:05:42 +00:00
|
|
|
const _isVideoMuted = isParticipantVideoMuted(participant, state);
|
2021-09-01 23:13:16 +00:00
|
|
|
const audioMediaState = getParticipantAudioMediaState(participant, _isAudioMuted, state);
|
2021-09-22 14:05:42 +00:00
|
|
|
const videoMediaState = getParticipantVideoMediaState(participant, _isVideoMuted, state);
|
2021-09-28 08:46:20 +00:00
|
|
|
const { disableModeratorIndicator } = state['features/base/config'];
|
2021-11-24 07:46:01 +00:00
|
|
|
const raisedHand = hasRaisedHand(participant?.local
|
|
|
|
? participant
|
|
|
|
: getParticipantById(state, participant.id)
|
|
|
|
);
|
2021-07-12 15:14:38 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
_audioMediaState: audioMediaState,
|
2021-09-28 08:46:20 +00:00
|
|
|
_disableModeratorIndicator: disableModeratorIndicator,
|
2021-07-12 15:14:38 +00:00
|
|
|
_displayName: getParticipantDisplayName(state, participant?.id),
|
|
|
|
_isAudioMuted,
|
2021-09-01 23:13:16 +00:00
|
|
|
_isFakeParticipant: Boolean(participant?.isFakeParticipant),
|
2021-09-22 14:05:42 +00:00
|
|
|
_isModerator: isParticipantModerator(participant),
|
2021-07-12 15:14:38 +00:00
|
|
|
_local: Boolean(participant?.local),
|
2021-09-01 23:13:16 +00:00
|
|
|
_localVideoOwner: Boolean(ownerId === localParticipantId),
|
2021-07-12 15:14:38 +00:00
|
|
|
_participantID: participant?.id,
|
2021-11-24 07:46:01 +00:00
|
|
|
_raisedHand: raisedHand,
|
2021-09-22 14:05:42 +00:00
|
|
|
_videoMediaState: videoMediaState
|
2021-07-12 15:14:38 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export default translate(connect(mapStateToProps)(MeetingParticipantItem));
|
|
|
|
|
|
|
|
|