/* * Wire * Copyright (C) 2024 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ import React from 'react'; import cx from 'classnames'; import {CallParticipantsListItem} from 'Components/calling/CallParticipantsListItem'; import {FadingScrollbar} from 'Components/FadingScrollbar'; import * as Icon from 'Components/Icon'; import {t} from 'Util/LocalizerUtil'; import {sortUsersByPriority} from 'Util/StringUtil'; import {labelStyles} from './CallingParticipantList.styles'; import {CallingRepository} from '../../../../calling/CallingRepository'; import {Participant} from '../../../../calling/Participant'; import {Conversation} from '../../../../entity/Conversation'; import {ContextMenuEntry, showContextMenu} from '../../../../ui/ContextMenu'; interface CallingParticipantListProps { callingRepository: Pick; conversation: Conversation; isModerator?: boolean; isSelfVerified?: boolean; participants: Participant[]; showParticipants?: boolean; } export const CallingParticipantList = ({ callingRepository, conversation, isModerator, isSelfVerified, participants, showParticipants, }: CallingParticipantListProps) => { const getParticipantContext = (event: React.MouseEvent, participant: Participant) => { event.preventDefault(); const muteParticipant = { click: () => callingRepository.sendModeratorMute(conversation.qualifiedId, [participant]), icon: Icon.MicOffIcon, identifier: `moderator-mute-participant`, isDisabled: participant.isMuted(), label: t('moderatorMenuEntryMute'), }; const muteOthers: ContextMenuEntry = { click: () => { callingRepository.sendModeratorMute( conversation.qualifiedId, participants.filter(p => p !== participant), ); }, icon: Icon.MicOffIcon, identifier: 'moderator-mute-others', label: t('moderatorMenuEntryMuteAllOthers'), }; const entries: ContextMenuEntry[] = [muteOthers].concat(!participant.user.isMe ? muteParticipant : []); showContextMenu({event, entries, identifier: 'participant-moderator-menu'}); }; return (

{t('videoCallOverlayParticipantsListLabel', participants.length)}

    {participants .slice() .sort((participantA, participantB) => sortUsersByPriority(participantA.user, participantB.user)) .map((participant, index, participantsArray) => (
  • getParticipantContext(event, participant)} isLast={participantsArray.length === index} />
  • ))}
); };