2016-11-07 23:52:39 +08:00
|
|
|
import React, { Component } from 'react';
|
2020-05-26 04:00:13 +08:00
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2023-03-20 21:08:35 +08:00
|
|
|
import ModalFullscreen from '/imports/ui/components/common/modal/fullscreen/component';
|
2019-07-26 02:41:24 +08:00
|
|
|
import logger from '/imports/startup/client/logger';
|
|
|
|
import PropTypes from 'prop-types';
|
2017-10-06 20:50:01 +08:00
|
|
|
import AudioService from '../audio/service';
|
2019-05-08 03:12:25 +08:00
|
|
|
import VideoService from '../video-provider/service';
|
2021-03-12 09:31:46 +08:00
|
|
|
import { screenshareHasEnded } from '/imports/ui/components/screenshare/service';
|
2021-10-26 21:37:23 +08:00
|
|
|
import Styled from './styles';
|
2022-04-12 20:50:19 +08:00
|
|
|
import { Session } from 'meteor/session';
|
2016-11-07 23:52:39 +08:00
|
|
|
|
|
|
|
const intlMessages = defineMessages({
|
|
|
|
title: {
|
2016-11-14 19:57:10 +08:00
|
|
|
id: 'app.breakoutJoinConfirmation.title',
|
2017-04-10 23:50:03 +08:00
|
|
|
description: 'Join breakout room title',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
|
|
|
message: {
|
|
|
|
id: 'app.breakoutJoinConfirmation.message',
|
2020-07-10 04:53:42 +08:00
|
|
|
description: 'Join breakout confirm message',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
2018-07-07 01:38:14 +08:00
|
|
|
freeJoinMessage: {
|
|
|
|
id: 'app.breakoutJoinConfirmation.freeJoinMessage',
|
2020-07-10 04:53:42 +08:00
|
|
|
description: 'Join breakout confirm message',
|
2018-07-07 01:38:14 +08:00
|
|
|
},
|
2016-11-07 23:52:39 +08:00
|
|
|
confirmLabel: {
|
2019-05-25 01:29:36 +08:00
|
|
|
id: 'app.createBreakoutRoom.join',
|
2017-04-10 23:50:03 +08:00
|
|
|
description: 'Join confirmation button label',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
|
|
|
confirmDesc: {
|
|
|
|
id: 'app.breakoutJoinConfirmation.confirmDesc',
|
2017-04-11 21:52:30 +08:00
|
|
|
description: 'adds context to confirm option',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
|
|
|
dismissLabel: {
|
|
|
|
id: 'app.breakoutJoinConfirmation.dismissLabel',
|
2017-04-10 23:50:03 +08:00
|
|
|
description: 'Cancel button label',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
|
|
|
dismissDesc: {
|
|
|
|
id: 'app.breakoutJoinConfirmation.dismissDesc',
|
2017-04-11 21:52:30 +08:00
|
|
|
description: 'adds context to dismiss option',
|
2016-11-07 23:52:39 +08:00
|
|
|
},
|
2021-08-10 03:10:14 +08:00
|
|
|
generatingURL: {
|
|
|
|
id: 'app.createBreakoutRoom.generatingURLMessage',
|
|
|
|
description: 'label for generating breakout room url',
|
|
|
|
},
|
2016-11-07 23:52:39 +08:00
|
|
|
});
|
|
|
|
|
2019-07-26 02:41:24 +08:00
|
|
|
const propTypes = {
|
2020-05-26 04:00:13 +08:00
|
|
|
intl: PropTypes.object.isRequired,
|
2019-07-26 02:41:24 +08:00
|
|
|
breakout: PropTypes.objectOf(Object).isRequired,
|
|
|
|
getURL: PropTypes.func.isRequired,
|
|
|
|
breakoutURL: PropTypes.string.isRequired,
|
|
|
|
isFreeJoin: PropTypes.bool.isRequired,
|
2019-07-26 22:35:20 +08:00
|
|
|
voiceUserJoined: PropTypes.bool.isRequired,
|
2019-07-26 02:41:24 +08:00
|
|
|
requestJoinURL: PropTypes.func.isRequired,
|
|
|
|
breakouts: PropTypes.arrayOf(Object).isRequired,
|
|
|
|
breakoutName: PropTypes.string.isRequired,
|
2024-01-27 00:21:58 +08:00
|
|
|
sendUserUnshareWebcam: PropTypes.func.isRequired,
|
2019-07-26 02:41:24 +08:00
|
|
|
};
|
|
|
|
|
2021-08-10 03:10:14 +08:00
|
|
|
let interval = null;
|
|
|
|
|
2017-02-16 02:36:30 +08:00
|
|
|
class BreakoutJoinConfirmation extends Component {
|
2016-11-07 23:52:39 +08:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
2018-07-07 01:38:14 +08:00
|
|
|
this.state = {
|
|
|
|
selectValue: props.breakout.breakoutId,
|
2021-08-13 22:44:09 +08:00
|
|
|
waiting: true,
|
2018-07-07 01:38:14 +08:00
|
|
|
};
|
|
|
|
|
2016-11-07 23:52:39 +08:00
|
|
|
this.handleJoinBreakoutConfirmation = this.handleJoinBreakoutConfirmation.bind(this);
|
2018-07-07 01:38:14 +08:00
|
|
|
this.renderSelectMeeting = this.renderSelectMeeting.bind(this);
|
|
|
|
this.handleSelectChange = this.handleSelectChange.bind(this);
|
2016-11-07 23:52:39 +08:00
|
|
|
}
|
|
|
|
|
2019-10-25 01:01:39 +08:00
|
|
|
componentDidMount() {
|
|
|
|
const {
|
|
|
|
isFreeJoin,
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
const {
|
|
|
|
selectValue,
|
|
|
|
} = this.state;
|
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
if (isFreeJoin) {
|
|
|
|
this.fetchJoinURL(selectValue);
|
|
|
|
} else {
|
|
|
|
this.setState({ waiting: false });
|
2019-10-25 01:01:39 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
componentWillUnmount() {
|
|
|
|
if (interval) clearInterval(interval);
|
|
|
|
}
|
|
|
|
|
2016-11-07 23:52:39 +08:00
|
|
|
handleJoinBreakoutConfirmation() {
|
2017-05-03 01:18:01 +08:00
|
|
|
const {
|
2018-07-07 01:38:14 +08:00
|
|
|
getURL,
|
2023-03-22 20:50:39 +08:00
|
|
|
setIsOpen,
|
2018-07-07 01:38:14 +08:00
|
|
|
breakoutURL,
|
|
|
|
isFreeJoin,
|
2019-07-26 22:35:20 +08:00
|
|
|
voiceUserJoined,
|
2020-07-10 04:53:42 +08:00
|
|
|
requestJoinURL,
|
2021-11-24 00:41:37 +08:00
|
|
|
amIPresenter,
|
2024-01-27 00:21:58 +08:00
|
|
|
sendUserUnshareWebcam,
|
2017-05-03 01:18:01 +08:00
|
|
|
} = this.props;
|
2019-07-26 02:41:24 +08:00
|
|
|
|
|
|
|
const { selectValue } = this.state;
|
2020-07-10 04:53:42 +08:00
|
|
|
if (!getURL(selectValue)) {
|
|
|
|
requestJoinURL(selectValue);
|
|
|
|
}
|
|
|
|
const urlFromSelectedRoom = getURL(selectValue);
|
|
|
|
const url = isFreeJoin ? urlFromSelectedRoom : breakoutURL;
|
2019-07-26 02:41:24 +08:00
|
|
|
|
2021-02-10 04:22:39 +08:00
|
|
|
// leave main room's audio, and stops video and screenshare when joining a breakout room
|
2019-07-26 22:35:20 +08:00
|
|
|
if (voiceUserJoined) {
|
2019-07-26 02:41:24 +08:00
|
|
|
AudioService.exitAudio();
|
|
|
|
logger.info({
|
|
|
|
logCode: 'breakoutjoinconfirmation_ended_audio',
|
|
|
|
extraInfo: { logType: 'user_action' },
|
|
|
|
}, 'joining breakout room closed audio in the main room');
|
|
|
|
}
|
|
|
|
|
2021-03-27 03:51:39 +08:00
|
|
|
VideoService.storeDeviceIds();
|
2024-01-27 00:21:58 +08:00
|
|
|
VideoService.exitVideo(sendUserUnshareWebcam);
|
2021-11-24 00:41:37 +08:00
|
|
|
if (amIPresenter) screenshareHasEnded();
|
2020-07-10 04:53:42 +08:00
|
|
|
if (url === '') {
|
|
|
|
logger.error({
|
|
|
|
logCode: 'breakoutjoinconfirmation_redirecting_to_url',
|
|
|
|
extraInfo: { breakoutURL, isFreeJoin },
|
|
|
|
}, 'joining breakout room but redirected to about://blank');
|
|
|
|
}
|
2022-04-12 20:50:19 +08:00
|
|
|
|
|
|
|
Session.set('lastBreakoutIdOpened', selectValue);
|
2018-07-07 01:38:14 +08:00
|
|
|
window.open(url);
|
2023-03-22 20:50:39 +08:00
|
|
|
setIsOpen(false);
|
2016-11-07 23:52:39 +08:00
|
|
|
}
|
2018-07-13 00:19:54 +08:00
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
async fetchJoinURL(selectValue) {
|
2019-10-25 01:01:39 +08:00
|
|
|
const {
|
|
|
|
requestJoinURL,
|
|
|
|
getURL,
|
|
|
|
} = this.props;
|
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
this.setState({ selectValue });
|
|
|
|
|
|
|
|
if (!getURL(selectValue)) {
|
|
|
|
requestJoinURL(selectValue);
|
|
|
|
|
|
|
|
this.setState({ waiting: true });
|
2021-08-10 03:10:14 +08:00
|
|
|
|
|
|
|
await new Promise((resolve) => {
|
|
|
|
|
|
|
|
interval = setInterval(() => {
|
2021-08-13 22:44:09 +08:00
|
|
|
const url = getURL(selectValue);
|
2021-08-10 03:10:14 +08:00
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
if (url !== "") {
|
2021-08-10 03:10:14 +08:00
|
|
|
resolve();
|
2021-08-13 22:44:09 +08:00
|
|
|
clearInterval(interval);
|
|
|
|
this.setState({ waiting: false });
|
2021-08-10 03:10:14 +08:00
|
|
|
}
|
|
|
|
}, 1000)
|
|
|
|
})
|
2021-08-13 22:44:09 +08:00
|
|
|
} else {
|
|
|
|
this.setState({ waiting: false });
|
2019-10-25 01:01:39 +08:00
|
|
|
}
|
2018-07-07 01:38:14 +08:00
|
|
|
}
|
|
|
|
|
2021-08-13 22:44:09 +08:00
|
|
|
handleSelectChange(e) {
|
|
|
|
const { value } = e.target;
|
|
|
|
|
|
|
|
this.fetchJoinURL(value);
|
|
|
|
}
|
|
|
|
|
2018-07-07 01:38:14 +08:00
|
|
|
renderSelectMeeting() {
|
|
|
|
const { breakouts, intl } = this.props;
|
2021-08-10 03:10:14 +08:00
|
|
|
const { selectValue, waiting, } = this.state;
|
2018-07-07 01:38:14 +08:00
|
|
|
return (
|
2021-10-26 21:37:23 +08:00
|
|
|
<Styled.SelectParent>
|
2018-07-07 01:38:14 +08:00
|
|
|
{`${intl.formatMessage(intlMessages.freeJoinMessage)}`}
|
2021-10-26 21:37:23 +08:00
|
|
|
<Styled.Select
|
2019-07-26 02:41:24 +08:00
|
|
|
value={selectValue}
|
2018-07-07 01:38:14 +08:00
|
|
|
onChange={this.handleSelectChange}
|
2021-08-10 03:10:14 +08:00
|
|
|
disabled={waiting}
|
2018-07-07 01:38:14 +08:00
|
|
|
>
|
2019-07-26 02:41:24 +08:00
|
|
|
{
|
|
|
|
breakouts.map(({ name, breakoutId }) => (
|
|
|
|
<option
|
2023-02-10 03:43:49 +08:00
|
|
|
data-test="roomOption"
|
2019-07-26 02:41:24 +08:00
|
|
|
key={breakoutId}
|
|
|
|
value={breakoutId}
|
|
|
|
>
|
|
|
|
{name}
|
|
|
|
</option>
|
|
|
|
))
|
|
|
|
}
|
2021-10-26 21:37:23 +08:00
|
|
|
</Styled.Select>
|
2021-10-07 04:19:46 +08:00
|
|
|
{ waiting ? <span data-test="labelGeneratingURL">{intl.formatMessage(intlMessages.generatingURL)}</span> : null}
|
2021-10-26 21:37:23 +08:00
|
|
|
</Styled.SelectParent>
|
2018-07-07 01:38:14 +08:00
|
|
|
);
|
|
|
|
}
|
2016-11-07 23:52:39 +08:00
|
|
|
|
|
|
|
render() {
|
2023-04-12 23:51:23 +08:00
|
|
|
const { intl, breakoutName, isFreeJoin, setIsOpen,
|
|
|
|
isOpen, priority,
|
|
|
|
} = this.props;
|
2021-08-10 03:10:14 +08:00
|
|
|
const { waiting } = this.state;
|
2019-07-26 02:41:24 +08:00
|
|
|
|
2016-11-07 23:52:39 +08:00
|
|
|
return (
|
2023-03-20 21:08:35 +08:00
|
|
|
<ModalFullscreen
|
2016-11-07 23:52:39 +08:00
|
|
|
title={intl.formatMessage(intlMessages.title)}
|
|
|
|
confirm={{
|
|
|
|
callback: this.handleJoinBreakoutConfirmation,
|
2019-05-25 01:29:36 +08:00
|
|
|
label: intl.formatMessage(intlMessages.confirmLabel),
|
2016-11-07 23:52:39 +08:00
|
|
|
description: intl.formatMessage(intlMessages.confirmDesc),
|
2019-05-24 23:32:31 +08:00
|
|
|
icon: 'popout_window',
|
2021-08-10 03:10:14 +08:00
|
|
|
disabled: waiting,
|
2016-11-07 23:52:39 +08:00
|
|
|
}}
|
|
|
|
dismiss={{
|
2023-03-22 20:50:39 +08:00
|
|
|
callback: () => setIsOpen(false),
|
2016-11-07 23:52:39 +08:00
|
|
|
label: intl.formatMessage(intlMessages.dismissLabel),
|
|
|
|
description: intl.formatMessage(intlMessages.dismissDesc),
|
2017-06-03 03:25:02 +08:00
|
|
|
}}
|
2023-12-12 00:21:00 +08:00
|
|
|
{...{
|
2023-04-12 23:51:23 +08:00
|
|
|
setIsOpen,
|
|
|
|
isOpen,
|
|
|
|
priority,
|
|
|
|
}}
|
2017-06-03 03:25:02 +08:00
|
|
|
>
|
2018-07-07 01:38:14 +08:00
|
|
|
{ isFreeJoin ? this.renderSelectMeeting() : `${intl.formatMessage(intlMessages.message)} ${breakoutName}?`}
|
2023-03-20 21:08:35 +08:00
|
|
|
</ModalFullscreen>
|
2016-11-07 23:52:39 +08:00
|
|
|
);
|
|
|
|
}
|
2017-06-03 03:25:02 +08:00
|
|
|
}
|
2016-11-07 23:52:39 +08:00
|
|
|
|
2023-03-22 20:50:39 +08:00
|
|
|
export default injectIntl(BreakoutJoinConfirmation);
|
2019-07-26 02:41:24 +08:00
|
|
|
|
|
|
|
BreakoutJoinConfirmation.propTypes = propTypes;
|