feat(native-participants-pane) created meeting participant list
This commit is contained in:
parent
e7280e5040
commit
f49c05c666
|
@ -2,6 +2,7 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
|
@ -30,20 +31,22 @@ export const LobbyParticipantItem = ({ participant: p }: Props) => {
|
|||
audioMuteState = { MediaState.Muted }
|
||||
participant = { p }
|
||||
videoMuteState = { MediaState.ForceMuted }>
|
||||
<Button
|
||||
labelStyle = { styles.participantActionsButtonText }
|
||||
mode = 'contained'
|
||||
onPress = { admit }
|
||||
style = { styles.participantActionsButtonAdmit }>
|
||||
{t('lobby.admit')}
|
||||
</Button>
|
||||
<Button
|
||||
labelStyle = { styles.participantActionsButtonText }
|
||||
mode = 'contained'
|
||||
onPress = { reject }
|
||||
style = { styles.participantActionsButtonReject }>
|
||||
{t('lobby.reject')}
|
||||
</Button>
|
||||
<View style = { styles.lobbyParticipantItem }>
|
||||
<Button
|
||||
children = { t('lobby.admit') }
|
||||
contentStyle = { styles.participantActionsButtonContent }
|
||||
labelStyle = { styles.participantActionsButtonText }
|
||||
mode = 'contained'
|
||||
onPress = { admit }
|
||||
style = { styles.participantActionsButtonAdmit } />
|
||||
<Button
|
||||
children = { t('lobby.reject') }
|
||||
contentStyle = { styles.participantActionsButtonContent }
|
||||
labelStyle = { styles.participantActionsButtonText }
|
||||
mode = 'contained'
|
||||
onPress = { reject }
|
||||
style = { styles.participantActionsButtonReject } />
|
||||
</View>
|
||||
</ParticipantItem>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
getIsParticipantAudioMuted,
|
||||
getIsParticipantVideoMuted
|
||||
} from '../../../base/tracks';
|
||||
import { MediaState } from '../../constants';
|
||||
|
||||
import ParticipantItem from './ParticipantItem';
|
||||
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Participant reference
|
||||
*/
|
||||
participant: Object
|
||||
};
|
||||
|
||||
export const MeetingParticipantItem = ({ participant }: Props) => {
|
||||
const isAudioMuted = useSelector(getIsParticipantAudioMuted(participant));
|
||||
const isVideoMuted = useSelector(getIsParticipantVideoMuted(participant));
|
||||
|
||||
return (
|
||||
<ParticipantItem
|
||||
audioMuteState = { isAudioMuted ? MediaState.Muted : MediaState.Unmuted }
|
||||
participant = { participant }
|
||||
videoMuteState = { isVideoMuted ? MediaState.Muted : MediaState.Unmuted } />
|
||||
);
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
|
||||
import { Icon, IconInviteMore } from '../../../base/icons';
|
||||
|
||||
import { MeetingParticipantItem } from './MeetingParticipantItem';
|
||||
import { participants } from './participants';
|
||||
import styles from './styles';
|
||||
|
||||
export const MeetingParticipantList = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<View style = { styles.lobbyList }>
|
||||
<Text style = { styles.lobbyListDescription }>
|
||||
{t('participantsPane.headings.participantsList',
|
||||
{ count: participants.length })}
|
||||
</Text>
|
||||
<Button
|
||||
children = { t('participantsPane.actions.invite') }
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
icon = { () =>
|
||||
(<Icon
|
||||
size = { 24 }
|
||||
src = { IconInviteMore } />)
|
||||
}
|
||||
labelStyle = { styles.inviteLabel }
|
||||
mode = 'contained'
|
||||
style = { styles.inviteButton } />
|
||||
{ participants.map(p => (
|
||||
<MeetingParticipantItem
|
||||
key = { p.id }
|
||||
participant = { p } />)
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
|
@ -3,7 +3,8 @@
|
|||
import React from 'react';
|
||||
import type { Node } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { Text } from 'react-native-paper';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { Avatar } from '../../../base/avatar';
|
||||
|
@ -35,7 +36,7 @@ type Props = {
|
|||
/**
|
||||
* React children
|
||||
*/
|
||||
children: Node,
|
||||
children?: Node,
|
||||
|
||||
/**
|
||||
* Callback for when the mouse leaves this component
|
||||
|
@ -86,7 +87,7 @@ function ParticipantItem({
|
|||
<View style = { styles.participantStateAudio }>{AudioStateIcons[audioMuteState]}</View>
|
||||
</View>
|
||||
</View>
|
||||
{ p.local ? <Text style = { styles.participantActions }> { children } </Text> : null }
|
||||
{ children }
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { View } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { hideDialog } from '../../../base/dialog';
|
||||
|
@ -11,32 +11,20 @@ import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
|
|||
import { JitsiModal } from '../../../base/modal';
|
||||
|
||||
import { LobbyParticipantList } from './LobbyParticipantList';
|
||||
import { MeetingParticipantList } from './MeetingParticipantList';
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
/**
|
||||
* {@code ParticipantsPane}'s React {@code Component} prop types.
|
||||
*/
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* Theme used for styles.
|
||||
*/
|
||||
theme: Object
|
||||
}
|
||||
|
||||
/**
|
||||
* Participant pane.
|
||||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
function ParticipantsPane({ theme }: Props) {
|
||||
export function ParticipantsPane() {
|
||||
const dispatch = useDispatch();
|
||||
const closePane = useCallback(
|
||||
() => dispatch(hideDialog()),
|
||||
[ dispatch ]);
|
||||
const { t } = useTranslation();
|
||||
const { palette } = theme;
|
||||
|
||||
return (
|
||||
<JitsiModal
|
||||
|
@ -53,21 +41,17 @@ function ParticipantsPane({ theme }: Props) {
|
|||
}
|
||||
mode = 'contained'
|
||||
onPress = { closePane }
|
||||
style = { styles.closeButton }
|
||||
theme = {{
|
||||
colors: {
|
||||
primary: palette.action02
|
||||
}
|
||||
}} />
|
||||
style = { styles.closeButton } />
|
||||
</View>
|
||||
<LobbyParticipantList />
|
||||
<ScrollView>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList />
|
||||
</ScrollView>
|
||||
<View style = { styles.footer }>
|
||||
<Button
|
||||
color = { palette.text01 }
|
||||
contentStyle = { styles.muteAllContent }
|
||||
style = { styles.muteAllButton } >
|
||||
{ t('participantsPane.actions.muteAll') }
|
||||
</Button>
|
||||
children = { t('participantsPane.actions.muteAll') }
|
||||
labelStyle = { styles.muteAllLabel }
|
||||
style = { styles.muteAllButton } />
|
||||
<Button
|
||||
contentStyle = { styles.moreIcon }
|
||||
/* eslint-disable-next-line react/jsx-no-bind */
|
||||
|
@ -77,16 +61,11 @@ function ParticipantsPane({ theme }: Props) {
|
|||
src = { IconHorizontalPoints } />)
|
||||
}
|
||||
mode = 'contained'
|
||||
style = { styles.moreButton }
|
||||
theme = {{
|
||||
colors: {
|
||||
primary: palette.action02
|
||||
}
|
||||
}} />
|
||||
style = { styles.moreButton } />
|
||||
</View>
|
||||
</JitsiModal>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default withTheme(ParticipantsPane);
|
||||
export default ParticipantsPane;
|
||||
|
|
|
@ -18,17 +18,6 @@ const flexContent = {
|
|||
flex: 1
|
||||
};
|
||||
|
||||
/**
|
||||
* The style of the participants pane buttons.
|
||||
*/
|
||||
const container = {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
paddingRight: 16,
|
||||
width: '100%'
|
||||
};
|
||||
|
||||
/**
|
||||
* The style of the participants pane buttons.
|
||||
*/
|
||||
|
@ -65,7 +54,8 @@ const buttonContent = {
|
|||
*/
|
||||
export default {
|
||||
|
||||
participantActions: {
|
||||
lobbyParticipantItem: {
|
||||
flexDirection: 'row',
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
zIndex: 1
|
||||
|
@ -110,7 +100,15 @@ export default {
|
|||
height: 32
|
||||
},
|
||||
|
||||
participantActionsButtonContent: {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
height: 32
|
||||
},
|
||||
|
||||
participantActionsButtonText: {
|
||||
color: BaseTheme.palette.text01,
|
||||
textTransform: 'capitalize'
|
||||
},
|
||||
|
||||
allParticipantActionsButton: {
|
||||
|
@ -134,7 +132,7 @@ export default {
|
|||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
width: '100%'
|
||||
},
|
||||
|
@ -144,7 +142,7 @@ export default {
|
|||
flexDirection: 'row',
|
||||
marginLeft: BaseTheme.spacing[2],
|
||||
overflow: 'hidden',
|
||||
width: 232
|
||||
width: '63%'
|
||||
},
|
||||
|
||||
participantName: {
|
||||
|
@ -162,7 +160,8 @@ export default {
|
|||
|
||||
participantStatesContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
marginLeft: 16
|
||||
},
|
||||
|
||||
participantStateAudio: {
|
||||
|
@ -170,7 +169,8 @@ export default {
|
|||
},
|
||||
|
||||
participantStateVideo: {
|
||||
...participantState
|
||||
...participantState,
|
||||
marginRight: 8
|
||||
},
|
||||
|
||||
raisedHandIndicator: {
|
||||
|
@ -187,33 +187,58 @@ export default {
|
|||
},
|
||||
lobbyList: {
|
||||
marginLeft: 16,
|
||||
marginRight: 16
|
||||
marginRight: 16,
|
||||
position: 'relative'
|
||||
},
|
||||
|
||||
lobbyListDetails: {
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
overflow: 'hidden',
|
||||
paddingBottom: 16,
|
||||
paddingTop: 16,
|
||||
position: 'relative',
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
lobbyListDescription: {
|
||||
color: BaseTheme.palette.text01,
|
||||
overflow: 'hidden',
|
||||
width: 188
|
||||
paddingBottom: 8,
|
||||
paddingTop: 8,
|
||||
position: 'relative',
|
||||
width: '55%'
|
||||
},
|
||||
|
||||
lobbyListActions: {
|
||||
flexDirection: 'row'
|
||||
flexDirection: 'row',
|
||||
left: 0
|
||||
},
|
||||
|
||||
header: {
|
||||
...container
|
||||
alignItems: 'center',
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
top: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: 88,
|
||||
paddingRight: 16,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
left: 0
|
||||
},
|
||||
|
||||
footer: {
|
||||
...container,
|
||||
marginTop: 'auto'
|
||||
alignItems: 'center',
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
bottom: 0,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: 88,
|
||||
paddingRight: 16,
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
left: 0
|
||||
},
|
||||
|
||||
closeButton: {
|
||||
|
@ -229,6 +254,15 @@ export default {
|
|||
...smallButton
|
||||
},
|
||||
|
||||
inviteButton: {
|
||||
backgroundColor: BaseTheme.palette.action01
|
||||
},
|
||||
|
||||
inviteLabel: {
|
||||
...BaseTheme.typography.labelButtonLarge,
|
||||
textTransform: 'capitalize'
|
||||
},
|
||||
|
||||
moreIcon: {
|
||||
...buttonContent,
|
||||
left: 8
|
||||
|
@ -239,7 +273,8 @@ export default {
|
|||
left: 80
|
||||
},
|
||||
|
||||
muteAllContent: {
|
||||
...buttonContent
|
||||
muteAllLabel: {
|
||||
color: BaseTheme.palette.text01,
|
||||
textTransform: 'capitalize'
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue