in react/features/virtual-background/components/VirtualBackgroundDialog.js [114:355]
function VirtualBackground({
_images,
_jitsiTrack,
_localFlipX,
_selectedThumbnail,
_showUploadButton,
_virtualBackground,
dispatch,
initialOptions,
t
}: Props) {
const [ previewIsLoaded, setPreviewIsLoaded ] = useState(false);
const [ options, setOptions ] = useState({ ...initialOptions });
const localImages = jitsiLocalStorage.getItem('virtualBackgrounds');
const [ storedImages, setStoredImages ] = useState<Array<Image>>((localImages && Bourne.parse(localImages)) || []);
const [ loading, setLoading ] = useState(false);
const { disableScreensharingVirtualBackground } = useSelector(state => state['features/base/config']);
const [ activeDesktopVideo ] = useState(_virtualBackground?.virtualSource?.videoType === VIDEO_TYPE.DESKTOP
? _virtualBackground.virtualSource
: null);
const [ initialVirtualBackground ] = useState(_virtualBackground);
const deleteStoredImage = useCallback(e => {
const imageId = e.currentTarget.getAttribute('data-imageid');
setStoredImages(storedImages.filter(item => item.id !== imageId));
}, [ storedImages ]);
const deleteStoredImageKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
deleteStoredImage(e);
}
}, [ deleteStoredImage ]);
/**
* Updates stored images on local storage.
*/
useEffect(() => {
try {
jitsiLocalStorage.setItem('virtualBackgrounds', JSON.stringify(storedImages));
} catch (err) {
// Preventing localStorage QUOTA_EXCEEDED_ERR
err && setStoredImages(storedImages.slice(1));
}
if (storedImages.length === BACKGROUNDS_LIMIT) {
setStoredImages(storedImages.slice(1));
}
}, [ storedImages ]);
const enableBlur = useCallback(async () => {
setOptions({
backgroundType: VIRTUAL_BACKGROUND_TYPE.BLUR,
enabled: true,
blurValue: 25,
selectedThumbnail: 'blur'
});
logger.info('"Blur" option setted for virtual background preview!');
}, []);
const enableBlurKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
enableBlur();
}
}, [ enableBlur ]);
const enableSlideBlur = useCallback(async () => {
setOptions({
backgroundType: VIRTUAL_BACKGROUND_TYPE.BLUR,
enabled: true,
blurValue: 8,
selectedThumbnail: 'slight-blur'
});
logger.info('"Slight-blur" option setted for virtual background preview!');
}, []);
const enableSlideBlurKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
enableSlideBlur();
}
}, [ enableSlideBlur ]);
const shareDesktop = useCallback(async () => {
if (disableScreensharingVirtualBackground) {
return;
}
let isCancelled = false, url;
try {
url = await createLocalTrack('desktop', '');
} catch (e) {
if (e.name === JitsiTrackErrors.SCREENSHARING_USER_CANCELED) {
isCancelled = true;
} else {
logger.error(e);
}
}
if (!url) {
if (!isCancelled) {
dispatch(showErrorNotification({
titleKey: 'virtualBackground.desktopShareError'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
logger.error('Could not create desktop share as a virtual background!');
}
/**
* For electron createLocalTrack will open the {@code DesktopPicker} dialog and hide the
* {@code VirtualBackgroundDialog}. That's why we need to reopen the {@code VirtualBackgroundDialog}
* and restore the current state through {@code initialOptions} prop.
*/
if (browser.isElectron()) {
dispatch(openDialog(VirtualBackgroundDialog, { initialOptions: options }));
}
return;
}
const newOptions = {
backgroundType: VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE,
enabled: true,
selectedThumbnail: 'desktop-share',
url
};
/**
* For electron createLocalTrack will open the {@code DesktopPicker} dialog and hide the
* {@code VirtualBackgroundDialog}. That's why we need to reopen the {@code VirtualBackgroundDialog}
* and force it to show desktop share virtual background through {@code initialOptions} prop.
*/
if (browser.isElectron()) {
dispatch(openDialog(VirtualBackgroundDialog, { initialOptions: newOptions }));
} else {
setOptions(newOptions);
logger.info('"Desktop-share" option setted for virtual background preview!');
}
}, [ dispatch, options ]);
const shareDesktopKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
shareDesktop();
}
}, [ shareDesktop ]);
const removeBackground = useCallback(async () => {
setOptions({
enabled: false,
selectedThumbnail: 'none'
});
logger.info('"None" option setted for virtual background preview!');
}, []);
const removeBackgroundKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
removeBackground();
}
}, [ removeBackground ]);
const setUploadedImageBackground = useCallback(async e => {
const imageId = e.currentTarget.getAttribute('data-imageid');
const image = storedImages.find(img => img.id === imageId);
if (image) {
setOptions({
backgroundType: 'image',
enabled: true,
url: image.src,
selectedThumbnail: image.id
});
logger.info('Uploaded image setted for virtual background preview!');
}
}, [ storedImages ]);
const setImageBackground = useCallback(async e => {
const imageId = e.currentTarget.getAttribute('data-imageid');
const image = _images.find(img => img.id === imageId);
if (image) {
try {
const url = await toDataURL(image.src);
setOptions({
backgroundType: 'image',
enabled: true,
url,
selectedThumbnail: image.id
});
logger.info('Image set for virtual background preview!');
} catch (err) {
logger.error('Could not fetch virtual background image:', err);
}
setLoading(false);
}
}, []);
const setImageBackgroundKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
setImageBackground(e);
}
}, [ setImageBackground ]);
const setUploadedImageBackgroundKeyPress = useCallback(e => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault();
setUploadedImageBackground(e);
}
}, [ setUploadedImageBackground ]);
const applyVirtualBackground = useCallback(async () => {
if (activeDesktopVideo) {
await activeDesktopVideo.dispose();
}
setLoading(true);
await dispatch(toggleBackgroundEffect(options, _jitsiTrack));
await setLoading(false);
if (_localFlipX && options.backgroundType === VIRTUAL_BACKGROUND_TYPE.DESKTOP_SHARE) {
dispatch(updateSettings({
localFlipX: !_localFlipX
}));
} else {
// Set x scale to default value.
dispatch(updateSettings({
localFlipX: true
}));
}
dispatch(hideDialog());
logger.info(`Virtual background type: '${typeof options.backgroundType === 'undefined'
? 'none' : options.backgroundType}' applied!`);
dispatch(virtualBackgroundTrackChanged());
}, [ dispatch, options, _localFlipX ]);