2021-08-19 01:24:19 +08:00
|
|
|
import React, { useState, useRef } from 'react';
|
2021-07-20 04:19:06 +08:00
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { styles } from './styles';
|
|
|
|
import Button from '/imports/ui/components/button/component';
|
2021-08-19 01:24:19 +08:00
|
|
|
import TooltipContainer from '/imports/ui/components/tooltip/container';
|
2021-07-20 04:19:06 +08:00
|
|
|
import {
|
|
|
|
EFFECT_TYPES,
|
|
|
|
BLUR_FILENAME,
|
|
|
|
IMAGE_NAMES,
|
|
|
|
getVirtualBackgroundThumbnail,
|
2021-08-04 03:24:08 +08:00
|
|
|
isVirtualBackgroundSupported,
|
2021-07-20 04:19:06 +08:00
|
|
|
} from '/imports/ui/services/virtual-background/service'
|
|
|
|
|
|
|
|
const propTypes = {
|
|
|
|
intl: PropTypes.shape({
|
|
|
|
formatMessage: PropTypes.func.isRequired,
|
|
|
|
}).isRequired,
|
|
|
|
handleVirtualBgSelected: PropTypes.func.isRequired,
|
|
|
|
locked: PropTypes.bool.isRequired,
|
|
|
|
showThumbnails: PropTypes.bool,
|
|
|
|
initialVirtualBgState: PropTypes.shape({
|
|
|
|
type: PropTypes.string.isRequired,
|
|
|
|
name: PropTypes.string,
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
|
|
|
|
const intlMessages = defineMessages({
|
|
|
|
virtualBackgroundSettingsLabel: {
|
|
|
|
id: 'app.videoPreview.webcamVirtualBackgroundLabel',
|
|
|
|
description: 'Label for the virtual background',
|
|
|
|
},
|
2021-08-04 03:24:08 +08:00
|
|
|
virtualBackgroundSettingsDisabledLabel: {
|
|
|
|
id: 'app.videoPreview.webcamVirtualBackgroundDisabledLabel',
|
|
|
|
description: 'Label for the unsupported virtual background',
|
|
|
|
},
|
2021-07-20 04:19:06 +08:00
|
|
|
noneLabel: {
|
|
|
|
id: 'app.video.virtualBackground.none',
|
|
|
|
description: 'Label for no virtual background selected',
|
|
|
|
},
|
|
|
|
blurLabel: {
|
|
|
|
id: 'app.video.virtualBackground.blur',
|
|
|
|
description: 'Label for the blurred camera option',
|
2021-08-19 01:24:19 +08:00
|
|
|
},
|
|
|
|
thumbnailLabel: {
|
|
|
|
id: 'app.video.virtualBackground.thumbnail',
|
|
|
|
description: 'Label for the image camera options',
|
2021-07-20 04:19:06 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const VirtualBgSelector = ({
|
|
|
|
intl,
|
|
|
|
handleVirtualBgSelected,
|
|
|
|
locked,
|
|
|
|
showThumbnails,
|
|
|
|
initialVirtualBgState,
|
|
|
|
}) => {
|
|
|
|
const [currentVirtualBg, setCurrentVirtualBg] = useState({
|
|
|
|
...initialVirtualBgState,
|
|
|
|
});
|
|
|
|
|
2021-08-19 01:24:19 +08:00
|
|
|
const inputElementsRef = useRef([]);
|
|
|
|
|
|
|
|
const _virtualBgSelected = (type, name, index) => {
|
2021-07-20 04:19:06 +08:00
|
|
|
handleVirtualBgSelected(type, name).then(switched => {
|
|
|
|
// Reset to the base NONE_TYPE effect if it failed because the expected
|
|
|
|
// behaviour from upstream's method is to actually stop/reset the effect
|
|
|
|
// service if it fails
|
|
|
|
if (!switched) {
|
|
|
|
return setCurrentVirtualBg({ type: EFFECT_TYPES.NONE_TYPE });
|
|
|
|
}
|
|
|
|
|
2021-08-19 01:24:19 +08:00
|
|
|
if (index >= 0) {
|
|
|
|
inputElementsRef.current[index].focus();
|
|
|
|
}
|
2021-07-20 04:19:06 +08:00
|
|
|
setCurrentVirtualBg({ type, name });
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderDropdownSelector = () => {
|
2021-08-04 03:24:08 +08:00
|
|
|
const disabled = locked || !isVirtualBackgroundSupported();
|
|
|
|
|
2021-07-20 04:19:06 +08:00
|
|
|
return (
|
|
|
|
<div className={styles.virtualBackgroundRowDropdown}>
|
|
|
|
<select
|
|
|
|
value={JSON.stringify(currentVirtualBg)}
|
|
|
|
className={styles.select}
|
2021-08-04 03:24:08 +08:00
|
|
|
disabled={disabled}
|
2021-07-20 04:19:06 +08:00
|
|
|
onChange={event => {
|
|
|
|
const { type, name } = JSON.parse(event.target.value);
|
|
|
|
_virtualBgSelected(type, name);
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<option value={JSON.stringify({ type: EFFECT_TYPES.NONE_TYPE })}>
|
|
|
|
{intl.formatMessage(intlMessages.noneLabel)}
|
|
|
|
</option>
|
|
|
|
|
|
|
|
<option value={JSON.stringify({ type: EFFECT_TYPES.BLUR_TYPE })}>
|
|
|
|
{intl.formatMessage(intlMessages.blurLabel)}
|
|
|
|
</option>
|
|
|
|
|
|
|
|
{IMAGE_NAMES.map((imageName, index) => (
|
|
|
|
<option key={`${imageName}-${index}`} value={JSON.stringify({
|
|
|
|
type: EFFECT_TYPES.IMAGE_TYPE,
|
|
|
|
name: imageName,
|
|
|
|
})}>
|
|
|
|
{imageName.split(".")[0]}
|
|
|
|
</option>
|
|
|
|
))}
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
const renderThumbnailSelector = () => {
|
2021-08-04 03:24:08 +08:00
|
|
|
const disabled = locked || !isVirtualBackgroundSupported();
|
|
|
|
|
2021-07-20 04:19:06 +08:00
|
|
|
return (
|
|
|
|
<div className={styles.virtualBackgroundRowThumbnail}>
|
|
|
|
<Button
|
|
|
|
icon='close'
|
|
|
|
label={intl.formatMessage(intlMessages.noneLabel)}
|
|
|
|
hideLabel
|
2021-08-04 03:24:08 +08:00
|
|
|
disabled={disabled}
|
2021-07-20 04:19:06 +08:00
|
|
|
onClick={() => _virtualBgSelected(EFFECT_TYPES.NONE_TYPE)}
|
|
|
|
/>
|
|
|
|
|
2021-08-19 01:24:19 +08:00
|
|
|
<TooltipContainer title={intl.formatMessage(intlMessages.blurLabel)} key={`blur-0`}>
|
|
|
|
<input
|
|
|
|
type="image"
|
|
|
|
className={styles.virtualBackgroundItem}
|
|
|
|
alt="image-input"
|
|
|
|
aria-label={EFFECT_TYPES.BLUR_TYPE}
|
|
|
|
src={getVirtualBackgroundThumbnail(BLUR_FILENAME)}
|
|
|
|
disabled={disabled}
|
|
|
|
ref={ref => inputElementsRef.current[0] = ref}
|
|
|
|
onClick={() => _virtualBgSelected(EFFECT_TYPES.BLUR_TYPE, 'Blur', 0)}
|
|
|
|
/>
|
|
|
|
</TooltipContainer>
|
|
|
|
|
|
|
|
{IMAGE_NAMES.map((imageName, index) => (
|
|
|
|
<TooltipContainer
|
|
|
|
title={intl.formatMessage(
|
|
|
|
intlMessages.thumbnailLabel,
|
|
|
|
({ 0: imageName }),
|
|
|
|
)}
|
|
|
|
key={`${imageName}-${index}`}
|
|
|
|
>
|
|
|
|
<input
|
|
|
|
type="image"
|
|
|
|
className={styles.virtualBackgroundItem}
|
|
|
|
alt="image-input"
|
|
|
|
aria-label={imageName}
|
|
|
|
src={getVirtualBackgroundThumbnail(imageName)}
|
|
|
|
ref={ref => inputElementsRef.current[index + 1] = ref}
|
|
|
|
onClick={() => _virtualBgSelected(EFFECT_TYPES.IMAGE_TYPE, imageName, index + 1)}
|
|
|
|
disabled={disabled}
|
|
|
|
/>
|
|
|
|
</TooltipContainer>
|
|
|
|
))}
|
|
|
|
</div>
|
2021-07-20 04:19:06 +08:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
const renderSelector = () => {
|
|
|
|
if (showThumbnails) return renderThumbnailSelector();
|
|
|
|
return renderDropdownSelector();
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
2021-08-04 03:24:08 +08:00
|
|
|
<>
|
2021-07-20 04:19:06 +08:00
|
|
|
<label className={styles.label}>
|
2021-08-04 03:24:08 +08:00
|
|
|
{!isVirtualBackgroundSupported()
|
|
|
|
? intl.formatMessage(intlMessages.virtualBackgroundSettingsDisabledLabel)
|
|
|
|
: intl.formatMessage(intlMessages.virtualBackgroundSettingsLabel)}
|
2021-07-20 04:19:06 +08:00
|
|
|
</label>
|
|
|
|
|
|
|
|
{renderSelector()}
|
2021-08-04 03:24:08 +08:00
|
|
|
</>
|
2021-07-20 04:19:06 +08:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
VirtualBgSelector.propTypes = propTypes;
|
|
|
|
VirtualBgSelector.defaultProps = {
|
|
|
|
showThumbnails: false,
|
|
|
|
initialVirtualBgState: {
|
|
|
|
type: EFFECT_TYPES.NONE_TYPE,
|
2021-08-04 03:24:08 +08:00
|
|
|
},
|
2021-07-20 04:19:06 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
export default injectIntl(VirtualBgSelector);
|