feat(screenshare) - add web security fix for electron (#13096)

use send the share screen sources using the external api

---------

Co-authored-by: Gabriel Borlea <gabriel.borlea@8x8.com>
This commit is contained in:
Duduman Bogdan Vlad
2023-10-16 14:59:55 +03:00
committed by GitHub
parent f78ebbb9a9
commit 8a2e4bc628
12 changed files with 290 additions and 41 deletions

View File

@@ -1,26 +1,24 @@
import _ from 'lodash';
import React, { PureComponent } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { IStore } from '../../app/types';
import { IReduxState, IStore } from '../../app/types';
import { hideDialog } from '../../base/dialog/actions';
import { translate } from '../../base/i18n/functions';
import Dialog from '../../base/ui/components/web/Dialog';
import Tabs from '../../base/ui/components/web/Tabs';
import { obtainDesktopSources } from '../functions';
import { deleteDesktopSources } from '../actions';
import { THUMBNAIL_SIZE } from '../constants';
import {
getDesktopPickerSources,
obtainDesktopSources,
oldJitsiMeetElectronUsage
} from '../functions';
import { IDesktopSources } from '../types';
import DesktopPickerPane from './DesktopPickerPane';
/**
* The size of the requested thumbnails.
*
* @type {Object}
*/
const THUMBNAIL_SIZE = {
height: 300,
width: 300
};
/**
* The sources polling interval in ms.
*
@@ -47,6 +45,11 @@ const VALID_TYPES = Object.keys(TAB_LABELS);
*/
interface IProps extends WithTranslation {
/**
* An object containing all the DesktopCapturerSources.
*/
_sources: IDesktopSources;
/**
* An array with desktop sharing sources to be displayed.
*/
@@ -182,6 +185,29 @@ class DesktopPicker extends PureComponent<IProps, IState> {
this._stopPolling();
}
/**
* Clean up component and DesktopCapturerSource store state.
*
* @inheritdoc
*/
componentDidUpdate(prevProps: IProps) {
// skip logic if old jitsi meet electron used.
if (oldJitsiMeetElectronUsage()) {
return;
}
if (this.props._sources && !_.isEqual(this.props._sources, prevProps._sources)) {
const selectedSource = this._getSelectedSource(this.props._sources);
// update state with latest thumbnail desktop sources
this.setState({
sources: this.props._sources,
selectedSource
});
}
}
/**
* Implements React's {@link Component#render()}.
*
@@ -282,6 +308,7 @@ class DesktopPicker extends PureComponent<IProps, IState> {
_onCloseModal(id = '', type?: string, screenShareAudio = false) {
this.props.onSourceChoose(id, type, screenShareAudio);
this.props.dispatch(hideDialog());
this.props.dispatch(deleteDesktopSources());
}
/**
@@ -322,14 +349,14 @@ class DesktopPicker extends PureComponent<IProps, IState> {
_onTabSelected(id: string) {
const { sources } = this.state;
this._selectedTabType = id;
// When we change tabs also reset the screenShareAudio state so we don't
// use the option from one tab when sharing from another.
this.setState({
screenShareAudio: false,
selectedSource: this._getSelectedSource(sources),
selectedTab: id
// select type `window` or `screen` from id
selectedTab: id.split('-')[0]
});
}
@@ -406,24 +433,44 @@ class DesktopPicker extends PureComponent<IProps, IState> {
_updateSources() {
const { types } = this.state;
if (types.length > 0) {
obtainDesktopSources(
this.state.types,
{ thumbnailSize: THUMBNAIL_SIZE }
)
.then((sources: any) => {
const selectedSource = this._getSelectedSource(sources);
if (oldJitsiMeetElectronUsage()) {
// TODO: Maybe check if we have stopped the timer and unmounted
// the component.
this.setState({
sources,
selectedSource
});
})
.catch(() => { /* ignore */ });
if (types.length > 0) {
obtainDesktopSources(
this.state.types,
{ thumbnailSize: THUMBNAIL_SIZE }
)
.then((sources: any) => {
const selectedSource = this._getSelectedSource(sources);
this.setState({
sources,
selectedSource
});
})
.catch(() => { /* ignore */ });
}
} else {
APP.API.notifyRequestDesktopSources({
types,
thumbnailSize: THUMBNAIL_SIZE
});
}
}
}
export default translate(connect()(DesktopPicker));
/**
* Maps (parts of) the redux state to the React props.
*
* @param {Object} state - The redux state.
* @returns {{
* _sources: IDesktopPicker
* }}
*/
function _mapStateToProps(state: IReduxState) {
return {
_sources: getDesktopPickerSources(state)
};
}
export default translate(connect(_mapStateToProps)(DesktopPicker));

View File

@@ -74,12 +74,7 @@ class DesktopSourcePreview extends Component<IProps> {
className = { displayClasses }
onClick = { this._onClick }
onDoubleClick = { this._onDoubleClick }>
<div className = 'desktop-source-preview-image-container'>
<img
alt = { this.props.t('welcomepage.logo.desktopPreviewThumbnail') }
className = 'desktop-source-preview-thumbnail'
src = { this.props.source.thumbnail.toDataURL() } />
</div>
{this._renderThumbnailImageContainer()}
<div className = 'desktop-source-preview-label'>
{ this.props.source.name }
</div>
@@ -87,6 +82,43 @@ class DesktopSourcePreview extends Component<IProps> {
);
}
/**
* Render thumbnail screenshare image.
*
* @returns {Object} - Thumbnail image.
*/
_renderThumbnailImageContainer() {
// default data URL for thumnbail image
let srcImage = this.props.source.thumbnail.dataUrl;
// legacy thumbnail image
if (typeof this.props.source.thumbnail.toDataURL === 'function') {
srcImage = this.props.source.thumbnail.toDataURL();
}
return (
<div className = 'desktop-source-preview-image-container'>
{ this._renderThumbnailImage(srcImage) }
</div>
);
}
/**
* Render thumbnail screenshare image.
*
* @param {string} src - Of the image.
* @returns {Object} - Thumbnail image.
*/
_renderThumbnailImage(src: string) {
return (
<img
alt = { this.props.t('welcomepage.logo.desktopPreviewThumbnail') }
className = 'desktop-source-preview-thumbnail'
src = { src } />
);
}
/**
* Invokes the passed in onClick callback.
*