Added inline chrome extension install. Added screen sharing button. Added new actions to handle screen sharing.
This commit is contained in:
+62
-38
@@ -6,7 +6,6 @@ import { getProtooUrl } from './urlFactory';
|
||||
import * as cookiesManager from './cookiesManager';
|
||||
import * as requestActions from './redux/requestActions';
|
||||
import * as stateActions from './redux/stateActions';
|
||||
import { getBrowserType } from './utils';
|
||||
|
||||
const logger = new Logger('RoomClient');
|
||||
|
||||
@@ -81,8 +80,7 @@ export default class RoomClient
|
||||
// Local Webcam. Object with:
|
||||
// - {MediaDeviceInfo} [device]
|
||||
// - {String} [resolution] - 'qvga' / 'vga' / 'hd'.
|
||||
this._webcam =
|
||||
{
|
||||
this._webcam = {
|
||||
device : null,
|
||||
resolution : 'hd'
|
||||
};
|
||||
@@ -195,6 +193,57 @@ export default class RoomClient
|
||||
this._micProducer.resume();
|
||||
}
|
||||
|
||||
installExtension()
|
||||
{
|
||||
logger.debug('installExtension()');
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
{
|
||||
window.addEventListener('message', _onExtensionMessage, false);
|
||||
function _onExtensionMessage({ data })
|
||||
{
|
||||
if (data.type === 'ScreenShareInjected')
|
||||
{
|
||||
logger.debug('installExtension() | installation succeeded');
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function _failedInstall(reason)
|
||||
{
|
||||
window.removeEventListener('message', _onExtensionMessage);
|
||||
|
||||
return Promise.reject(
|
||||
new Error('Failed to install extension: %s', reason));
|
||||
}
|
||||
|
||||
function _successfulInstall()
|
||||
{
|
||||
logger.debug('installExtension() | installation accepted');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
chrome.webstore.install(null, _successfulInstall, _failedInstall);
|
||||
})
|
||||
.then(() =>
|
||||
{
|
||||
this._dispatch(stateActions.setScreenCapabilities(
|
||||
{
|
||||
canShareScreen : true,
|
||||
needExtension : false
|
||||
}));
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('enableScreenSharing() | failed: %o', error);
|
||||
|
||||
this._dispatch(
|
||||
stateActions.setScreenShareInProgress(false));
|
||||
});
|
||||
}
|
||||
|
||||
enableScreenSharing()
|
||||
{
|
||||
logger.debug('enableScreenSharing()');
|
||||
@@ -203,37 +252,6 @@ export default class RoomClient
|
||||
stateActions.setScreenShareInProgress(true));
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
{
|
||||
const browser = getBrowserType();
|
||||
|
||||
switch (browser)
|
||||
{
|
||||
case 'chrome':
|
||||
{
|
||||
// Check if we have extension, if not, try to install
|
||||
// if (!('__multipartyMeetingScreenShareExtensionAvailable__' in window))
|
||||
// {
|
||||
// window.addEventListener('message', function(ev)
|
||||
// {
|
||||
// if (ev.data.type === 'ScreenShareInjected')
|
||||
// {
|
||||
// }
|
||||
// }, false);
|
||||
// }
|
||||
break;
|
||||
}
|
||||
case 'firefox':
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return Promise.reject(
|
||||
new Error('Unsupported browser for screen sharing'));
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() =>
|
||||
{
|
||||
return this._setScreenShareProducer();
|
||||
@@ -820,9 +838,14 @@ export default class RoomClient
|
||||
// Set our media capabilities.
|
||||
this._dispatch(stateActions.setMediaCapabilities(
|
||||
{
|
||||
canSendMic : this._room.canSend('audio'),
|
||||
canSendWebcam : this._room.canSend('video'),
|
||||
canShareScreen : this._room.canSend('video')
|
||||
canSendMic : this._room.canSend('audio'),
|
||||
canSendWebcam : this._room.canSend('video')
|
||||
}));
|
||||
this._dispatch(stateActions.setScreenCapabilities(
|
||||
{
|
||||
canShareScreen : this._room.canSend('video') &&
|
||||
this._screenSharing.isScreenShareAvailable(),
|
||||
needExtension : this._screenSharing.needExtension()
|
||||
}));
|
||||
})
|
||||
.then(() =>
|
||||
@@ -1007,7 +1030,8 @@ export default class RoomClient
|
||||
return Promise.resolve()
|
||||
.then(() =>
|
||||
{
|
||||
const available = this._screenSharing.isScreenShareAvailable();
|
||||
const available = this._screenSharing.isScreenShareAvailable() &&
|
||||
!this._screenSharing.needExtension();
|
||||
|
||||
if (!available)
|
||||
throw new Error('screen sharing not available');
|
||||
|
||||
@@ -63,6 +63,16 @@ class ChromeScreenShare
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
needExtension()
|
||||
{
|
||||
if ('__multipartyMeetingScreenShareExtensionAvailable__' in window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_toConstraints(options, streamId)
|
||||
{
|
||||
@@ -135,6 +145,11 @@ class FirefoxScreenShare
|
||||
return true;
|
||||
}
|
||||
|
||||
needExtension()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_toConstraints(options)
|
||||
{
|
||||
const constraints = {
|
||||
|
||||
@@ -20,12 +20,27 @@ class Room extends React.Component
|
||||
room,
|
||||
me,
|
||||
amActiveSpeaker,
|
||||
screenProducer,
|
||||
onRoomLinkCopy,
|
||||
onSetAudioMode,
|
||||
onRestartIce,
|
||||
onLeaveMeeting
|
||||
onLeaveMeeting,
|
||||
onShareScreen,
|
||||
onUnShareScreen,
|
||||
onNeedExtension
|
||||
} = this.props;
|
||||
|
||||
let screenState;
|
||||
|
||||
if (me.needExtension)
|
||||
screenState = 'need-extension';
|
||||
else if (!me.canShareScreen)
|
||||
screenState = 'unsupported';
|
||||
else if (screenProducer)
|
||||
screenState = 'on';
|
||||
else
|
||||
screenState = 'off';
|
||||
|
||||
return (
|
||||
<Appear duration={300}>
|
||||
<div data-component='Room'>
|
||||
@@ -79,6 +94,37 @@ class Room extends React.Component
|
||||
</div>
|
||||
|
||||
<div className='sidebar'>
|
||||
<div
|
||||
className={classnames('button', 'screen', screenState)}
|
||||
data-tip='Toggle screen sharing'
|
||||
data-type='dark'
|
||||
onClick={() =>
|
||||
{
|
||||
switch (screenState)
|
||||
{
|
||||
case 'on':
|
||||
{
|
||||
onUnShareScreen();
|
||||
break;
|
||||
}
|
||||
case 'off':
|
||||
{
|
||||
onShareScreen();
|
||||
break;
|
||||
}
|
||||
case 'need-extension':
|
||||
{
|
||||
onNeedExtension();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'audio-only', {
|
||||
on : me.audioOnly,
|
||||
@@ -122,18 +168,27 @@ Room.propTypes =
|
||||
room : appPropTypes.Room.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
amActiveSpeaker : PropTypes.bool.isRequired,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
onRoomLinkCopy : PropTypes.func.isRequired,
|
||||
onSetAudioMode : PropTypes.func.isRequired,
|
||||
onRestartIce : PropTypes.func.isRequired,
|
||||
onLeaveMeeting : PropTypes.func.isRequired
|
||||
onLeaveMeeting : PropTypes.func.isRequired,
|
||||
onShareScreen : PropTypes.func.isRequired,
|
||||
onUnShareScreen : PropTypes.func.isRequired,
|
||||
onNeedExtension : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
{
|
||||
const producersArray = Object.values(state.producers);
|
||||
const screenProducer =
|
||||
producersArray.find((producer) => producer.source === 'screen');
|
||||
|
||||
return {
|
||||
room : state.room,
|
||||
me : state.me,
|
||||
amActiveSpeaker : state.me.name === state.room.activeSpeakerName
|
||||
amActiveSpeaker : state.me.name === state.room.activeSpeakerName,
|
||||
screenProducer : screenProducer
|
||||
};
|
||||
};
|
||||
|
||||
@@ -161,6 +216,18 @@ const mapDispatchToProps = (dispatch) =>
|
||||
onLeaveMeeting : () =>
|
||||
{
|
||||
dispatch(requestActions.leaveRoom());
|
||||
},
|
||||
onShareScreen : () =>
|
||||
{
|
||||
dispatch(requestActions.enableScreenSharing());
|
||||
},
|
||||
onUnShareScreen : () =>
|
||||
{
|
||||
dispatch(requestActions.disableScreenSharing());
|
||||
},
|
||||
onNeedExtension : () =>
|
||||
{
|
||||
dispatch(requestActions.installExtension());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -6,7 +6,8 @@ const initialState =
|
||||
device : null,
|
||||
canSendMic : false,
|
||||
canSendWebcam : false,
|
||||
canShareScreen : true,
|
||||
canShareScreen : false,
|
||||
needExtension : false,
|
||||
canChangeWebcam : false,
|
||||
webcamInProgress : false,
|
||||
screenShareInProgress : false,
|
||||
@@ -28,9 +29,16 @@ const me = (state = initialState, action) =>
|
||||
|
||||
case 'SET_MEDIA_CAPABILITIES':
|
||||
{
|
||||
const { canSendMic, canSendWebcam, canShareScreen } = action.payload;
|
||||
const { canSendMic, canSendWebcam } = action.payload;
|
||||
|
||||
return { ...state, canSendMic, canSendWebcam, canShareScreen };
|
||||
return { ...state, canSendMic, canSendWebcam };
|
||||
}
|
||||
|
||||
case 'SET_SCREEN_CAPABILITIES':
|
||||
{
|
||||
const { canShareScreen, needExtension } = action.payload;
|
||||
|
||||
return { ...state, canShareScreen, needExtension };
|
||||
}
|
||||
|
||||
case 'SET_CAN_CHANGE_WEBCAM':
|
||||
|
||||
@@ -99,6 +99,13 @@ export const disableScreenSharing = () =>
|
||||
};
|
||||
};
|
||||
|
||||
export const installExtension = () =>
|
||||
{
|
||||
return {
|
||||
type : 'INSTALL_EXTENSION'
|
||||
};
|
||||
};
|
||||
|
||||
export const sendChatMessage = (text, name) =>
|
||||
{
|
||||
const message = createNewMessage(text, 'response', name);
|
||||
|
||||
@@ -123,6 +123,13 @@ export default ({ dispatch, getState }) => (next) =>
|
||||
break;
|
||||
}
|
||||
|
||||
case 'INSTALL_EXTENSION':
|
||||
{
|
||||
client.installExtension();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'SEND_CHAT_MESSAGE':
|
||||
{
|
||||
const { message } = action.payload;
|
||||
|
||||
@@ -30,11 +30,19 @@ export const setMe = ({ peerName, displayName, displayNameSet, device }) =>
|
||||
};
|
||||
};
|
||||
|
||||
export const setMediaCapabilities = ({ canSendMic, canSendWebcam, canShareScreen }) =>
|
||||
export const setMediaCapabilities = ({ canSendMic, canSendWebcam }) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_MEDIA_CAPABILITIES',
|
||||
payload : { canSendMic, canSendWebcam, canShareScreen }
|
||||
payload : { canSendMic, canSendWebcam }
|
||||
};
|
||||
};
|
||||
|
||||
export const setScreenCapabilities = ({ canShareScreen, needExtension }) =>
|
||||
{
|
||||
return {
|
||||
type : 'SET_SCREEN_CAPABILITIES',
|
||||
payload : { canShareScreen, needExtension }
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user