feat(native-participants-pane) removed mock data

This commit is contained in:
Calin Chitu 2021-06-09 18:35:58 +03:00 committed by Hristo Terezov
parent 05e6dde341
commit 14a5c45fa3
9 changed files with 103 additions and 71 deletions

View File

@ -39,7 +39,7 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
<Avatar <Avatar
className = 'participant-avatar' className = 'participant-avatar'
participantId = { p.id } participantId = { p.id }
size = { 24 } /> size = { 20 } />
<View style = { styles.contextMenuItemText }> <View style = { styles.contextMenuItemText }>
<Text style = { styles.contextMenuItemName }> <Text style = { styles.contextMenuItemName }>
{ displayName } { displayName }
@ -51,7 +51,7 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
onPress = { reject } onPress = { reject }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconClose } src = { IconClose }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }>{ t('lobby.reject') }</Text> <Text style = { styles.contextMenuItemText }>{ t('lobby.reject') }</Text>

View File

@ -81,7 +81,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
<Avatar <Avatar
className = 'participant-avatar' className = 'participant-avatar'
participantId = { p.id } participantId = { p.id }
size = { 24 } /> size = { 20 } />
<View style = { styles.contextMenuItemText }> <View style = { styles.contextMenuItemText }>
<Text style = { styles.contextMenuItemName }> <Text style = { styles.contextMenuItemName }>
{ displayName } { displayName }
@ -95,7 +95,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteAudio } onPress = { muteAudio }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconMicrophoneEmptySlash } src = { IconMicrophoneEmptySlash }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }> <Text style = { styles.contextMenuItemText }>
@ -109,7 +109,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteEveryoneElse } onPress = { muteEveryoneElse }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconMuteEveryoneElse } src = { IconMuteEveryoneElse }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }> <Text style = { styles.contextMenuItemText }>
@ -125,7 +125,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteVideo } onPress = { muteVideo }
style = { styles.contextMenuItemSection }> style = { styles.contextMenuItemSection }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconVideoOff } src = { IconVideoOff }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }> <Text style = { styles.contextMenuItemText }>
@ -140,7 +140,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { kickRemoteParticipant } onPress = { kickRemoteParticipant }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconCloseCircle } src = { IconCloseCircle }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }> <Text style = { styles.contextMenuItemText }>
@ -152,7 +152,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { sendPrivateMessage } onPress = { sendPrivateMessage }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconMessage } src = { IconMessage }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }> <Text style = { styles.contextMenuItemText }>
@ -162,7 +162,7 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
<TouchableOpacity <TouchableOpacity
style = { styles.contextMenuItemSection }> style = { styles.contextMenuItemSection }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconConnectionActive } src = { IconConnectionActive }
style = { styles.contextMenuItemIcon } /> style = { styles.contextMenuItemIcon } />
<Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text> <Text style = { styles.contextMenuItemText }>{ t('participantsPane.actions.networkStats') }</Text>

View File

@ -45,14 +45,14 @@ export const ContextMenuMore = ({ exclude }: Props) => {
onPress = { muteEveryoneVideo } onPress = { muteEveryoneVideo }
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconVideoOff } /> src = { IconVideoOff } />
<Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.stopEveryonesVideo')}</Text> <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.stopEveryonesVideo')}</Text>
</TouchableOpacity> </TouchableOpacity>
<TouchableOpacity <TouchableOpacity
style = { styles.contextMenuItem }> style = { styles.contextMenuItem }>
<Icon <Icon
size = { 24 } size = { 20 }
src = { IconMicDisabledHollow } src = { IconMicDisabledHollow }
style = { styles.contextMenuIcon } /> style = { styles.contextMenuIcon } />
<Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.dontAllowUnmute')}</Text> <Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.dontAllowUnmute')}</Text>

View File

@ -4,19 +4,30 @@ import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
import { Button } from 'react-native-paper'; import { Button } from 'react-native-paper';
import { useDispatch } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { getLobbyState } from '../../../lobby/functions';
import { admitAllKnockingParticipants } from '../../../video-menu/actions.any'; import { admitAllKnockingParticipants } from '../../../video-menu/actions.any';
import { LobbyParticipantItem } from './LobbyParticipantItem'; import { LobbyParticipantItem } from './LobbyParticipantItem';
import { participants } from './participants';
import styles from './styles'; import styles from './styles';
export const LobbyParticipantList = () => { export const LobbyParticipantList = () => {
const {
lobbyEnabled,
knockingParticipants: participants
} = useSelector(getLobbyState);
const dispatch = useDispatch(); const dispatch = useDispatch();
const admitAll = useCallback(() => dispatch(admitAllKnockingParticipants()), [ dispatch ]); const admitAll = useCallback(() =>
dispatch(admitAllKnockingParticipants(participants, lobbyEnabled)),
[ dispatch ]);
const { t } = useTranslation(); const { t } = useTranslation();
if (!lobbyEnabled || !participants.length) {
return null;
}
return ( return (
<View style = { styles.lobbyList }> <View style = { styles.lobbyList }>
<View style = { styles.lobbyListDetails } > <View style = { styles.lobbyListDetails } >
@ -33,11 +44,13 @@ export const LobbyParticipantList = () => {
{t('lobby.admitAll')} {t('lobby.admitAll')}
</Button> </Button>
</View> </View>
{ participants.map(p => ( {
<LobbyParticipantItem participants.map(p => (
key = { p.id } <LobbyParticipantItem
participant = { p } />) key = { p.id }
)} participant = { p } />)
)
}
</View> </View>
); );
}; };

View File

@ -4,22 +4,23 @@ import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
import { Button } from 'react-native-paper'; import { Button } from 'react-native-paper';
import { useDispatch } from 'react-redux'; import { useDispatch, useSelector, useStore } from 'react-redux';
import { createToolbarEvent, sendAnalytics } from '../../../analytics';
import { Icon, IconInviteMore } from '../../../base/icons'; import { Icon, IconInviteMore } from '../../../base/icons';
import { getParticipants } from '../../../base/participants';
import { doInvitePeople } from '../../../invite/actions.native'; import { doInvitePeople } from '../../../invite/actions.native';
import { shouldRenderInviteButton } from '../../functions';
import { MeetingParticipantItem } from './MeetingParticipantItem'; import { MeetingParticipantItem } from './MeetingParticipantItem';
import { participants } from './participants';
import styles from './styles'; import styles from './styles';
export const MeetingParticipantList = () => { export const MeetingParticipantList = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const onInvite = useCallback(() => { const onInvite = useCallback(() => dispatch(doInvitePeople()), [ dispatch ]);
sendAnalytics(createToolbarEvent('invite')); const showInviteButton = useSelector(shouldRenderInviteButton);
dispatch(doInvitePeople()); const store = useStore();
}, [ dispatch ]); const state = store.getState();
const participants = getParticipants(state);
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
@ -28,23 +29,28 @@ export const MeetingParticipantList = () => {
{t('participantsPane.headings.participantsList', {t('participantsPane.headings.participantsList',
{ count: participants.length })} { count: participants.length })}
</Text> </Text>
<Button {
children = { t('participantsPane.actions.invite') } showInviteButton
/* eslint-disable-next-line react/jsx-no-bind */ && <Button
icon = { () => children = { t('participantsPane.actions.invite') }
(<Icon /* eslint-disable-next-line react/jsx-no-bind */
size = { 24 } icon = { () =>
src = { IconInviteMore } />) (<Icon
} size = { 24 }
labelStyle = { styles.inviteLabel } src = { IconInviteMore } />)
mode = 'contained' }
onPress = { onInvite } labelStyle = { styles.inviteLabel }
style = { styles.inviteButton } /> mode = 'contained'
{ participants.map(p => ( onPress = { onInvite }
<MeetingParticipantItem style = { styles.inviteButton } />
key = { p.id } }
participant = { p } />) {
)} participants.map(p => (
<MeetingParticipantItem
key = { p.id }
participant = { p } />)
)
}
</View> </View>
); );
}; };

View File

@ -67,12 +67,12 @@ type Props = {
* @returns {React$Element<any>} * @returns {React$Element<any>}
*/ */
function ParticipantItem({ function ParticipantItem({
audioMuteState = MediaState.None,
children, children,
isKnockingParticipant, isKnockingParticipant,
name, name,
onPress, onPress,
participant: p, participant: p,
audioMuteState = MediaState.None,
videoMuteState = MediaState.None videoMuteState = MediaState.None
}: Props) { }: Props) {
@ -96,8 +96,11 @@ function ParticipantItem({
{ p.local ? <Text style = { styles.isLocal }>({t('chat.you')})</Text> : null } { p.local ? <Text style = { styles.isLocal }>({t('chat.you')})</Text> : null }
</View> </View>
{ {
!isKnockingParticipant && <> !isKnockingParticipant
{p.raisedHand && <RaisedHandIndicator />} && <>
{
p.raisedHand && <RaisedHandIndicator />
}
<View style = { styles.participantStatesContainer }> <View style = { styles.participantStatesContainer }>
<View style = { styles.participantStateVideo }>{VideoStateIcons[videoMuteState]}</View> <View style = { styles.participantStateVideo }>{VideoStateIcons[videoMuteState]}</View>
<View>{AudioStateIcons[audioMuteState]}</View> <View>{AudioStateIcons[audioMuteState]}</View>
@ -105,7 +108,7 @@ function ParticipantItem({
</> </>
} }
</TouchableOpacity> </TouchableOpacity>
{ children } { !p.local && children }
</View> </View>
); );
} }

View File

@ -4,11 +4,12 @@ import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ScrollView, View } from 'react-native'; import { ScrollView, View } from 'react-native';
import { Button } from 'react-native-paper'; import { Button } from 'react-native-paper';
import { useDispatch } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { hideDialog, openDialog } from '../../../base/dialog'; import { hideDialog, openDialog } from '../../../base/dialog';
import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons'; import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
import { JitsiModal } from '../../../base/modal'; import { JitsiModal } from '../../../base/modal';
import { isLocalParticipantModerator } from '../../../base/participants';
import MuteEveryoneDialog import MuteEveryoneDialog
from '../../../video-menu/components/native/MuteEveryoneDialog'; from '../../../video-menu/components/native/MuteEveryoneDialog';
@ -24,8 +25,9 @@ import styles from './styles';
*/ */
export function ParticipantsPane() { export function ParticipantsPane() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore))); const openMoreMenu = useCallback(() => dispatch(openDialog(ContextMenuMore)), [ dispatch ]);
const closePane = useCallback(() => dispatch(hideDialog()), [ dispatch ]); const closePane = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const isLocalModerator = useSelector(isLocalParticipantModerator);
const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)), const muteAll = useCallback(() => dispatch(openDialog(MuteEveryoneDialog)),
[ dispatch ]); [ dispatch ]);
const { t } = useTranslation(); const { t } = useTranslation();
@ -51,26 +53,29 @@ export function ParticipantsPane() {
<LobbyParticipantList /> <LobbyParticipantList />
<MeetingParticipantList /> <MeetingParticipantList />
</ScrollView> </ScrollView>
<View style = { styles.footer }> {
<Button isLocalModerator
children = { t('participantsPane.actions.muteAll') } && <View style = { styles.footer }>
contentStyle = { styles.muteAllContent } <Button
labelStyle = { styles.muteAllLabel } children = { t('participantsPane.actions.muteAll') }
mode = 'contained' contentStyle = { styles.muteAllContent }
onPress = { muteAll } labelStyle = { styles.muteAllLabel }
style = { styles.muteAllButton } /> mode = 'contained'
<Button onPress = { muteAll }
contentStyle = { styles.moreIcon } style = { styles.muteAllButton } />
/* eslint-disable-next-line react/jsx-no-bind */ <Button
icon = { () => contentStyle = { styles.moreIcon }
(<Icon /* eslint-disable-next-line react/jsx-no-bind */
size = { 24 } icon = { () =>
src = { IconHorizontalPoints } />) (<Icon
} size = { 24 }
mode = 'contained' src = { IconHorizontalPoints } />)
onPress = { openMoreMenu } }
style = { styles.moreButton } /> mode = 'contained'
</View> onPress = { openMoreMenu }
style = { styles.moreButton } />
</View>
}
</JitsiModal> </JitsiModal>
); );
} }

View File

@ -5,8 +5,12 @@ import type { Dispatch } from 'redux';
import { openDialog } from '../../../base/dialog'; import { openDialog } from '../../../base/dialog';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n';
import { IconParticipants } from '../../../base/icons'; import { IconParticipants } from '../../../base/icons';
import { setActiveModalId } from '../../../base/modal';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components'; import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
import {
PARTICIPANTS_PANE_ID
} from '../../../invite/constants';
import { ParticipantsPane } from './'; import { ParticipantsPane } from './';
@ -35,6 +39,7 @@ class ParticipantsPaneButton extends AbstractButton<Props, *> {
*/ */
_handleClick() { _handleClick() {
this.props.dispatch(openDialog(ParticipantsPane)); this.props.dispatch(openDialog(ParticipantsPane));
this.props.dispatch(setActiveModalId(PARTICIPANTS_PANE_ID));
} }
} }

View File

@ -3,7 +3,7 @@
import { openDialog } from '../../../base/dialog'; import { openDialog } from '../../../base/dialog';
import { getFeatureFlag, OVERFLOW_MENU_ENABLED } from '../../../base/flags'; import { getFeatureFlag, OVERFLOW_MENU_ENABLED } from '../../../base/flags';
import { translate } from '../../../base/i18n'; import { translate } from '../../../base/i18n';
import { IconMenuThumb } from '../../../base/icons'; import { IconHorizontalPoints } from '../../../base/icons';
import { connect } from '../../../base/redux'; import { connect } from '../../../base/redux';
import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components'; import { AbstractButton, type AbstractButtonProps } from '../../../base/toolbox/components';
@ -25,7 +25,7 @@ type Props = AbstractButtonProps & {
*/ */
class OverflowMenuButton extends AbstractButton<Props, *> { class OverflowMenuButton extends AbstractButton<Props, *> {
accessibilityLabel = 'toolbar.accessibilityLabel.moreActions'; accessibilityLabel = 'toolbar.accessibilityLabel.moreActions';
icon = IconMenuThumb; icon = IconHorizontalPoints;
label = 'toolbar.moreActions'; label = 'toolbar.moreActions';
/** /**