import React, { PureComponent } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import _ from 'lodash'; import Button from '/imports/ui/components/button/component'; import { Session } from 'meteor/session'; import logger from '/imports/startup/client/logger'; import { styles } from './styles'; import Service from './service'; import BreakoutRoomContainer from './breakout-remaining-time/container'; import VideoService from '/imports/ui/components/video-provider/service'; import { screenshareHasEnded } from '/imports/ui/components/screenshare/service'; import UserListService from '/imports/ui/components/user-list/service'; import AudioManager from '/imports/ui/services/audio-manager'; const intlMessages = defineMessages({ breakoutTitle: { id: 'app.createBreakoutRoom.title', description: 'breakout title', }, breakoutAriaTitle: { id: 'app.createBreakoutRoom.ariaTitle', description: 'breakout aria title', }, breakoutDuration: { id: 'app.createBreakoutRoom.duration', description: 'breakout duration time', }, breakoutRoom: { id: 'app.createBreakoutRoom.room', description: 'breakout room', }, breakoutJoin: { id: 'app.createBreakoutRoom.join', description: 'label for join breakout room', }, breakoutJoinAudio: { id: 'app.createBreakoutRoom.joinAudio', description: 'label for option to transfer audio', }, breakoutReturnAudio: { id: 'app.createBreakoutRoom.returnAudio', description: 'label for option to return audio', }, generatingURL: { id: 'app.createBreakoutRoom.generatingURL', description: 'label for generating breakout room url', }, generatedURL: { id: 'app.createBreakoutRoom.generatedURL', description: 'label for generate breakout room url', }, endAllBreakouts: { id: 'app.createBreakoutRoom.endAllBreakouts', description: 'Button label to end all breakout rooms', }, alreadyConnected: { id: 'app.createBreakoutRoom.alreadyConnected', description: 'label for the user that is already connected to breakout room', }, }); class BreakoutRoom extends PureComponent { static sortById(a, b) { if (a.userId > b.userId) { return 1; } if (a.userId < b.userId) { return -1; } return 0; } constructor(props) { super(props); this.renderBreakoutRooms = this.renderBreakoutRooms.bind(this); this.getBreakoutURL = this.getBreakoutURL.bind(this); this.renderDuration = this.renderDuration.bind(this); this.transferUserToBreakoutRoom = this.transferUserToBreakoutRoom.bind(this); this.renderUserActions = this.renderUserActions.bind(this); this.returnBackToMeeeting = this.returnBackToMeeeting.bind(this); this.state = { requestedBreakoutId: '', waiting: false, joinedAudioOnly: false, breakoutId: '', }; } componentDidUpdate() { const { breakoutRoomUser, breakoutRooms, closeBreakoutPanel, setBreakoutAudioTransferStatus, isMicrophoneUser, isReconnecting, } = this.props; const { waiting, requestedBreakoutId, joinedAudioOnly, } = this.state; if (breakoutRooms.length <= 0) closeBreakoutPanel(); if (waiting) { const breakoutUser = breakoutRoomUser(requestedBreakoutId); if (!breakoutUser) return; if (breakoutUser.redirectToHtml5JoinURL !== '') { window.open(breakoutUser.redirectToHtml5JoinURL, '_blank'); _.delay(() => this.setState({ waiting: false }), 1000); } } if (joinedAudioOnly && (!isMicrophoneUser || isReconnecting)) { this.clearJoinedAudioOnly(); setBreakoutAudioTransferStatus({ breakoutMeetingId: '', status: AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.DISCONNECTED, }); } } getBreakoutURL(breakoutId) { Session.set('lastBreakoutOpened', breakoutId); const { requestJoinURL, breakoutRoomUser } = this.props; const { waiting } = this.state; const hasUser = breakoutRoomUser(breakoutId); if (!hasUser && !waiting) { this.setState( { waiting: true, requestedBreakoutId: breakoutId, }, () => requestJoinURL(breakoutId), ); } if (hasUser) { window.open(hasUser.redirectToHtml5JoinURL, '_blank'); this.setState({ waiting: false }); } return null; } clearJoinedAudioOnly() { this.setState({ joinedAudioOnly: false }); } transferUserToBreakoutRoom(breakoutId) { const { transferToBreakout } = this.props; transferToBreakout(breakoutId); this.setState({ joinedAudioOnly: true, breakoutId }); } returnBackToMeeeting(breakoutId) { const { transferUserToMeeting, meetingId } = this.props; transferUserToMeeting(breakoutId, meetingId); this.setState({ joinedAudioOnly: false, breakoutId }); } renderUserActions(breakoutId, joinedUsers, number) { const { isMicrophoneUser, amIModerator, intl, isUserInBreakoutRoom, exitAudio, setBreakoutAudioTransferStatus, getBreakoutAudioTransferStatus, } = this.props; const { joinedAudioOnly, breakoutId: _stateBreakoutId, requestedBreakoutId, waiting, } = this.state; const { breakoutMeetingId: currentAudioTransferBreakoutId, status, } = getBreakoutAudioTransferStatus(); const isInBreakoutAudioTransfer = status === AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.CONNECTED; const stateBreakoutId = _stateBreakoutId || currentAudioTransferBreakoutId; const moderatorJoinedAudio = isMicrophoneUser && amIModerator; const disable = waiting && requestedBreakoutId !== breakoutId; const audioAction = joinedAudioOnly || isInBreakoutAudioTransfer ? () => { setBreakoutAudioTransferStatus({ breakoutMeetingId: breakoutId, status: AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.RETURNING, }); this.returnBackToMeeeting(breakoutId); return logger.debug({ logCode: 'breakoutroom_return_main_audio', extraInfo: { logType: 'user_action' }, }, 'Returning to main audio (breakout room audio closed)'); } : () => { setBreakoutAudioTransferStatus({ breakoutMeetingId: breakoutId, status: AudioManager.BREAKOUT_AUDIO_TRANSFER_STATES.CONNECTED, }); this.transferUserToBreakoutRoom(breakoutId); return logger.debug({ logCode: 'breakoutroom_join_audio_from_main_room', extraInfo: { logType: 'user_action' }, }, 'joining breakout room audio (main room audio closed)'); }; return (