feat(participants-pane) separated participants into collapsible lists
This commit is contained in:
parent
b1a2ac66b0
commit
73f3409f0d
|
@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
|
|||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoom } from '../../actions';
|
||||
import { createBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
import styles from './styles';
|
||||
|
|
@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
|
|||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { autoAssignToBreakoutRooms } from '../../actions';
|
||||
import { autoAssignToBreakoutRooms } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
import styles from './styles';
|
||||
|
|
@ -6,17 +6,17 @@ import { TouchableOpacity } from 'react-native';
|
|||
import { Text } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
|
||||
import { hideDialog } from '../../../base/dialog/actions';
|
||||
import BottomSheet from '../../../base/dialog/components/native/BottomSheet';
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
|
||||
import { hideDialog } from '../../../../../base/dialog/actions';
|
||||
import BottomSheet from '../../../../../base/dialog/components/native/BottomSheet';
|
||||
import {
|
||||
Icon,
|
||||
IconClose,
|
||||
IconRingGroup
|
||||
} from '../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import styles from '../../../participants-pane/components/native/styles';
|
||||
import { closeBreakoutRoom, moveToRoom, removeBreakoutRoom } from '../../actions';
|
||||
} from '../../../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../../../base/participants';
|
||||
import { closeBreakoutRoom, moveToRoom, removeBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||
import styles from '../../../native/styles';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { isParticipantModerator } from '../../../base/participants';
|
||||
import ParticipantItem from '../../../participants-pane/components/native/ParticipantItem';
|
||||
import { isParticipantModerator } from '../../../../../base/participants';
|
||||
import ParticipantItem from '../../../native/ParticipantItem';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FlatList, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { FlatList } from 'react-native';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { openDialog } from '../../../base/dialog';
|
||||
import { Icon, IconArrowDown, IconArrowUp } from '../../../base/icons';
|
||||
import { participantMatchesSearch } from '../../../participants-pane/functions';
|
||||
import { openDialog } from '../../../../../base/dialog';
|
||||
import { participantMatchesSearch } from '../../../../functions';
|
||||
import CollapsibleList from '../../../native/CollapsibleList';
|
||||
import styles from '../../../native/styles';
|
||||
|
||||
import BreakoutRoomContextMenu from './BreakoutRoomContextMenu';
|
||||
import BreakoutRoomParticipantItem from './BreakoutRoomParticipantItem';
|
||||
import styles from './styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
|
@ -39,33 +39,23 @@ function _keyExtractor(item: Object) {
|
|||
|
||||
export const CollapsibleRoom = ({ room, searchString }: Props) => {
|
||||
const dispatch = useDispatch();
|
||||
const [ collapsed, setCollapsed ] = useState(false);
|
||||
const { t } = useTranslation();
|
||||
const _toggleCollapsed = useCallback(() => {
|
||||
setCollapsed(!collapsed);
|
||||
}, [ collapsed ]);
|
||||
const _openContextMenu = useCallback(() => {
|
||||
dispatch(openDialog(BreakoutRoomContextMenu, { room }));
|
||||
}, [ room ]);
|
||||
const roomParticipantsNr = Object.values(room.participants || {}).length;
|
||||
const title
|
||||
= `${room.name
|
||||
|| t('breakoutRooms.mainRoom')} (${roomParticipantsNr})`;
|
||||
const containerStyle
|
||||
= roomParticipantsNr > 3 && styles.collapsibleRoomContainer;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<TouchableOpacity
|
||||
onLongPress = { _openContextMenu }
|
||||
onPress = { _toggleCollapsed }
|
||||
style = { styles.collapsibleRoom }>
|
||||
<TouchableOpacity
|
||||
onPress = { _toggleCollapsed }
|
||||
style = { styles.arrowIcon }>
|
||||
<Icon
|
||||
size = { 18 }
|
||||
src = { collapsed ? IconArrowDown : IconArrowUp } />
|
||||
</TouchableOpacity>
|
||||
<Text style = { styles.roomName }>
|
||||
{`${room.name || t('breakoutRooms.mainRoom')} (${Object.values(room.participants || {}).length})`}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{!collapsed && <FlatList
|
||||
<CollapsibleList
|
||||
containerStyle = { containerStyle }
|
||||
onLongPress = { _openContextMenu }
|
||||
title = { title }>
|
||||
<FlatList
|
||||
bounces = { false }
|
||||
data = { Object.values(room.participants || {}) }
|
||||
horizontal = { false }
|
||||
|
@ -73,8 +63,9 @@ export const CollapsibleRoom = ({ room, searchString }: Props) => {
|
|||
// eslint-disable-next-line react/jsx-no-bind
|
||||
renderItem = { ({ item: participant }) => participantMatchesSearch(participant, searchString)
|
||||
&& <BreakoutRoomParticipantItem item = { participant } /> }
|
||||
scrollEnabled = { true }
|
||||
showsHorizontalScrollIndicator = { false }
|
||||
windowSize = { 2 } />}
|
||||
</View>
|
||||
windowSize = { 2 } />
|
||||
</CollapsibleList>
|
||||
);
|
||||
};
|
|
@ -5,8 +5,8 @@ import { useTranslation } from 'react-i18next';
|
|||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
|
||||
import { moveToRoom } from '../../actions';
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
|
||||
import { moveToRoom } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
import styles from './styles';
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import BaseTheme from '../../../base/ui/components/BaseTheme.native';
|
||||
import BaseTheme from '../../../../../base/ui/components/BaseTheme';
|
||||
|
||||
const baseButton = {
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
|
@ -36,6 +36,16 @@ export default {
|
|||
alignItems: 'center'
|
||||
},
|
||||
|
||||
collapsibleList: {
|
||||
alignItems: 'center',
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
height: BaseTheme.spacing[7],
|
||||
marginHorizontal: BaseTheme.spacing[3],
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
arrowIcon: {
|
||||
backgroundColor: BaseTheme.palette.ui03,
|
||||
height: BaseTheme.spacing[5],
|
||||
|
@ -53,6 +63,13 @@ export default {
|
|||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
listTile: {
|
||||
fontSize: 15,
|
||||
color: BaseTheme.palette.text01,
|
||||
fontWeight: 'bold',
|
||||
marginLeft: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
transparentButton: {
|
||||
...baseButton,
|
||||
backgroundColor: 'transparent'
|
|
@ -5,8 +5,8 @@ import React, { useCallback } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import ParticipantPaneBaseButton from '../../../participants-pane/components/web/ParticipantPaneBaseButton';
|
||||
import { createBreakoutRoom } from '../../actions';
|
||||
import { createBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||
import ParticipantPaneBaseButton from '../../../web/ParticipantPaneBaseButton';
|
||||
|
||||
const useStyles = makeStyles(() => {
|
||||
return {
|
|
@ -5,8 +5,8 @@ import React, { useCallback } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import ParticipantPaneBaseButton from '../../../participants-pane/components/web/ParticipantPaneBaseButton';
|
||||
import { autoAssignToBreakoutRooms } from '../../actions';
|
||||
import { autoAssignToBreakoutRooms } from '../../../../../breakout-rooms/actions';
|
||||
import ParticipantPaneBaseButton from '../../../web/ParticipantPaneBaseButton';
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
return {
|
|
@ -6,11 +6,11 @@ import React, { useCallback, useState } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { ListItem } from '../../../base/components';
|
||||
import { Icon, IconArrowDown, IconArrowUp } from '../../../base/icons';
|
||||
import ParticipantItem from '../../../participants-pane/components/web/ParticipantItem';
|
||||
import { ACTION_TRIGGER } from '../../../participants-pane/constants';
|
||||
import { participantMatchesSearch } from '../../../participants-pane/functions';
|
||||
import { ListItem } from '../../../../../base/components';
|
||||
import { Icon, IconArrowDown, IconArrowUp } from '../../../../../base/icons';
|
||||
import { ACTION_TRIGGER } from '../../../../constants';
|
||||
import { participantMatchesSearch } from '../../../../functions';
|
||||
import ParticipantItem from '../../../web/ParticipantItem';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -5,9 +5,9 @@ import React, { useCallback } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
|
||||
import { QuickActionButton } from '../../../base/components';
|
||||
import { moveToRoom } from '../../actions';
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
|
||||
import { QuickActionButton } from '../../../../../base/components';
|
||||
import { moveToRoom } from '../../../../../breakout-rooms/actions';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -5,9 +5,9 @@ import React, { useCallback } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
|
||||
import ParticipantPaneBaseButton from '../../../participants-pane/components/web/ParticipantPaneBaseButton';
|
||||
import { moveToRoom } from '../../actions';
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
|
||||
import { moveToRoom } from '../../../../../breakout-rooms/actions';
|
||||
import ParticipantPaneBaseButton from '../../../web/ParticipantPaneBaseButton';
|
||||
|
||||
const useStyles = makeStyles(theme => {
|
||||
return {
|
|
@ -4,8 +4,8 @@ import { makeStyles } from '@material-ui/styles';
|
|||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { QuickActionButton } from '../../../base/components';
|
||||
import { Icon, IconHorizontalPoints } from '../../../base/icons';
|
||||
import { QuickActionButton } from '../../../../../base/components';
|
||||
import { Icon, IconHorizontalPoints } from '../../../../../base/icons';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -4,15 +4,15 @@ import React, { useCallback } from 'react';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../analytics';
|
||||
import { ContextMenu, ContextMenuItemGroup } from '../../../base/components';
|
||||
import { createBreakoutRoomsEvent, sendAnalytics } from '../../../../../analytics';
|
||||
import { ContextMenu, ContextMenuItemGroup } from '../../../../../base/components';
|
||||
import {
|
||||
IconClose,
|
||||
IconRingGroup
|
||||
} from '../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { showOverflowDrawer } from '../../../toolbox/functions.web';
|
||||
import { closeBreakoutRoom, moveToRoom, removeBreakoutRoom } from '../../actions';
|
||||
} from '../../../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../../../base/participants';
|
||||
import { closeBreakoutRoom, moveToRoom, removeBreakoutRoom } from '../../../../../breakout-rooms/actions';
|
||||
import { showOverflowDrawer } from '../../../../../toolbox/functions';
|
||||
|
||||
type Props = {
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import useContextMenu from '../../../base/components/context-menu/useContextMenu';
|
||||
import { getParticipantCount, isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { equals } from '../../../base/redux';
|
||||
import { showOverflowDrawer } from '../../../toolbox/functions.web';
|
||||
import { getBreakoutRooms, isInBreakoutRoom, getCurrentRoomId } from '../../functions';
|
||||
import useContextMenu from '../../../../../base/components/context-menu/useContextMenu';
|
||||
import { getParticipantCount, isLocalParticipantModerator } from '../../../../../base/participants';
|
||||
import { equals } from '../../../../../base/redux';
|
||||
import { getBreakoutRooms, isInBreakoutRoom, getCurrentRoomId } from '../../../../../breakout-rooms/functions';
|
||||
import { showOverflowDrawer } from '../../../../../toolbox/functions';
|
||||
|
||||
import { AutoAssignButton } from './AutoAssignButton';
|
||||
import { CollapsibleRoom } from './CollapsibleRoom';
|
|
@ -0,0 +1,65 @@
|
|||
// @flow
|
||||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
import { Icon, IconArrowDown, IconArrowUp } from '../../../base/icons';
|
||||
import { StyleType } from '../../../base/styles';
|
||||
import styles from '../breakout-rooms/components/native/styles';
|
||||
|
||||
type Props = {
|
||||
|
||||
/**
|
||||
* The children to be displayed within this list.
|
||||
*/
|
||||
children: React$Node,
|
||||
|
||||
/**
|
||||
* Additional style to be appended to the CollapsibleList container.
|
||||
*/
|
||||
containerStyle?: StyleType,
|
||||
|
||||
/**
|
||||
* Callback to invoke when the {@code CollapsibleList} is long pressed.
|
||||
*/
|
||||
onLongPress?: Function,
|
||||
|
||||
/**
|
||||
* Collapsable list title.
|
||||
*/
|
||||
title: Object
|
||||
}
|
||||
|
||||
const CollapsibleList = ({ children, containerStyle, onLongPress, title }: Props) => {
|
||||
const [ collapsed, setCollapsed ] = useState(true);
|
||||
const _toggleCollapsed = useCallback(() => {
|
||||
setCollapsed(!collapsed);
|
||||
}, [ collapsed ]);
|
||||
|
||||
return (
|
||||
<View style = { !collapsed && containerStyle }>
|
||||
<TouchableOpacity
|
||||
onLongPress = { onLongPress }
|
||||
onPress = { _toggleCollapsed }
|
||||
style = { styles.collapsibleList }>
|
||||
<TouchableOpacity
|
||||
onPress = { _toggleCollapsed }
|
||||
style = { styles.arrowIcon }>
|
||||
<Icon
|
||||
size = { 18 }
|
||||
src = { collapsed ? IconArrowDown : IconArrowUp } />
|
||||
</TouchableOpacity>
|
||||
<Text style = { styles.listTile }>
|
||||
{
|
||||
title
|
||||
}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
{
|
||||
!collapsed && children
|
||||
}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export default CollapsibleList;
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
import React, { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Text, View } from 'react-native';
|
||||
import { ScrollView, Text, View } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { admitMultiple } from '../../../lobby/actions.native';
|
||||
import { getKnockingParticipants, getLobbyEnabled } from '../../../lobby/functions';
|
||||
|
||||
import CollapsibleList from './CollapsibleList';
|
||||
import { LobbyParticipantItem } from './LobbyParticipantItem';
|
||||
import styles from './styles';
|
||||
|
||||
|
@ -34,36 +35,43 @@ const LobbyParticipantList = ({ theme }: Props) => {
|
|||
if (!lobbyEnabled || !participants.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View
|
||||
style = { styles.lobbyListContainer } >
|
||||
<View style = { styles.lobbyListDetails } >
|
||||
<Text style = { styles.lobbyListDescription }>
|
||||
{t('participantsPane.headings.waitingLobby',
|
||||
const title = (
|
||||
<View style = { styles.lobbyListDetails } >
|
||||
<Text style = { styles.lobbyListDescription }>
|
||||
{t('participantsPane.headings.waitingLobby',
|
||||
{ count: participants.length })}
|
||||
</Text>
|
||||
{
|
||||
participants.length > 1 && (
|
||||
<Button
|
||||
color = { palette.action02 }
|
||||
labelStyle = { styles.admitAllParticipantsActionButtonLabel }
|
||||
mode = 'text'
|
||||
onPress = { admitAll }>
|
||||
{t('lobby.admitAll')}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
</Text>
|
||||
{
|
||||
participants.map(p => (
|
||||
<LobbyParticipantItem
|
||||
key = { p.id }
|
||||
participant = { p } />)
|
||||
participants.length > 1 && (
|
||||
<Button
|
||||
color = { palette.action02 }
|
||||
labelStyle = { styles.admitAllParticipantsActionButtonLabel }
|
||||
mode = 'text'
|
||||
onPress = { admitAll }>
|
||||
{t('lobby.admitAll')}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
);
|
||||
const style = participants.length > 1 && styles.lobbyListContent;
|
||||
|
||||
return (
|
||||
<CollapsibleList
|
||||
title = { title }>
|
||||
<ScrollView
|
||||
bounces = { false }
|
||||
style = { style } >
|
||||
{
|
||||
participants.map(p => (
|
||||
<LobbyParticipantItem
|
||||
key = { p.id }
|
||||
participant = { p } />)
|
||||
)
|
||||
}
|
||||
</ScrollView>
|
||||
</CollapsibleList>
|
||||
);
|
||||
};
|
||||
|
||||
export default withTheme(LobbyParticipantList);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import React, { PureComponent } from 'react';
|
||||
import { FlatList, Text, View } from 'react-native';
|
||||
import { FlatList } from 'react-native';
|
||||
import { Button, withTheme } from 'react-native-paper';
|
||||
|
||||
import { translate } from '../../../base/i18n';
|
||||
|
@ -13,6 +13,7 @@ import { doInvitePeople } from '../../../invite/actions.native';
|
|||
import { participantMatchesSearch, shouldRenderInviteButton } from '../../functions';
|
||||
|
||||
import ClearableInput from './ClearableInput';
|
||||
import CollapsibleList from './CollapsibleList';
|
||||
import MeetingParticipantItem from './MeetingParticipantItem';
|
||||
import styles from './styles';
|
||||
|
||||
|
@ -181,17 +182,19 @@ class MeetingParticipantList extends PureComponent<Props> {
|
|||
_sortedRemoteParticipants,
|
||||
t
|
||||
} = this.props;
|
||||
const title = _currentRoom?.name
|
||||
|
||||
// $FlowExpectedError
|
||||
? `${_currentRoom.name} (${_participantsCount})`
|
||||
: t('participantsPane.headings.participantsList',
|
||||
{ count: _participantsCount });
|
||||
const containerStyle
|
||||
= _participantsCount > 3 && styles.meetingListContainer;
|
||||
|
||||
return (
|
||||
<View
|
||||
style = { styles.meetingListContainer }>
|
||||
<Text style = { styles.meetingListDescription }>
|
||||
{_currentRoom?.name
|
||||
|
||||
// $FlowExpectedError
|
||||
? `${_currentRoom.name} (${_participantsCount})`
|
||||
: t('participantsPane.headings.participantsList', { count: _participantsCount })}
|
||||
</Text>
|
||||
<CollapsibleList
|
||||
containerStyle = { containerStyle }
|
||||
title = { title } >
|
||||
{
|
||||
_showInviteButton
|
||||
&& <Button
|
||||
|
@ -212,11 +215,10 @@ class MeetingParticipantList extends PureComponent<Props> {
|
|||
horizontal = { false }
|
||||
keyExtractor = { this._keyExtractor }
|
||||
renderItem = { this._renderParticipant }
|
||||
scrollEnabled = { false }
|
||||
scrollEnabled = { true }
|
||||
showsHorizontalScrollIndicator = { false }
|
||||
style = { styles.meetingList }
|
||||
windowSize = { 2 } />
|
||||
</View>
|
||||
</CollapsibleList>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { Button } from 'react-native-paper';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
|
@ -13,15 +13,15 @@ import {
|
|||
isLocalParticipantModerator
|
||||
} from '../../../base/participants';
|
||||
import { equals } from '../../../base/redux';
|
||||
import { getBreakoutRooms, getCurrentRoomId, isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||
import MuteEveryoneDialog
|
||||
from '../../../video-menu/components/native/MuteEveryoneDialog';
|
||||
import {
|
||||
AddBreakoutRoomButton,
|
||||
AutoAssignButton,
|
||||
LeaveBreakoutRoomButton
|
||||
} from '../../../breakout-rooms/components/native';
|
||||
import { CollapsibleRoom } from '../../../breakout-rooms/components/native/CollapsibleRoom';
|
||||
import { getBreakoutRooms, getCurrentRoomId, isInBreakoutRoom } from '../../../breakout-rooms/functions';
|
||||
import MuteEveryoneDialog
|
||||
from '../../../video-menu/components/native/MuteEveryoneDialog';
|
||||
} from '../breakout-rooms/components/native';
|
||||
import { CollapsibleRoom } from '../breakout-rooms/components/native/CollapsibleRoom';
|
||||
|
||||
import { ContextMenuMore } from './ContextMenuMore';
|
||||
import HorizontalDotsIcon from './HorizontalDotsIcon';
|
||||
|
@ -54,32 +54,36 @@ const ParticipantsPane = () => {
|
|||
.sort((p1: Object, p2: Object) => (p1?.name || '').localeCompare(p2?.name || ''));
|
||||
const inBreakoutRoom = useSelector(isInBreakoutRoom);
|
||||
const participantsCount = useSelector(getParticipantCount);
|
||||
const autoAssign = !inBreakoutRoom && isLocalModerator
|
||||
&& participantsCount > 2 && rooms.length > 1;
|
||||
const addBreakoutRoom
|
||||
= _isBreakoutRoomsSupported && !hideAddRoomButton && isLocalModerator;
|
||||
|
||||
return (
|
||||
<JitsiScreen
|
||||
style = { styles.participantsPane }>
|
||||
<ScrollView bounces = { false }>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList
|
||||
searchString = { searchString }
|
||||
setSearchString = { setSearchString } />
|
||||
{!inBreakoutRoom
|
||||
&& isLocalModerator
|
||||
&& participantsCount > 2
|
||||
&& rooms.length > 1
|
||||
&& <AutoAssignButton />}
|
||||
{inBreakoutRoom && <LeaveBreakoutRoomButton />}
|
||||
{_isBreakoutRoomsSupported
|
||||
&& rooms.map(room => (<CollapsibleRoom
|
||||
key = { room.id }
|
||||
room = { room }
|
||||
searchString = { searchString } />))}
|
||||
{_isBreakoutRoomsSupported && !hideAddRoomButton && isLocalModerator
|
||||
&& <AddBreakoutRoomButton />}
|
||||
</ScrollView>
|
||||
<JitsiScreen style = { styles.participantsPaneContainer }>
|
||||
<LobbyParticipantList />
|
||||
<MeetingParticipantList
|
||||
searchString = { searchString }
|
||||
setSearchString = { setSearchString } />
|
||||
{
|
||||
autoAssign && <AutoAssignButton />
|
||||
}
|
||||
{
|
||||
inBreakoutRoom && <LeaveBreakoutRoomButton />
|
||||
}
|
||||
{
|
||||
_isBreakoutRoomsSupported
|
||||
&& rooms.map(room => (<CollapsibleRoom
|
||||
key = { room.id }
|
||||
room = { room }
|
||||
searchString = { searchString } />))
|
||||
}
|
||||
{
|
||||
addBreakoutRoom && <AddBreakoutRoomButton />
|
||||
}
|
||||
{
|
||||
isLocalModerator
|
||||
&& <View style = { styles.footer }>
|
||||
&& <View style = { styles.participantsPaneFooter }>
|
||||
<Button
|
||||
children = { t('participantsPane.actions.muteAll') }
|
||||
labelStyle = { styles.muteAllLabel }
|
||||
|
|
|
@ -113,7 +113,9 @@ export default {
|
|||
admitAllParticipantsActionButtonLabel: {
|
||||
...BaseTheme.typography.heading6,
|
||||
color: BaseTheme.palette.link01,
|
||||
textTransform: 'capitalize'
|
||||
textTransform: 'capitalize',
|
||||
marginRight: BaseTheme.spacing[5],
|
||||
marginTop: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
participantContainer: {
|
||||
|
@ -167,12 +169,6 @@ export default {
|
|||
paddingTop: BaseTheme.spacing[1]
|
||||
},
|
||||
|
||||
participantsPane: {
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
flex: 1,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
participantStatesContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
|
@ -199,12 +195,15 @@ export default {
|
|||
color: BaseTheme.palette.uiBackground
|
||||
},
|
||||
|
||||
lobbyListContainer: {
|
||||
position: 'relative'
|
||||
lobbyListContent: {
|
||||
height: '20%'
|
||||
},
|
||||
|
||||
lobbyListDescription: {
|
||||
...participantListDescription
|
||||
fontSize: 15,
|
||||
color: BaseTheme.palette.text01,
|
||||
fontWeight: 'bold',
|
||||
marginTop: BaseTheme.spacing[2]
|
||||
},
|
||||
|
||||
lobbyListDetails: {
|
||||
|
@ -213,13 +212,12 @@ export default {
|
|||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
overflow: 'hidden',
|
||||
paddingLeft: BaseTheme.spacing[3],
|
||||
position: 'relative',
|
||||
width: '100%'
|
||||
},
|
||||
|
||||
meetingListContainer: {
|
||||
flex: 1
|
||||
height: '60%'
|
||||
},
|
||||
|
||||
meetingListDescription: {
|
||||
|
@ -227,11 +225,28 @@ export default {
|
|||
marginLeft: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
footer: {
|
||||
collapsibleRoomContainer: {
|
||||
height: '30%'
|
||||
},
|
||||
|
||||
participantsPaneContainer: {
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
flex: 1,
|
||||
justifyContent: 'center'
|
||||
},
|
||||
|
||||
participantsPaneFooter: {
|
||||
alignItems: 'center',
|
||||
backgroundColor: BaseTheme.palette.ui01,
|
||||
bottom: 0,
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: BaseTheme.spacing[3],
|
||||
paddingVertical: BaseTheme.spacing[2]
|
||||
height: BaseTheme.spacing[12],
|
||||
left: 0,
|
||||
right: 0,
|
||||
position: 'absolute',
|
||||
paddingBottom: BaseTheme.spacing[2],
|
||||
paddingLeft: BaseTheme.spacing[3],
|
||||
paddingRight: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
headerCloseIcon: {
|
||||
|
@ -242,9 +257,9 @@ export default {
|
|||
backgroundColor: BaseTheme.palette.action01,
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
height: BaseTheme.spacing[7],
|
||||
marginBottom: BaseTheme.spacing[4],
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
marginRight: BaseTheme.spacing[3]
|
||||
marginRight: BaseTheme.spacing[3],
|
||||
marginVertical: BaseTheme.spacing[3]
|
||||
},
|
||||
|
||||
inviteLabel: {
|
||||
|
@ -335,7 +350,8 @@ export default {
|
|||
backgroundColor: BaseTheme.palette.uiBackground,
|
||||
borderRadius: BaseTheme.shape.borderRadius,
|
||||
marginLeft: BaseTheme.spacing[3],
|
||||
marginRight: BaseTheme.spacing[3]
|
||||
marginRight: BaseTheme.spacing[3],
|
||||
marginBottom: BaseTheme.spacing[4]
|
||||
},
|
||||
|
||||
clearableInputFocus: {
|
||||
|
|
|
@ -9,11 +9,11 @@ import { translate } from '../../../base/i18n';
|
|||
import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
|
||||
import { isLocalParticipantModerator } from '../../../base/participants';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { AddBreakoutRoomButton } from '../../../breakout-rooms/components/web/AddBreakoutRoomButton';
|
||||
import { RoomList } from '../../../breakout-rooms/components/web/RoomList';
|
||||
import { MuteEveryoneDialog } from '../../../video-menu/components/';
|
||||
import { close } from '../../actions';
|
||||
import { classList, findAncestorByClass, getParticipantsPaneOpen } from '../../functions';
|
||||
import { AddBreakoutRoomButton } from '../breakout-rooms/components/web/AddBreakoutRoomButton';
|
||||
import { RoomList } from '../breakout-rooms/components/web/RoomList';
|
||||
|
||||
import FooterButton from './FooterButton';
|
||||
import { FooterContextMenu } from './FooterContextMenu';
|
||||
|
|
Loading…
Reference in New Issue