Added inline chrome extension install. Added screen sharing button. Added new actions to handle screen sharing.
parent
687e85c3ec
commit
56ce361e3c
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
if (window.antiglobal)
|
||||
{
|
||||
window.antiglobal('___browserSync___oldSocketIo', 'io', '___browserSync___', '__core-js_shared__');
|
||||
window.antiglobal('__multipartyMeetingScreenShareExtensionAvailable__', '___browserSync___oldSocketIo', 'io', '___browserSync___', '__core-js_shared__');
|
||||
setInterval(window.antiglobal, 180000);
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
@ -821,8 +839,13 @@ export default class RoomClient
|
|||
this._dispatch(stateActions.setMediaCapabilities(
|
||||
{
|
||||
canSendMic : this._room.canSend('audio'),
|
||||
canSendWebcam : this._room.canSend('video'),
|
||||
canShareScreen : this._room.canSend('video')
|
||||
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');
|
||||
|
|
|
|||
|
|
@ -64,6 +64,16 @@ class ChromeScreenShare
|
|||
return false;
|
||||
}
|
||||
|
||||
needExtension()
|
||||
{
|
||||
if ('__multipartyMeetingScreenShareExtensionAvailable__' in window)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
_toConstraints(options, streamId)
|
||||
{
|
||||
const constraints = {
|
||||
|
|
@ -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 }
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 83.208 83.208" style="enable-background:new 0 0 83.208 83.208;" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<polygon style="fill:#D80027;" points="25.052,69.154 17.894,76.312 53.683,76.312 46.525,69.154 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#D80027;" d="M64.419,6.896c-7.831,0-14.537,4.814-17.357,11.631H0v46.525h71.577v-22.01
|
||||
c6.814-2.82,11.631-9.53,11.631-17.357C83.208,15.325,74.78,6.896,64.419,6.896z M64.419,42.685c-9.373,0-17-7.627-17-17
|
||||
s7.627-17,17-17s17,7.627,17,17S73.792,42.685,64.419,42.685z"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon style="fill:#D80027;" points="66.338,29.372 67.068,14.258 61.764,14.258 62.533,29.372 "/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#D80027;" d="M64.434,31.039c-1.764,0-3.003,1.267-3.003,3.035c0,1.732,1.199,3.035,3.003,3.035
|
||||
c1.804,0,2.97-1.303,2.97-3.035C67.368,32.306,66.202,31.039,64.434,31.039z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
|
@ -234,20 +234,20 @@
|
|||
|
||||
&.screen {
|
||||
&.on {
|
||||
background-image: url('/resources/images/unshare-screen.svg');
|
||||
background-image: url('/resources/images/no-share-screen-black.svg');
|
||||
}
|
||||
|
||||
&.off {
|
||||
background-image: url('/resources/images/share-screen.svg');
|
||||
background-image: url('/resources/images/share-screen-black.svg');
|
||||
}
|
||||
|
||||
&.unsupported {
|
||||
background-image: url('/resources/images/unshare-screen.svg');
|
||||
background-image: url('/resources/images/no-share-screen-white.svg');
|
||||
background-color: rgba(#d42241, 0.7);
|
||||
}
|
||||
|
||||
&.need-extension {
|
||||
background-image: url('/resources/images/share-screen.svg');
|
||||
background-image: url('/resources/images/share-screen-extension.svg');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue