feat(remotecontrol): Make sure the receiver is always sharing entire screen

This commit is contained in:
hristoterezov 2017-07-09 16:34:08 -05:00
parent 1a9a8a2098
commit dc8198100b
6 changed files with 84 additions and 33 deletions

View File

@ -87,8 +87,8 @@ import {VIDEO_CONTAINER_TYPE} from "./modules/UI/videolayout/VideoContainer";
* lib-jitsi-meet to detect and invoke
*/
window.JitsiMeetScreenObtainer = {
openDesktopPicker(onSourceChoose) {
APP.store.dispatch(showDesktopPicker(onSourceChoose));
openDesktopPicker(options, onSourceChoose) {
APP.store.dispatch(showDesktopPicker(options, onSourceChoose));
}
};
@ -341,6 +341,7 @@ function createLocalTracks(options, checkForPermissionPrompt) {
.createLocalTracks({
// copy array to avoid mutations inside library
devices: options.devices.slice(0),
desktopSharingSources: options.desktopSharingSources,
resolution: config.resolution,
cameraDeviceId: typeof options.cameraDeviceId === 'undefined' ||
options.cameraDeviceId === null
@ -1108,9 +1109,14 @@ export default {
/**
* Toggles between screensharing and camera video.
* @param {boolean} [shareScreen]
* @param {Object} [options] - Screen sharing options that will be passed to
* createLocalTracks.
* @param {Array<string>} [options.desktopSharingSources] - Array with the
* sources that have to be displayed in the desktop picker window ('screen',
* 'window', etc.).
* @return {Promise.<T>}
*/
toggleScreenSharing(shareScreen = !this.isSharingScreen) {
toggleScreenSharing(shareScreen = !this.isSharingScreen, options = {}) {
if (this.videoSwitchInProgress) {
return Promise.reject('Switch in progress.');
}
@ -1130,6 +1136,7 @@ export default {
if (shareScreen) {
return createLocalTracks({
desktopSharingSources: options.desktopSharingSources,
devices: ['desktop'],
desktopSharingExtensionExternalInstallation: {
interval: 500,

View File

@ -340,6 +340,7 @@
"remoteControlDeniedMessage": "__user__ rejected your remote control request!",
"remoteControlAllowedMessage": "__user__ accepted your remote control request!",
"remoteControlErrorMessage": "An error occurred while trying to request remote control permissions from __user__!",
"startRemoteControlErrorMessage": "An error occurred while trying to start the remote control session!",
"remoteControlStopMessage": "The remote control session ended!",
"close": "Close",
"shareYourScreen": "Share your screen",

View File

@ -214,10 +214,15 @@ export default class Receiver extends RemoteControlParticipant {
let promise;
if (APP.conference.isSharingScreen) {
if (APP.conference.isSharingScreen
&& APP.conference.getDesktopSharingSourceType() === 'screen') {
promise = this._sendStartRequest();
} else {
promise = APP.conference.toggleScreenSharing()
promise = APP.conference.toggleScreenSharing(
true,
{
desktopSharingSources: [ 'screen' ]
})
.then(() => this._sendStartRequest());
}
@ -228,14 +233,20 @@ export default class Receiver extends RemoteControlParticipant {
action: PERMISSIONS_ACTIONS.grant
})
)
.catch(() => {
.catch(error => {
logger.error(error);
this.sendRemoteControlEndpointMessage(userId, {
type: EVENTS.permissions,
action: PERMISSIONS_ACTIONS.error
});
// FIXME: show err msg
this._stop();
APP.UI.messageHandler.openMessageDialog(
'dialog.remoteControlTitle',
'dialog.startRemoteControlErrorMessage'
);
this._stop(true);
});
}

View File

@ -62,12 +62,14 @@ export function resetDesktopSources() {
/**
* Signals to open a dialog with the DesktopPicker component.
*
* @param {Object} options - Desktop sharing settings.
* @param {Function} onSourceChoose - The callback to invoke when
* a DesktopCapturerSource has been chosen.
* @returns {Object}
*/
export function showDesktopPicker(onSourceChoose) {
export function showDesktopPicker(options, onSourceChoose) {
return openDialog(DesktopPicker, {
options,
onSourceChoose
});
}

View File

@ -1,5 +1,3 @@
/* global config */
import Tabs from '@atlaskit/tabs';
import React, { Component } from 'react';
import { connect } from 'react-redux';
@ -33,12 +31,7 @@ const TAB_CONFIGURATIONS = [
type: 'window'
}
];
const CONFIGURED_TYPES = config.desktopSharingChromeSources || [];
const VALID_TYPES = TAB_CONFIGURATIONS.map(c => c.type);
const TABS_TO_POPULATE
= TAB_CONFIGURATIONS.filter(
c => CONFIGURED_TYPES.includes(c.type) && VALID_TYPES.includes(c.type));
const TYPES_TO_FETCH = TABS_TO_POPULATE.map(c => c.type);
/**
* React component for DesktopPicker.
@ -63,6 +56,11 @@ class DesktopPicker extends Component {
*/
onSourceChoose: React.PropTypes.func,
/**
* An object with options related to desktop sharing.
*/
options: React.PropTypes.object,
/**
* An object with arrays of DesktopCapturerSources. The key should be
* the source type.
@ -85,7 +83,9 @@ class DesktopPicker extends Component {
super(props);
this.state = {
selectedSource: {}
selectedSource: {},
tabsToPopulate: [],
typesToFetch: []
};
this._poller = null;
@ -102,6 +102,10 @@ class DesktopPicker extends Component {
* @inheritdoc
*/
componentWillMount() {
const options = this.props.options || {};
this._onSourceTypesConfigChanged(
options.desktopSharingSources);
this._updateSources();
this._startPolling();
}
@ -125,6 +129,11 @@ class DesktopPicker extends Component {
}
});
}
const options = this.props.options || {};
this._onSourceTypesConfigChanged(
options.desktopSharingSources);
}
/**
@ -166,7 +175,7 @@ class DesktopPicker extends Component {
* the onSourceChoose callback.
* @returns {void}
*/
_onCloseModal(id, type) {
_onCloseModal(id = '', type) {
this.props.onSourceChoose(id, type);
this.props.dispatch(hideDialog());
}
@ -209,19 +218,20 @@ class DesktopPicker extends Component {
const { selectedSource } = this.state;
const { sources, t } = this.props;
const tabs
= TABS_TO_POPULATE.map(({ defaultSelected, label, type }) => {
return {
content: <DesktopPickerPane
key = { type }
onClick = { this._onPreviewClick }
onDoubleClick = { this._onCloseModal }
selectedSourceId = { selectedSource.id }
sources = { sources[type] || [] }
type = { type } />,
defaultSelected,
label: t(label)
};
});
= this.state.tabsToPopulate.map(
({ defaultSelected, label, type }) => {
return {
content: <DesktopPickerPane
key = { type }
onClick = { this._onPreviewClick }
onDoubleClick = { this._onCloseModal }
selectedSourceId = { selectedSource.id }
sources = { sources[type] || [] }
type = { type } />,
defaultSelected,
label: t(label)
};
});
return <Tabs tabs = { tabs } />;
}
@ -248,6 +258,25 @@ class DesktopPicker extends Component {
this._poller = null;
}
/**
* Handles changing of allowed desktop sharing source types.
*
* @param {Array<string>} desktopSharingSourceTypes - The types that will be
* fetched and displayed.
* @returns {void}
*/
_onSourceTypesConfigChanged(desktopSharingSourceTypes = []) {
const tabsToPopulate = TAB_CONFIGURATIONS.filter(
c => desktopSharingSourceTypes.includes(c.type)
&& VALID_TYPES.includes(c.type)
);
this.setState({
tabsToPopulate,
typesToFetch: tabsToPopulate.map(c => c.type)
});
}
/**
* Dispatches an action to get currently available DesktopCapturerSources.
*
@ -256,7 +285,7 @@ class DesktopPicker extends Component {
*/
_updateSources() {
this.props.dispatch(obtainDesktopSources(
TYPES_TO_FETCH,
this.state.typesToFetch,
{
THUMBNAIL_SIZE
}

View File

@ -94,7 +94,8 @@ class RemoteControlAuthorizationDialog extends Component {
_getAdditionalMessage() {
// FIXME: Once we have this information in redux we should
// start getting it from there.
if (APP.conference.isSharingScreen) {
if (APP.conference.isSharingScreen
&& APP.conference.getDesktopSharingSourceType() === 'screen') {
return null;
}