feat(native-participants-pane) rebase, resolved conflicts pt. 2

This commit is contained in:
Calin Chitu 2021-07-13 16:17:20 +03:00 committed by Hristo Terezov
parent d62e378528
commit b268e01a42
9 changed files with 70 additions and 78 deletions

View File

@ -261,23 +261,6 @@ export function haveParticipantWithScreenSharingFeature(stateful: Object | Funct
return toState(stateful)['features/base/participants'].haveParticipantWithScreenSharingFeature; return toState(stateful)['features/base/participants'].haveParticipantWithScreenSharingFeature;
} }
/**
* Selectors for getting all known participant ids, with fake participants filtered
* out.
*
* @param {(Function|Object|Participant[])} stateful - The redux state
* features/base/participants, the (whole) redux state, or redux's
* {@code getState} function to be used to retrieve the state
* features/base/participants.
* @returns {Participant[]}
*/
export function getParticipantsById(stateful: Object | Function) {
const state = toState(stateful)['features/base/participants'];
const noFakeParticipants = state.filter(p => !p.fakeParticipants);
return noFakeParticipants.map(p => p.id);
}
/** /**
* Selectors for getting all remote participants. * Selectors for getting all remote participants.
* *

View File

@ -12,7 +12,7 @@ export function getLobbyState(state: any) {
/** /**
* Selector to return lobby state. * Selector to return array with knocking participant ids.
* *
* @param {any} state - State object. * @param {any} state - State object.
* @returns {Array} * @returns {Array}

View File

@ -3,7 +3,10 @@
import { openDialog } from '../base/dialog'; import { openDialog } from '../base/dialog';
import { SET_VOLUME } from './actionTypes'; import { SET_VOLUME } from './actionTypes';
import { ContextMenuLobbyParticipantReject, ContextMenuMeetingParticipantDetails } from './components/native'; import {
ContextMenuMeetingParticipantDetails,
ContextMenuLobbyParticipantReject
} from './components/native';
export * from './actions.any'; export * from './actions.any';
/** /**

View File

@ -24,7 +24,7 @@ type Props = {
participant: Object participant: Object
}; };
export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => { const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const knockParticipantsIDArr = useSelector(getKnockingParticipantsById); const knockParticipantsIDArr = useSelector(getKnockingParticipantsById);
const knockParticipantIsAvailable = knockParticipantsIDArr.find(knockPartId => knockPartId === p.id); const knockParticipantIsAvailable = knockParticipantsIDArr.find(knockPartId => knockPartId === p.id);
@ -63,3 +63,5 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
</BottomSheet> </BottomSheet>
); );
}; };
export default ContextMenuLobbyParticipantReject;

View File

@ -7,7 +7,6 @@ import { Divider, Text } from 'react-native-paper';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { Avatar } from '../../../base/avatar'; import { Avatar } from '../../../base/avatar';
import { isToolbarButtonEnabled } from '../../../base/config';
import { hideDialog, openDialog } from '../../../base/dialog/actions'; import { hideDialog, openDialog } from '../../../base/dialog/actions';
import BottomSheet from '../../../base/dialog/components/native/BottomSheet'; import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
import { import {
@ -16,7 +15,9 @@ import {
IconMuteEveryoneElse, IconVideoOff IconMuteEveryoneElse, IconVideoOff
} from '../../../base/icons'; } from '../../../base/icons';
import { import {
getParticipantByIdOrUndefined, getParticipantDisplayName, getLocalParticipant,
getParticipantByIdOrUndefined,
getParticipantDisplayName, getRemoteParticipants,
isLocalParticipantModerator isLocalParticipantModerator
} from '../../../base/participants/functions'; } from '../../../base/participants/functions';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
@ -29,9 +30,9 @@ import {
KickRemoteParticipantDialog, KickRemoteParticipantDialog,
MuteEveryoneDialog, MuteEveryoneDialog,
MuteRemoteParticipantDialog, MuteRemoteParticipantDialog,
MuteRemoteParticipantsVideoDialog, MuteRemoteParticipantsVideoDialog
VolumeSlider
} from '../../../video-menu'; } from '../../../video-menu';
import VolumeSlider from '../../../video-menu/components/native/VolumeSlider';
import styles from './styles'; import styles from './styles';
@ -47,11 +48,6 @@ type Props = {
*/ */
_isLocalModerator: boolean, _isLocalModerator: boolean,
/**
* True if the chat button is enabled and false otherwise.
*/
_isChatButtonEnabled: boolean,
/** /**
* True if the participant is moderator and false otherwise. * True if the participant is moderator and false otherwise.
*/ */
@ -67,6 +63,11 @@ type Props = {
*/ */
_isParticipantAudioMuted: boolean, _isParticipantAudioMuted: boolean,
/**
* Whether the participant is present in the room or not.
*/
_isParticipantIDAvailable?: boolean,
/** /**
* Participant reference * Participant reference
*/ */
@ -78,14 +79,14 @@ type Props = {
participantID: string, participantID: string,
}; };
export const ContextMenuMeetingParticipantDetails = ( const ContextMenuMeetingParticipantDetails = (
{ {
_displayName, _displayName,
_isLocalModerator, _isLocalModerator,
_isChatButtonEnabled,
_isParticipantVideoMuted, _isParticipantVideoMuted,
_isParticipantAudioMuted, _isParticipantAudioMuted,
_participant, _participant,
_isParticipantIDAvailable,
participantID participantID
}: Props) => { }: Props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -121,6 +122,7 @@ export const ContextMenuMeetingParticipantDetails = (
<BottomSheet <BottomSheet
addScrollViewPadding = { false } addScrollViewPadding = { false }
onCancel = { cancel } onCancel = { cancel }
showSlidingView = { _isParticipantIDAvailable }
style = { styles.contextMenuMeetingParticipantDetails }> style = { styles.contextMenuMeetingParticipantDetails }>
<View <View
style = { styles.contextMenuItemSectionAvatar }> style = { styles.contextMenuItemSectionAvatar }>
@ -196,8 +198,6 @@ export const ContextMenuMeetingParticipantDetails = (
</> </>
) )
} }
{
_isChatButtonEnabled && (
<TouchableOpacity <TouchableOpacity
onPress = { sendPrivateMessage } onPress = { sendPrivateMessage }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
@ -208,8 +208,6 @@ export const ContextMenuMeetingParticipantDetails = (
{ t('toolbar.accessibilityLabel.privateMessage') } { t('toolbar.accessibilityLabel.privateMessage') }
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
)
}
{/* We need design specs for this*/} {/* We need design specs for this*/}
{/* <TouchableOpacity*/} {/* <TouchableOpacity*/}
{/* style = { styles.contextMenuItemSection }>*/} {/* style = { styles.contextMenuItemSection }>*/}
@ -220,7 +218,7 @@ export const ContextMenuMeetingParticipantDetails = (
{/* <Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text>*/} {/* <Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text>*/}
{/* </TouchableOpacity>*/} {/* </TouchableOpacity>*/}
<Divider style = { styles.divider } /> <Divider style = { styles.divider } />
<VolumeSlider participant = { _participant } /> <VolumeSlider participantID = { participantID } />
</BottomSheet> </BottomSheet>
); );
}; };
@ -236,17 +234,28 @@ export const ContextMenuMeetingParticipantDetails = (
*/ */
function _mapStateToProps(state, ownProps): Object { function _mapStateToProps(state, ownProps): Object {
const { participantID } = ownProps; const { participantID } = ownProps;
const participantIDS = [];
const participant = getParticipantByIdOrUndefined(state, participantID); const participant = getParticipantByIdOrUndefined(state, participantID);
const _isLocalModerator = isLocalParticipantModerator(state); const _isLocalModerator = isLocalParticipantModerator(state);
const _isChatButtonEnabled = isToolbarButtonEnabled('chat', state);
const _isParticipantVideoMuted = isParticipantVideoMuted(participant, state); const _isParticipantVideoMuted = isParticipantVideoMuted(participant, state);
const _isParticipantAudioMuted = isParticipantAudioMuted(participant, state); const _isParticipantAudioMuted = isParticipantAudioMuted(participant, state);
const localParticipant = getLocalParticipant(state);
const remoteParticipants = getRemoteParticipants(state);
localParticipant && participantIDS.push(localParticipant?.id);
remoteParticipants.forEach(p => {
participantIDS.push(p?.id);
});
const isParticipantIDAvailable = participantIDS.find(partID => partID === participantID);
return { return {
_displayName: getParticipantDisplayName(state, participantID), _displayName: getParticipantDisplayName(state, participantID),
_isLocalModerator, _isLocalModerator,
_isChatButtonEnabled,
_isParticipantAudioMuted, _isParticipantAudioMuted,
_isParticipantIDAvailable: Boolean(isParticipantIDAvailable),
_isParticipantVideoMuted, _isParticipantVideoMuted,
_participant: participant _participant: participant
}; };

View File

@ -62,8 +62,13 @@ type Props = {
participantID: ?string participantID: ?string
}; };
const MeetingParticipantItem = ( /**
{ * Implements the MeetingParticipantItem component.
*
* @param {Props} props - The props of the component.
* @returns {ReactElement}
*/
function MeetingParticipantItem({
_audioMediaState, _audioMediaState,
_displayName, _displayName,
_isVideoMuted, _isVideoMuted,
@ -71,21 +76,19 @@ const MeetingParticipantItem = (
_participantID, _participantID,
_raisedHand, _raisedHand,
onPress onPress
}: Props) => { }: Props) {
const showParticipantDetails = !_local && onPress;
return ( return (
<ParticipantItem <ParticipantItem
audioMediaState = { _audioMediaState } audioMediaState = { _audioMediaState }
displayName = { _displayName } displayName = { _displayName }
isKnockingParticipant = { false } isKnockingParticipant = { false }
local = { _local } local = { _local }
onPress = { showParticipantDetails } onPress = { onPress }
participantID = { _participantID } participantID = { _participantID }
raisedHand = { _raisedHand } raisedHand = { _raisedHand }
videoMediaState = { _isVideoMuted ? MEDIA_STATE.MUTED : MEDIA_STATE.UNMUTED } /> videoMediaState = { _isVideoMuted ? MEDIA_STATE.MUTED : MEDIA_STATE.UNMUTED } />
); );
}; }
/** /**
* Maps (parts of) the redux state to the associated props for this component. * Maps (parts of) the redux state to the associated props for this component.

View File

@ -35,7 +35,7 @@ export const MeetingParticipantList = () => {
<MeetingParticipantItem <MeetingParticipantItem
key = { id } key = { id }
/* eslint-disable-next-line react/jsx-no-bind */ /* eslint-disable-next-line react/jsx-no-bind */
onPress = { () => dispatch(showContextMenuDetails(id)) } onPress = { () => !localParticipant && dispatch(showContextMenuDetails(id)) }
participantID = { id } /> participantID = { id } />
); );

View File

@ -2,5 +2,5 @@
export { default as ParticipantsPane } from './ParticipantsPane'; export { default as ParticipantsPane } from './ParticipantsPane';
export { default as ParticipantsPaneButton } from './ParticipantsPaneButton'; export { default as ParticipantsPaneButton } from './ParticipantsPaneButton';
export { ContextMenuLobbyParticipantReject } from './ContextMenuLobbyParticipantReject'; export { default as ContextMenuLobbyParticipantReject } from './ContextMenuLobbyParticipantReject';
export { ContextMenuMeetingParticipantDetails } from './ContextMenuMeetingParticipantDetails'; export { default as ContextMenuMeetingParticipantDetails } from './ContextMenuMeetingParticipantDetails';

View File

@ -6,7 +6,7 @@ import { Slider, View } from 'react-native';
import { withTheme } from 'react-native-paper'; import { withTheme } from 'react-native-paper';
import { Icon, IconVolumeEmpty } from '../../../base/icons'; import { Icon, IconVolumeEmpty } from '../../../base/icons';
import { getParticipantByIdOrUndefined } from '../../../base/participants'; import { getLocalParticipant } from '../../../base/participants';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { setVolume } from '../../../participants-pane/actions.native'; import { setVolume } from '../../../participants-pane/actions.native';
import { VOLUME_SLIDER_SCALE } from '../../constants'; import { VOLUME_SLIDER_SCALE } from '../../constants';
@ -19,11 +19,6 @@ import styles from './styles';
*/ */
type Props = { type Props = {
/**
* Participant reference
*/
_participant: Object,
/** /**
* Whether the participant enters the conference silent. * Whether the participant enters the conference silent.
*/ */
@ -131,10 +126,9 @@ class VolumeSlider extends PureComponent<Props, State> {
* @returns {void} * @returns {void}
*/ */
_onVolumeChange(volumeLevel) { _onVolumeChange(volumeLevel) {
const { dispatch, _participant } = this.props; const { dispatch, participantID } = this.props;
const { id } = _participant;
dispatch(setVolume(id, volumeLevel)); dispatch(setVolume(participantID, volumeLevel));
} }
} }
@ -148,15 +142,13 @@ class VolumeSlider extends PureComponent<Props, State> {
*/ */
function mapStateToProps(state, ownProps): Object { function mapStateToProps(state, ownProps): Object {
const { participantID } = ownProps; const { participantID } = ownProps;
const participant = getParticipantByIdOrUndefined(state, participantID);
const { id, local } = participant;
const { participantsVolume } = state['features/participants-pane']; const { participantsVolume } = state['features/participants-pane'];
const { startSilent } = state['features/base/config']; const { startSilent } = state['features/base/config'];
const localParticipant = getLocalParticipant(state);
return { return {
_participant: participant,
_startSilent: Boolean(startSilent), _startSilent: Boolean(startSilent),
_volume: local ? undefined : participantsVolume[id] _volume: localParticipant ? undefined : participantsVolume[participantID]
}; };
} }