2019-06-13 02:40:58 +08:00
|
|
|
import React, { memo } from 'react';
|
2018-01-08 12:44:42 +08:00
|
|
|
import PropTypes from 'prop-types';
|
2022-02-15 04:20:50 +08:00
|
|
|
import ButtonEmoji from '/imports/ui/components/common/button/button-emoji/ButtonEmoji';
|
2019-11-28 21:13:06 +08:00
|
|
|
import VideoService from '../service';
|
2020-05-26 04:00:13 +08:00
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2021-11-03 21:06:18 +08:00
|
|
|
import Styled from './styles';
|
2019-11-28 21:13:06 +08:00
|
|
|
import { validIOSVersion } from '/imports/ui/components/app/service';
|
2021-10-16 06:37:37 +08:00
|
|
|
import deviceInfo from '/imports/utils/deviceInfo';
|
2021-02-10 21:29:26 +08:00
|
|
|
import { debounce } from 'lodash';
|
2022-04-12 01:09:13 +08:00
|
|
|
import BBBMenu from '/imports/ui/components/common/menu/component';
|
2017-09-20 11:12:10 +08:00
|
|
|
|
2021-10-18 22:03:21 +08:00
|
|
|
const ENABLE_WEBCAM_SELECTOR_BUTTON = Meteor.settings.public.app.enableWebcamSelectorButton;
|
2022-06-02 01:23:00 +08:00
|
|
|
const ENABLE_WEBCAM_BACKGROUND_UPLOAD = Meteor.settings.public.virtualBackgrounds.enableVirtualBackgroundUpload;
|
2021-10-16 06:37:37 +08:00
|
|
|
|
2017-09-20 11:12:10 +08:00
|
|
|
const intlMessages = defineMessages({
|
2022-04-12 01:09:13 +08:00
|
|
|
videoSettings: {
|
|
|
|
id: 'app.video.videoSettings',
|
|
|
|
description: 'Open video settings',
|
|
|
|
},
|
|
|
|
visualEffects: {
|
|
|
|
id: 'app.video.visualEffects',
|
|
|
|
description: 'Visual effects label',
|
|
|
|
},
|
2019-01-28 21:21:29 +08:00
|
|
|
joinVideo: {
|
|
|
|
id: 'app.video.joinVideo',
|
|
|
|
description: 'Join video button label',
|
2017-09-20 11:12:10 +08:00
|
|
|
},
|
2019-12-19 01:44:56 +08:00
|
|
|
leaveVideo: {
|
|
|
|
id: 'app.video.leaveVideo',
|
|
|
|
description: 'Leave video button label',
|
|
|
|
},
|
2021-08-10 23:25:20 +08:00
|
|
|
advancedVideo: {
|
|
|
|
id: 'app.video.advancedVideo',
|
|
|
|
description: 'Open advanced video label',
|
|
|
|
},
|
2019-03-29 22:31:56 +08:00
|
|
|
videoLocked: {
|
|
|
|
id: 'app.video.videoLocked',
|
2019-01-28 21:21:29 +08:00
|
|
|
description: 'video disabled label',
|
2018-03-23 01:02:59 +08:00
|
|
|
},
|
2020-09-10 02:07:32 +08:00
|
|
|
videoConnecting: {
|
|
|
|
id: 'app.video.connecting',
|
|
|
|
description: 'video connecting label',
|
|
|
|
},
|
2022-03-02 23:58:02 +08:00
|
|
|
camCapReached: {
|
|
|
|
id: 'app.video.meetingCamCapReached',
|
|
|
|
description: 'meeting camera cap label',
|
|
|
|
},
|
2020-09-10 02:07:32 +08:00
|
|
|
meteorDisconnected: {
|
2020-09-10 03:31:20 +08:00
|
|
|
id: 'app.video.clientDisconnected',
|
2020-09-10 02:07:32 +08:00
|
|
|
description: 'Meteor disconnected label',
|
|
|
|
},
|
2019-04-19 01:14:34 +08:00
|
|
|
iOSWarning: {
|
|
|
|
id: 'app.iOSWarning.label',
|
|
|
|
description: 'message indicating to upgrade ios version',
|
|
|
|
},
|
2017-09-20 11:12:10 +08:00
|
|
|
});
|
|
|
|
|
2021-02-10 21:29:26 +08:00
|
|
|
const JOIN_VIDEO_DELAY_MILLISECONDS = 500;
|
|
|
|
|
2018-02-26 20:29:28 +08:00
|
|
|
const propTypes = {
|
2020-05-26 04:00:13 +08:00
|
|
|
intl: PropTypes.object.isRequired,
|
2019-11-28 21:13:06 +08:00
|
|
|
hasVideoStream: PropTypes.bool.isRequired,
|
2022-04-05 01:02:50 +08:00
|
|
|
status: PropTypes.string.isRequired,
|
2019-12-19 01:44:56 +08:00
|
|
|
mountVideoPreview: PropTypes.func.isRequired,
|
2018-02-26 20:29:28 +08:00
|
|
|
};
|
2018-02-08 03:20:10 +08:00
|
|
|
|
2019-01-28 21:21:29 +08:00
|
|
|
const JoinVideoButton = ({
|
2018-02-26 20:29:28 +08:00
|
|
|
intl,
|
2019-11-28 21:13:06 +08:00
|
|
|
hasVideoStream,
|
2022-04-05 01:02:50 +08:00
|
|
|
status,
|
2020-09-10 02:07:32 +08:00
|
|
|
disableReason,
|
2019-12-19 01:44:56 +08:00
|
|
|
mountVideoPreview,
|
2019-04-19 01:14:34 +08:00
|
|
|
}) => {
|
2021-10-16 06:37:37 +08:00
|
|
|
const { isMobile } = deviceInfo;
|
2022-01-14 01:54:57 +08:00
|
|
|
const isMobileSharingCamera = hasVideoStream && isMobile;
|
2022-04-05 01:02:50 +08:00
|
|
|
const isDesktopSharingCamera = hasVideoStream && !isMobile;
|
|
|
|
const shouldEnableWebcamSelectorButton = ENABLE_WEBCAM_SELECTOR_BUTTON
|
|
|
|
&& isDesktopSharingCamera;
|
2022-04-12 01:09:13 +08:00
|
|
|
const shouldEnableWebcamBackgroundUploadButton = ENABLE_WEBCAM_BACKGROUND_UPLOAD
|
|
|
|
&& hasVideoStream
|
|
|
|
&& !isMobile;
|
2022-04-05 01:02:50 +08:00
|
|
|
const exitVideo = () => isDesktopSharingCamera && (!VideoService.isMultipleCamerasEnabled()
|
|
|
|
|| shouldEnableWebcamSelectorButton);
|
2019-12-19 01:44:56 +08:00
|
|
|
|
2021-02-10 21:29:26 +08:00
|
|
|
const handleOnClick = debounce(() => {
|
2019-11-29 04:28:41 +08:00
|
|
|
if (!validIOSVersion()) {
|
|
|
|
return VideoService.notify(intl.formatMessage(intlMessages.iOSWarning));
|
2019-04-19 01:14:34 +08:00
|
|
|
}
|
|
|
|
|
2022-04-05 01:02:50 +08:00
|
|
|
switch (status) {
|
|
|
|
case 'videoConnecting':
|
|
|
|
VideoService.stopVideo();
|
|
|
|
break;
|
|
|
|
case 'connected':
|
|
|
|
default:
|
|
|
|
if (exitVideo()) {
|
|
|
|
VideoService.exitVideo();
|
|
|
|
} else {
|
|
|
|
mountVideoPreview(isMobileSharingCamera);
|
|
|
|
}
|
2019-12-19 01:44:56 +08:00
|
|
|
}
|
2021-02-10 21:29:26 +08:00
|
|
|
}, JOIN_VIDEO_DELAY_MILLISECONDS);
|
2019-05-29 04:46:29 +08:00
|
|
|
|
2022-04-12 01:09:13 +08:00
|
|
|
const handleOpenAdvancedOptions = (props) => {
|
|
|
|
mountVideoPreview(isMobileSharingCamera, props);
|
2022-04-05 01:02:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
const getMessageFromStatus = () => {
|
|
|
|
let statusMessage = status;
|
|
|
|
if (status !== 'videoConnecting') {
|
|
|
|
statusMessage = exitVideo() ? 'leaveVideo' : 'joinVideo';
|
|
|
|
}
|
|
|
|
return statusMessage;
|
2021-08-10 23:25:20 +08:00
|
|
|
};
|
|
|
|
|
2022-04-05 01:02:50 +08:00
|
|
|
const label = disableReason
|
|
|
|
? intl.formatMessage(intlMessages[disableReason])
|
|
|
|
: intl.formatMessage(intlMessages[getMessageFromStatus()]);
|
2019-05-29 04:46:29 +08:00
|
|
|
|
2022-04-05 01:02:50 +08:00
|
|
|
const isSharing = hasVideoStream || status === 'videoConnecting';
|
2021-08-10 23:25:20 +08:00
|
|
|
|
2022-04-12 01:09:13 +08:00
|
|
|
const renderUserActions = () => {
|
|
|
|
const actions = [];
|
|
|
|
|
|
|
|
if (shouldEnableWebcamSelectorButton) {
|
|
|
|
actions.push(
|
|
|
|
{
|
|
|
|
key: 'advancedVideo',
|
|
|
|
label: intl.formatMessage(intlMessages.advancedVideo),
|
|
|
|
onClick: () => handleOpenAdvancedOptions(),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shouldEnableWebcamBackgroundUploadButton) {
|
|
|
|
actions.push(
|
|
|
|
{
|
|
|
|
key: 'virtualBgSelection',
|
|
|
|
label: intl.formatMessage(intlMessages.visualEffects),
|
|
|
|
onClick: () => handleOpenAdvancedOptions({ isVisualEffects: true }),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (actions.length === 0) return null;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<BBBMenu
|
|
|
|
trigger={(
|
|
|
|
<ButtonEmoji
|
|
|
|
emoji="device_list_selector"
|
|
|
|
hideLabel
|
|
|
|
label={intl.formatMessage(intlMessages.videoSettings)}
|
2022-06-17 00:58:54 +08:00
|
|
|
rotate
|
2022-04-12 01:09:13 +08:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
actions={actions}
|
2021-08-10 23:25:20 +08:00
|
|
|
/>
|
2022-04-12 01:09:13 +08:00
|
|
|
);
|
|
|
|
}
|
2019-05-29 04:46:29 +08:00
|
|
|
|
2019-04-19 01:14:34 +08:00
|
|
|
return (
|
2021-12-10 22:55:37 +08:00
|
|
|
<Styled.OffsetBottom>
|
|
|
|
<Styled.VideoButton
|
2021-10-18 21:55:19 +08:00
|
|
|
label={label}
|
|
|
|
data-test={hasVideoStream ? 'leaveVideo' : 'joinVideo'}
|
|
|
|
onClick={handleOnClick}
|
|
|
|
hideLabel
|
2022-04-05 01:02:50 +08:00
|
|
|
color={isSharing ? 'primary' : 'default'}
|
|
|
|
icon={isSharing ? 'video' : 'video_off'}
|
|
|
|
ghost={!isSharing}
|
2021-10-18 21:55:19 +08:00
|
|
|
size="lg"
|
|
|
|
circle
|
|
|
|
disabled={!!disableReason}
|
|
|
|
/>
|
2022-04-12 01:09:13 +08:00
|
|
|
{renderUserActions()}
|
2021-12-10 22:55:37 +08:00
|
|
|
</Styled.OffsetBottom>
|
2019-04-19 01:14:34 +08:00
|
|
|
);
|
|
|
|
};
|
2019-03-23 06:45:44 +08:00
|
|
|
|
2019-01-28 21:21:29 +08:00
|
|
|
JoinVideoButton.propTypes = propTypes;
|
2019-12-19 01:44:56 +08:00
|
|
|
|
2019-06-13 02:40:58 +08:00
|
|
|
export default injectIntl(memo(JoinVideoButton));
|