feat(native-participants-pane) implemented review remarks pt.4

This commit is contained in:
Calin Chitu 2021-07-06 22:07:52 +03:00 committed by Hristo Terezov
parent eeddf6b350
commit b7389e1c31
9 changed files with 70 additions and 59 deletions

View File

@ -9,3 +9,16 @@
export function getLobbyState(state: any) {
return state['features/lobby'];
}
/**
* Selector to return lobby state.
*
* @param {any} state - State object.
* @returns {Array}
*/
export function getKnockingParticipantsById(state: any) {
const { knockingParticipants } = state['features/lobby'];
return knockingParticipants.map(participant => participant.id);
}

View File

@ -4,7 +4,7 @@ import React, { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { TouchableOpacity, View } from 'react-native';
import { Divider, Text } from 'react-native-paper';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { Avatar } from '../../../base/avatar';
import { hideDialog } from '../../../base/dialog';
@ -13,6 +13,7 @@ import {
Icon, IconClose
} from '../../../base/icons';
import { setKnockingParticipantApproval } from '../../../lobby/actions.native';
import { getKnockingParticipantsById } from '../../../lobby/functions';
import styles from './styles';
type Props = {
@ -25,6 +26,8 @@ type Props = {
export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) => {
const dispatch = useDispatch();
const knockParticipantsIDArr = useSelector(getKnockingParticipantsById);
const knockParticipantIsAvailable = knockParticipantsIDArr.find(knockPartId => knockPartId === p.id);
const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const displayName = p.name;
const reject = useCallback(() => dispatch(setKnockingParticipantApproval(p.id, false), [ dispatch ]));
@ -32,14 +35,16 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
return (
<BottomSheet
addScrollViewPadding = { false }
onCancel = { cancel }
showSlidingView = { Boolean(knockParticipantIsAvailable) }
style = { styles.contextMenuMore }>
<View
style = { styles.contextMenuItemSectionAvatar }>
<Avatar
className = 'participant-avatar'
participantId = { p.id }
size = { 30 } />
size = { 20 } />
<View style = { styles.contextMenuItemAvatarText }>
<Text style = { styles.contextMenuItemName }>
{ displayName }
@ -51,9 +56,8 @@ export const ContextMenuLobbyParticipantReject = ({ participant: p }: Props) =>
onPress = { reject }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
src = { IconClose }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconClose } />
<Text style = { styles.contextMenuItemText }>{ t('lobby.reject') }</Text>
</TouchableOpacity>
</BottomSheet>

View File

@ -15,6 +15,7 @@ import {
IconMuteEveryoneElse, IconVideoOff
} from '../../../base/icons';
import {
getParticipantsById,
isLocalParticipantModerator
} from '../../../base/participants';
import { getIsParticipantVideoMuted } from '../../../base/tracks';
@ -39,11 +40,12 @@ type Props = {
export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props) => {
const dispatch = useDispatch();
const participantsIDArr = useSelector(getParticipantsById);
const participantIsAvailable = participantsIDArr.find(partId => partId === p.id);
const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const displayName = p.name;
const isLocalModerator = useSelector(isLocalParticipantModerator);
const isParticipantVideoMuted = useSelector(getIsParticipantVideoMuted(p));
const kickRemoteParticipant = useCallback(() => {
dispatch(openDialog(KickRemoteParticipantDialog, {
participantID: p.id
@ -73,14 +75,16 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
return (
<BottomSheet
addScrollViewPadding = { false }
onCancel = { cancel }
showSlidingView = { Boolean(participantIsAvailable) }
style = { styles.contextMenuMeetingParticipantDetails }>
<View
style = { styles.contextMenuItemSectionAvatar }>
<Avatar
className = 'participant-avatar'
participantId = { p.id }
size = { 30 } />
size = { 20 } />
<View style = { styles.contextMenuItemAvatarText }>
<Text style = { styles.contextMenuItemName }>
{ displayName }
@ -94,9 +98,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteAudio }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
src = { IconMicrophoneEmptySlash }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconMicrophoneEmptySlash } />
<Text style = { styles.contextMenuItemText }>
{ t('participantsPane.actions.mute') }
</Text>
@ -108,9 +111,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteEveryoneElse }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
src = { IconMuteEveryoneElse }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconMuteEveryoneElse } />
<Text style = { styles.contextMenuItemText }>
{ t('participantsPane.actions.muteEveryoneElse') }
</Text>
@ -124,9 +126,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { muteVideo }
style = { styles.contextMenuItemSection }>
<Icon
size = { 24 }
src = { IconVideoOff }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconVideoOff } />
<Text style = { styles.contextMenuItemText }>
{ t('participantsPane.actions.stopVideo') }
</Text>
@ -139,9 +140,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { kickRemoteParticipant }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
src = { IconCloseCircle }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconCloseCircle } />
<Text style = { styles.contextMenuItemText }>
{ t('videothumbnail.kick') }
</Text>
@ -151,9 +151,8 @@ export const ContextMenuMeetingParticipantDetails = ({ participant: p }: Props)
onPress = { sendPrivateMessage }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
src = { IconMessage }
style = { styles.contextMenuItemIcon } />
size = { 20 }
src = { IconMessage } />
<Text style = { styles.contextMenuItemText }>
{ t('toolbar.accessibilityLabel.privateMessage') }
</Text>

View File

@ -12,7 +12,10 @@ import {
Icon, IconMicDisabledHollow,
IconVideoOff
} from '../../../base/icons';
import { getLocalParticipant } from '../../../base/participants';
import {
getLocalParticipant,
getParticipantCount, isEveryoneModerator
} from '../../../base/participants';
import { BlockAudioVideoDialog } from '../../../video-menu';
import MuteEveryonesVideoDialog
from '../../../video-menu/components/native/MuteEveryonesVideoDialog';
@ -24,6 +27,9 @@ export const ContextMenuMore = () => {
const blockAudioVideo = useCallback(() => dispatch(openDialog(BlockAudioVideoDialog)), [ dispatch ]);
const cancel = useCallback(() => dispatch(hideDialog()), [ dispatch ]);
const { id } = useSelector(getLocalParticipant);
const everyoneModerator = useSelector(isEveryoneModerator);
const participantsCount = useSelector(getParticipantCount);
const showSlidingView = !everyoneModerator && participantsCount > 2;
const muteAllVideo = useCallback(() =>
dispatch(openDialog(MuteEveryonesVideoDialog,
{ exclude: [ id ] })),
@ -32,13 +38,15 @@ export const ContextMenuMore = () => {
return (
<BottomSheet
addScrollViewPadding = { false }
onCancel = { cancel }
showSlidingView = { showSlidingView }
style = { styles.contextMenuMore }>
<TouchableOpacity
onPress = { muteAllVideo }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
size = { 20 }
src = { IconVideoOff } />
<Text style = { styles.contextMenuItemText }>{t('participantsPane.actions.stopEveryonesVideo')}</Text>
</TouchableOpacity>
@ -46,7 +54,7 @@ export const ContextMenuMore = () => {
onPress = { blockAudioVideo }
style = { styles.contextMenuItem }>
<Icon
size = { 24 }
size = { 20 }
src = { IconMicDisabledHollow }
style = { styles.contextMenuIcon } />
<Text style = { styles.contextMenuItemText }>

View File

@ -34,7 +34,7 @@ export const MeetingParticipantList = () => {
/* eslint-disable-next-line react/jsx-no-bind */
icon = { () =>
(<Icon
size = { 24 }
size = { 20 }
src = { IconInviteMore } />)
}
labelStyle = { styles.inviteLabel }

View File

@ -49,7 +49,7 @@ const ParticipantsPane = () => {
/* eslint-disable-next-line react/jsx-no-bind */
icon = { () =>
(<Icon
size = { 24 }
size = { 20 }
src = { IconClose } />)
}
labelStyle = { styles.closeIcon }
@ -76,7 +76,7 @@ const ParticipantsPane = () => {
/* eslint-disable-next-line react/jsx-no-bind */
icon = { () =>
(<Icon
size = { 24 }
size = { 20 }
src = { IconHorizontalPoints } />)
}
labelStyle = { styles.moreIcon }

View File

@ -37,6 +37,8 @@ export const button = {
backgroundColor: BaseTheme.palette.action02,
borderRadius: BaseTheme.shape.borderRadius,
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
minWidth: 0
};
@ -62,8 +64,9 @@ const muteAllButton = {
*/
const buttonContent = {
...BaseTheme.typography.labelButton,
alignSelf: 'center',
alignContent: 'center',
color: BaseTheme.palette.text01,
display: 'flex',
justifyContent: 'center'
};
@ -71,9 +74,12 @@ const buttonContent = {
* The style of the context menu pane items.
*/
const contextMenuItem = {
alignItems: 'center',
display: 'flex',
flexDirection: 'row',
paddingBottom: 16,
paddingTop: 16
height: BaseTheme.spacing[7],
marginLeft: BaseTheme.spacing[3],
marginTop: BaseTheme.spacing[2]
};
/**
@ -173,7 +179,7 @@ export default {
backgroundColor: BaseTheme.palette.warning02,
borderRadius: BaseTheme.shape.borderRadius / 2,
height: BaseTheme.spacing[4],
marginLeft: BaseTheme.spacing[1],
marginLeft: BaseTheme.spacing[2],
width: BaseTheme.spacing[4]
},
@ -245,11 +251,7 @@ export default {
closeIcon: {
...buttonContent,
height: BaseTheme.spacing[5],
marginLeft: 'auto',
paddingTop: 12,
paddingBottom: 12,
paddingRight: BaseTheme.spacing[3],
paddingLeft: BaseTheme.spacing[3]
marginLeft: 'auto'
},
inviteButton: {
@ -271,11 +273,7 @@ export default {
moreIcon: {
...buttonContent,
height: BaseTheme.spacing[5],
marginLeft: 'auto',
paddingTop: 12,
paddingBottom: 12,
paddingRight: BaseTheme.spacing[3],
paddingLeft: BaseTheme.spacing[3]
marginLeft: 'auto'
},
contextMenuMore: {
@ -300,7 +298,6 @@ export default {
muteAllLabel: {
...BaseTheme.typography.labelButtonLarge,
color: BaseTheme.palette.text01,
flexDirection: 'column',
height: BaseTheme.spacing[7],
marginVertical: BaseTheme.spacing[0],
marginHorizontal: BaseTheme.spacing[0],
@ -322,12 +319,12 @@ export default {
contextMenuItemSectionAvatar: {
...contextMenuItem,
marginLeft: BaseTheme.spacing[1]
marginLeft: BaseTheme.spacing[3]
},
contextMenuItemAvatarText: {
...contextMenuItemText,
marginLeft: BaseTheme.spacing[2]
marginLeft: BaseTheme.spacing[3]
},
contextMenuItemText: {
@ -335,10 +332,6 @@ export default {
marginLeft: BaseTheme.spacing[3]
},
contextMenuItemIcon: {
marginLeft: BaseTheme.spacing[1]
},
contextMenuItemName: {
...BaseTheme.typography.bodyShortRegularLarge,
color: BaseTheme.palette.text01

View File

@ -101,9 +101,8 @@ class VolumeSlider extends PureComponent<Props, State> {
return (
<View style = { styles.volumeSliderContainer } >
<Icon
size = { 24 }
src = { IconVolumeEmpty }
style = { styles.volumeIcon } />
size = { 20 }
src = { IconVolumeEmpty } />
<Slider
maximumTrackTintColor = { palette.field02 }
maximumValue = { VOLUME_SLIDER_SCALE }

View File

@ -54,17 +54,12 @@ export default createStyleSheet({
volumeSliderContainer: {
alignItems: 'center',
flexDirection: 'row',
marginBottom: BaseTheme.spacing[3],
marginLeft: BaseTheme.spacing[3],
marginTop: BaseTheme.spacing[3]
},
volumeIcon: {
marginLeft: BaseTheme.spacing[1],
minWidth: '5%'
},
sliderContainer: {
marginLeft: BaseTheme.spacing[3],
minWidth: '90%'
minWidth: '84%'
}
});