diff --git a/conference.js b/conference.js index a2c08d21e..e23ed7a5c 100644 --- a/conference.js +++ b/conference.js @@ -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} [options.desktopSharingSources] - Array with the + * sources that have to be displayed in the desktop picker window ('screen', + * 'window', etc.). * @return {Promise.} */ - 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, diff --git a/lang/main.json b/lang/main.json index aefe8a567..c78c11795 100644 --- a/lang/main.json +++ b/lang/main.json @@ -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", diff --git a/modules/remotecontrol/Receiver.js b/modules/remotecontrol/Receiver.js index 4b3c11607..2e225eece 100644 --- a/modules/remotecontrol/Receiver.js +++ b/modules/remotecontrol/Receiver.js @@ -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); }); } diff --git a/react/features/desktop-picker/actions.js b/react/features/desktop-picker/actions.js index 43d157d06..c8bed9774 100644 --- a/react/features/desktop-picker/actions.js +++ b/react/features/desktop-picker/actions.js @@ -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 }); } diff --git a/react/features/desktop-picker/components/DesktopPicker.js b/react/features/desktop-picker/components/DesktopPicker.js index 318d6a5c6..9b1a241a5 100644 --- a/react/features/desktop-picker/components/DesktopPicker.js +++ b/react/features/desktop-picker/components/DesktopPicker.js @@ -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: , - defaultSelected, - label: t(label) - }; - }); + = this.state.tabsToPopulate.map( + ({ defaultSelected, label, type }) => { + return { + content: , + defaultSelected, + label: t(label) + }; + }); return ; } @@ -248,6 +258,25 @@ class DesktopPicker extends Component { this._poller = null; } + /** + * Handles changing of allowed desktop sharing source types. + * + * @param {Array} 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 } diff --git a/react/features/remote-control/components/RemoteControlAuthorizationDialog.js b/react/features/remote-control/components/RemoteControlAuthorizationDialog.js index 796f7390c..a38d024a2 100644 --- a/react/features/remote-control/components/RemoteControlAuthorizationDialog.js +++ b/react/features/remote-control/components/RemoteControlAuthorizationDialog.js @@ -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; }