jiti-meet/react/features/participants-pane/components/web/MeetingParticipants.js

170 lines
6.9 KiB
JavaScript
Raw Normal View History

// @flow
import { makeStyles } from '@material-ui/styles';
import React, { useCallback, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import { rejectParticipantAudio } from '../../../av-moderation/actions';
import useContextMenu from '../../../base/components/context-menu/useContextMenu';
import participantsPaneTheme from '../../../base/components/themes/participantsPaneTheme.json';
import { isToolbarButtonEnabled } from '../../../base/config/functions.web';
import { MEDIA_TYPE } from '../../../base/media';
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
import {
getParticipantCountWithFake
} from '../../../base/participants';
import { connect } from '../../../base/redux';
import { normalizeAccents } from '../../../base/util/strings';
import { getBreakoutRooms, getCurrentRoomId } from '../../../breakout-rooms/functions';
import { showOverflowDrawer } from '../../../toolbox/functions';
import { muteRemote } from '../../../video-menu/actions.any';
import { getSortedParticipantIds, shouldRenderInviteButton } from '../../functions';
import { useParticipantDrawer } from '../../hooks';
import ClearableInput from './ClearableInput';
import { InviteButton } from './InviteButton';
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
import MeetingParticipantContextMenu from './MeetingParticipantContextMenu';
import MeetingParticipantItems from './MeetingParticipantItems';
const useStyles = makeStyles(theme => {
return {
heading: {
color: theme.palette.text02,
...theme.typography.labelButton,
lineHeight: `${theme.typography.labelButton.lineHeight}px`,
margin: `8px 0 ${participantsPaneTheme.panePadding}px`,
[`@media(max-width: ${participantsPaneTheme.MD_BREAKPOINT})`]: {
...theme.typography.labelButtonLarge,
lineHeight: `${theme.typography.labelButtonLarge.lineHeight}px`
}
}
};
});
type Props = {
currentRoom: ?Object,
2021-11-04 21:10:43 +00:00
participantsCount: number,
showInviteButton: boolean,
overflowDrawer: boolean,
sortedParticipantIds: Array<string>
};
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
/**
* Renders the MeetingParticipantList component.
* NOTE: This component is not using useSelector on purpose. The child components MeetingParticipantItem
* and MeetingParticipantContextMenu are using connect. Having those mixed leads to problems.
* When this one was using useSelector and the other two were not -the other two were re-rendered before this one was
* re-rendered, so when participant is leaving, we first re-render the item and menu components,
* throwing errors (closing the page) before removing those components for the participant that left.
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
*
* @returns {ReactNode} - The component.
*/
function MeetingParticipants({
currentRoom,
overflowDrawer,
participantsCount,
showInviteButton,
sortedParticipantIds = []
}: Props) {
const dispatch = useDispatch();
const [ searchString, setSearchString ] = useState('');
const { t } = useTranslation();
const [ lowerMenu, , toggleMenu, menuEnter, menuLeave, raiseContext ] = useContextMenu();
const muteAudio = useCallback(id => () => {
dispatch(muteRemote(id, MEDIA_TYPE.AUDIO));
dispatch(rejectParticipantAudio(id));
}, [ dispatch ]);
const [ drawerParticipant, closeDrawer, openDrawerForParticipant ] = useParticipantDrawer();
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
// FIXME:
// It seems that useTranslation is not very scalable. Unmount 500 components that have the useTranslation hook is
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
// taking more than 10s. To workaround the issue we need to pass the texts as props. This is temporary and dirty
// solution!!!
// One potential proper fix would be to use react-window component in order to lower the number of components
// mounted.
const participantActionEllipsisLabel = t('participantsPane.actions.moreParticipantOptions');
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
const youText = t('chat.you');
const askUnmuteText = t('participantsPane.actions.askUnmute');
const muteParticipantButtonText = t('dialog.muteParticipantButton');
const styles = useStyles();
return (
<>
<div className = { styles.heading }>
{currentRoom?.name
// $FlowExpectedError
? `${currentRoom.name} (${participantsCount})`
: t('participantsPane.headings.participantsList', { count: participantsCount })}
</div>
{showInviteButton && <InviteButton />}
<ClearableInput
onChange = { setSearchString }
placeholder = { t('participantsPane.search') } />
<div>
<MeetingParticipantItems
askUnmuteText = { askUnmuteText }
lowerMenu = { lowerMenu }
muteAudio = { muteAudio }
muteParticipantButtonText = { muteParticipantButtonText }
openDrawerForParticipant = { openDrawerForParticipant }
overflowDrawer = { overflowDrawer }
participantActionEllipsisLabel = { participantActionEllipsisLabel }
participantIds = { sortedParticipantIds }
participantsCount = { participantsCount }
raiseContextId = { raiseContext.entity }
searchString = { normalizeAccents(searchString) }
toggleMenu = { toggleMenu }
youText = { youText } />
</div>
<MeetingParticipantContextMenu
closeDrawer = { closeDrawer }
drawerParticipant = { drawerParticipant }
muteAudio = { muteAudio }
offsetTarget = { raiseContext?.offsetTarget }
onEnter = { menuEnter }
onLeave = { menuLeave }
onSelect = { lowerMenu }
overflowDrawer = { overflowDrawer }
participantID = { raiseContext?.entity } />
</>
);
feat: Participants optimisations (#9515) * fix(participants): Change from array to Map * fix(unload): optimise * feat: Introduces new states for e2ee feature. Stores everyoneSupportsE2EE and everyoneEnabledE2EE to minimize looping through participants list. squash: Uses participants map and go over the elements only once. * feat: Optimizes isEveryoneModerator to do less frequent checks in all participants. * fix: Drops deep equal from participants pane and uses the map. * fix(SharedVideo): isVideoPlaying * fix(participants): Optimise isEveryoneModerator * fix(e2e): Optimise everyoneEnabledE2EE * fix: JS errors. * ref(participants): remove getParticipants * fix(participants): Prepare for PR. * fix: Changes participants pane to be component. The functional component was always rendered: `prev props: {} !== {} :next props`. * feat: Optimization to skip participants list on pane closed. * fix: The participants list shows and the local participant. * fix: Fix wrong action name for av-moderation. * fix: Minimizes the number of render calls of av moderation notification. * fix: Fix iterating over remote participants. * fix: Fixes lint error. * fix: Reflects participant updates for av-moderation. * fix(ParticipantPane): to work with IDs. * fix(av-moderation): on PARTCIPANT_UPDATE * fix(ParticipantPane): close delay. * fix: address code review comments * fix(API): mute-everyone * fix: bugs * fix(Thumbnail): on mobile. * fix(ParticipantPane): Close context menu on click. * fix: Handles few error when local participant is undefined. * feat: Hides AV moderation if not supported. * fix: Show mute all video. * fix: Fixes updating participant for av moderation. Co-authored-by: damencho <damencho@jitsi.org>
2021-07-09 12:36:19 +00:00
}
/**
* Maps (parts of) the redux state to the associated props for this component.
*
* @param {Object} state - The Redux state.
* @param {Object} ownProps - The own props of the component.
* @private
* @returns {Props}
*/
function _mapStateToProps(state): Object {
const sortedParticipantIds = getSortedParticipantIds(state);
// This is very important as getRemoteParticipants is not changing its reference object
// and we will not re-render on change, but if count changes we will do
const participantsCount = getParticipantCountWithFake(state);
const showInviteButton = shouldRenderInviteButton(state) && isToolbarButtonEnabled('invite', state);
const overflowDrawer = showOverflowDrawer(state);
const currentRoomId = getCurrentRoomId(state);
const currentRoom = getBreakoutRooms(state)[currentRoomId];
return {
currentRoom,
overflowDrawer,
participantsCount,
showInviteButton,
sortedParticipantIds
};
}
export default connect(_mapStateToProps)(MeetingParticipants);