Major cleanup
parent
fa91d9b9e2
commit
60fb9c735e
|
|
@ -2,6 +2,7 @@
|
|||
"plugins":
|
||||
[
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"jsx-control-statements",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-transform-runtime"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ module.exports =
|
|||
extends:
|
||||
[
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended'
|
||||
'plugin:react/recommended',
|
||||
'plugin:jsx-control-statements/recommended'
|
||||
],
|
||||
settings:
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,10 +30,21 @@ const VIDEO_CONSTRAINS =
|
|||
aspectRatio : 1.334
|
||||
};
|
||||
|
||||
let store;
|
||||
|
||||
export default class RoomClient
|
||||
{
|
||||
/**
|
||||
* @param {Object} data
|
||||
* @param {Object} data.store - The Redux store.
|
||||
*/
|
||||
static init(data)
|
||||
{
|
||||
store = data.store;
|
||||
}
|
||||
|
||||
constructor(
|
||||
{ roomId, peerName, displayName, device, useSimulcast, produce, dispatch, getState })
|
||||
{ roomId, peerName, displayName, device, useSimulcast, produce })
|
||||
{
|
||||
logger.debug(
|
||||
'constructor() [roomId:"%s", peerName:"%s", displayName:"%s", device:%s]',
|
||||
|
|
@ -53,12 +64,6 @@ export default class RoomClient
|
|||
// Whether simulcast should be used.
|
||||
this._useSimulcast = useSimulcast;
|
||||
|
||||
// Redux store dispatch function.
|
||||
this._dispatch = dispatch;
|
||||
|
||||
// Redux store getState function.
|
||||
this._getState = getState;
|
||||
|
||||
// This device
|
||||
this._device = device;
|
||||
|
||||
|
|
@ -139,7 +144,7 @@ export default class RoomClient
|
|||
// the 'leaveRoom' notification).
|
||||
setTimeout(() => this._signalingSocket.close(), 250);
|
||||
|
||||
this._dispatch(stateActions.setRoomState('closed'));
|
||||
store.dispatch(stateActions.setRoomState('closed'));
|
||||
}
|
||||
|
||||
_startKeyListener()
|
||||
|
|
@ -161,21 +166,21 @@ export default class RoomClient
|
|||
{
|
||||
case 'a': // Activate advanced mode
|
||||
{
|
||||
this._dispatch(stateActions.toggleAdvancedMode());
|
||||
store.dispatch(stateActions.toggleAdvancedMode());
|
||||
this.notify('Toggled advanced mode.');
|
||||
break;
|
||||
}
|
||||
|
||||
case '1': // Set democratic view
|
||||
{
|
||||
this._dispatch(stateActions.setDisplayMode('democratic'));
|
||||
store.dispatch(stateActions.setDisplayMode('democratic'));
|
||||
this.notify('Changed layout to democratic view.');
|
||||
break;
|
||||
}
|
||||
|
||||
case '2': // Set filmstrip view
|
||||
{
|
||||
this._dispatch(stateActions.setDisplayMode('filmstrip'));
|
||||
store.dispatch(stateActions.setDisplayMode('filmstrip'));
|
||||
this.notify('Changed layout to filmstrip view.');
|
||||
break;
|
||||
}
|
||||
|
|
@ -225,7 +230,7 @@ export default class RoomClient
|
|||
|
||||
notify(text)
|
||||
{
|
||||
this._dispatch(requestActions.notify({ text: text }));
|
||||
store.dispatch(requestActions.notify({ text: text }));
|
||||
}
|
||||
|
||||
timeoutCallback(callback)
|
||||
|
|
@ -290,7 +295,7 @@ export default class RoomClient
|
|||
{
|
||||
await this.sendRequest('change-display-name', { displayName });
|
||||
|
||||
this._dispatch(stateActions.setDisplayName(displayName));
|
||||
store.dispatch(stateActions.setDisplayName(displayName));
|
||||
|
||||
this.notify(`Your display name changed to ${displayName}.`);
|
||||
}
|
||||
|
|
@ -302,7 +307,7 @@ export default class RoomClient
|
|||
|
||||
// We need to refresh the component for it to render the previous
|
||||
// displayName again.
|
||||
this._dispatch(stateActions.setDisplayName());
|
||||
store.dispatch(stateActions.setDisplayName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -326,6 +331,9 @@ export default class RoomClient
|
|||
|
||||
try
|
||||
{
|
||||
store.dispatch(
|
||||
stateActions.addUserMessage(chatMessage.text));
|
||||
|
||||
await this.sendRequest('chat-message', { chatMessage });
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -367,7 +375,7 @@ export default class RoomClient
|
|||
if (chatHistory.length > 0)
|
||||
{
|
||||
logger.debug('Got chat history');
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.addChatHistory(chatHistory));
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +383,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('Got files history');
|
||||
|
||||
this._dispatch(stateActions.addFileHistory(fileHistory));
|
||||
store.dispatch(stateActions.addFileHistory(fileHistory));
|
||||
}
|
||||
|
||||
if (lastN.length > 0)
|
||||
|
|
@ -466,7 +474,7 @@ export default class RoomClient
|
|||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
window.addEventListener('message', _onExtensionMessage, false);
|
||||
// eslint-disable-next-line no-undef
|
||||
// eslint-disable-next-line
|
||||
chrome.webstore.install(null, _successfulInstall, _failedInstall);
|
||||
function _onExtensionMessage({ data })
|
||||
{
|
||||
|
|
@ -494,7 +502,7 @@ export default class RoomClient
|
|||
.then(() =>
|
||||
{
|
||||
// This should be handled better
|
||||
this._dispatch(stateActions.setScreenCapabilities(
|
||||
store.dispatch(stateActions.setScreenCapabilities(
|
||||
{
|
||||
canShareScreen : this._room.canSend('video'),
|
||||
needExtension : false
|
||||
|
|
@ -510,7 +518,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('enableScreenSharing()');
|
||||
|
||||
this._dispatch(stateActions.setScreenShareInProgress(true));
|
||||
store.dispatch(stateActions.setScreenShareInProgress(true));
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -521,7 +529,7 @@ export default class RoomClient
|
|||
logger.error('enableScreenSharing() | failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.setScreenShareInProgress(false));
|
||||
store.dispatch(stateActions.setScreenShareInProgress(false));
|
||||
}
|
||||
|
||||
async enableWebcam()
|
||||
|
|
@ -531,7 +539,7 @@ export default class RoomClient
|
|||
// Store in cookie.
|
||||
cookiesManager.setDevices({ webcamEnabled: true });
|
||||
|
||||
this._dispatch(stateActions.setWebcamInProgress(true));
|
||||
store.dispatch(stateActions.setWebcamInProgress(true));
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -542,14 +550,14 @@ export default class RoomClient
|
|||
logger.error('enableWebcam() | failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.setWebcamInProgress(false));
|
||||
store.dispatch(stateActions.setWebcamInProgress(false));
|
||||
}
|
||||
|
||||
async disableScreenSharing()
|
||||
{
|
||||
logger.debug('disableScreenSharing()');
|
||||
|
||||
this._dispatch(stateActions.setScreenShareInProgress(true));
|
||||
store.dispatch(stateActions.setScreenShareInProgress(true));
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -560,7 +568,7 @@ export default class RoomClient
|
|||
logger.error('disableScreenSharing() | failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.setScreenShareInProgress(false));
|
||||
store.dispatch(stateActions.setScreenShareInProgress(false));
|
||||
}
|
||||
|
||||
async disableWebcam()
|
||||
|
|
@ -570,7 +578,7 @@ export default class RoomClient
|
|||
// Store in cookie.
|
||||
cookiesManager.setDevices({ webcamEnabled: false });
|
||||
|
||||
this._dispatch(stateActions.setWebcamInProgress(true));
|
||||
store.dispatch(stateActions.setWebcamInProgress(true));
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -581,14 +589,14 @@ export default class RoomClient
|
|||
logger.error('disableWebcam() | failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.setWebcamInProgress(false));
|
||||
store.dispatch(stateActions.setWebcamInProgress(false));
|
||||
}
|
||||
|
||||
async changeAudioDevice(deviceId)
|
||||
{
|
||||
logger.debug('changeAudioDevice() [deviceId: %s]', deviceId);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -642,13 +650,13 @@ export default class RoomClient
|
|||
if (volume !== this._micProducer.volume)
|
||||
{
|
||||
this._micProducer.volume = volume;
|
||||
this._dispatch(stateActions.setProducerVolume(this._micProducer.id, volume));
|
||||
store.dispatch(stateActions.setProducerVolume(this._micProducer.id, volume));
|
||||
}
|
||||
});
|
||||
|
||||
track.stop();
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setProducerTrack(this._micProducer.id, newTrack));
|
||||
|
||||
cookiesManager.setAudioDevice({ audioDeviceId: deviceId });
|
||||
|
|
@ -660,7 +668,7 @@ export default class RoomClient
|
|||
logger.error('changeAudioDevice() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -668,7 +676,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('changeWebcam() [deviceId: %s]', deviceId);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setWebcamInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -704,7 +712,7 @@ export default class RoomClient
|
|||
|
||||
track.stop();
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setProducerTrack(this._webcamProducer.id, newTrack));
|
||||
|
||||
cookiesManager.setVideoDevice({ videoDeviceId: deviceId });
|
||||
|
|
@ -716,7 +724,7 @@ export default class RoomClient
|
|||
logger.error('changeWebcam() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setWebcamInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +735,7 @@ export default class RoomClient
|
|||
let oldResolution;
|
||||
let newResolution;
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setWebcamInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -768,7 +776,7 @@ export default class RoomClient
|
|||
|
||||
track.stop();
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setProducerTrack(this._webcamProducer.id, newTrack));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -778,7 +786,7 @@ export default class RoomClient
|
|||
this._webcam.resolution = oldResolution;
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setWebcamInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -788,7 +796,7 @@ export default class RoomClient
|
|||
|
||||
this._spotlights.setPeerSpotlight(peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setSelectedPeer(peerName));
|
||||
}
|
||||
|
||||
|
|
@ -796,7 +804,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('mutePeerAudio() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerAudioInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -820,7 +828,7 @@ export default class RoomClient
|
|||
logger.error('mutePeerAudio() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerAudioInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -828,7 +836,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('unmutePeerAudio() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerAudioInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -852,7 +860,7 @@ export default class RoomClient
|
|||
logger.error('unmutePeerAudio() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerAudioInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -860,7 +868,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('pausePeerVideo() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerVideoInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -884,7 +892,7 @@ export default class RoomClient
|
|||
logger.error('pausePeerVideo() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerVideoInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -892,7 +900,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('resumePeerVideo() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerVideoInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -916,7 +924,7 @@ export default class RoomClient
|
|||
logger.error('resumePeerVideo() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerVideoInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -924,7 +932,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('pausePeerScreen() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerScreenInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -948,7 +956,7 @@ export default class RoomClient
|
|||
logger.error('pausePeerScreen() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerScreenInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -956,7 +964,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('resumePeerScreen() [peerName:"%s"]', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerScreenInProgress(peerName, true));
|
||||
|
||||
try
|
||||
|
|
@ -980,7 +988,7 @@ export default class RoomClient
|
|||
logger.error('resumePeerScreen() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerScreenInProgress(peerName, false));
|
||||
}
|
||||
|
||||
|
|
@ -988,7 +996,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('enableAudioOnly()');
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -1007,7 +1015,7 @@ export default class RoomClient
|
|||
}
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyState(true));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -1015,7 +1023,7 @@ export default class RoomClient
|
|||
logger.error('enableAudioOnly() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -1023,7 +1031,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('disableAudioOnly()');
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -1042,7 +1050,7 @@ export default class RoomClient
|
|||
}
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyState(false));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -1050,7 +1058,7 @@ export default class RoomClient
|
|||
logger.error('disableAudioOnly() failed: %o', error);
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioOnlyInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -1058,14 +1066,14 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('sendRaiseHandState: ', state);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setMyRaiseHandStateInProgress(true));
|
||||
|
||||
try
|
||||
{
|
||||
await this.sendRequest('raisehand-message', { raiseHandState: state });
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setMyRaiseHandState(state));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -1075,10 +1083,10 @@ export default class RoomClient
|
|||
this.notify(`An error occured while ${state ? 'raising' : 'lowering'} hand.`);
|
||||
|
||||
// We need to refresh the component for it to render changed state
|
||||
this._dispatch(stateActions.setMyRaiseHandState(!state));
|
||||
store.dispatch(stateActions.setMyRaiseHandState(!state));
|
||||
}
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setMyRaiseHandStateInProgress(false));
|
||||
}
|
||||
|
||||
|
|
@ -1086,7 +1094,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.debug('restartIce()');
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setRestartIceInProgress(true));
|
||||
|
||||
try
|
||||
|
|
@ -1101,14 +1109,14 @@ export default class RoomClient
|
|||
// Make it artificially longer.
|
||||
setTimeout(() =>
|
||||
{
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setRestartIceInProgress(false));
|
||||
}, 500);
|
||||
}
|
||||
|
||||
_join({ displayName, device })
|
||||
{
|
||||
this._dispatch(stateActions.setRoomState('connecting'));
|
||||
store.dispatch(stateActions.setRoomState('connecting'));
|
||||
|
||||
this._signalingSocket.on('connect', () =>
|
||||
{
|
||||
|
|
@ -1127,7 +1135,7 @@ export default class RoomClient
|
|||
try { this._room.remoteClose({ cause: 'signaling disconnected' }); }
|
||||
catch (error) {}
|
||||
|
||||
this._dispatch(stateActions.setRoomState('connecting'));
|
||||
store.dispatch(stateActions.setRoomState('connecting'));
|
||||
});
|
||||
|
||||
this._signalingSocket.on('close', () =>
|
||||
|
|
@ -1151,7 +1159,7 @@ export default class RoomClient
|
|||
{
|
||||
const { peerName } = data;
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setRoomActiveSpeaker(peerName));
|
||||
|
||||
if (peerName && peerName !== this._peerName)
|
||||
|
|
@ -1177,7 +1185,7 @@ export default class RoomClient
|
|||
|
||||
peer.appData.displayName = displayName;
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerDisplayName(displayName, peerName));
|
||||
|
||||
this.notify(`${oldDisplayName} changed their display name to ${displayName}.`);
|
||||
|
|
@ -1187,7 +1195,7 @@ export default class RoomClient
|
|||
{
|
||||
const { peerName, picture } = data;
|
||||
|
||||
this._dispatch(stateActions.setPeerPicture(peerName, picture));
|
||||
store.dispatch(stateActions.setPeerPicture(peerName, picture));
|
||||
});
|
||||
|
||||
// This means: server wants to change MY user information
|
||||
|
|
@ -1198,8 +1206,8 @@ export default class RoomClient
|
|||
this.changeDisplayName(data.name);
|
||||
|
||||
this.changeProfilePicture(data.picture);
|
||||
this._dispatch(stateActions.setPicture(data.picture));
|
||||
this._dispatch(stateActions.loggedIn());
|
||||
store.dispatch(stateActions.setPicture(data.picture));
|
||||
store.dispatch(stateActions.loggedIn());
|
||||
|
||||
this.notify('You are logged in.');
|
||||
|
||||
|
|
@ -1224,7 +1232,7 @@ export default class RoomClient
|
|||
|
||||
this.notify(`${peer.appData.displayName} ${raiseHandState ? 'raised' : 'lowered'} their hand.`);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setPeerRaiseHandState(peerName, raiseHandState));
|
||||
});
|
||||
|
||||
|
|
@ -1234,12 +1242,12 @@ export default class RoomClient
|
|||
|
||||
logger.debug('Got chat from "%s"', peerName);
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.addResponseMessage({ ...chatMessage, peerName }));
|
||||
|
||||
if (!this._getState().toolarea.toolAreaOpen ||
|
||||
(this._getState().toolarea.toolAreaOpen &&
|
||||
this._getState().toolarea.currentToolTab !== 'chat')) // Make sound
|
||||
if (!store.getState().toolarea.toolAreaOpen ||
|
||||
(store.getState().toolarea.toolAreaOpen &&
|
||||
store.getState().toolarea.currentToolTab !== 'chat')) // Make sound
|
||||
{
|
||||
this._soundNotification();
|
||||
}
|
||||
|
|
@ -1259,13 +1267,13 @@ export default class RoomClient
|
|||
return;
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.addFile(file));
|
||||
store.dispatch(stateActions.addFile(file));
|
||||
|
||||
this.notify(`${peer.appData.displayName} shared a file.`);
|
||||
|
||||
if (!this._getState().toolarea.toolAreaOpen ||
|
||||
(this._getState().toolarea.toolAreaOpen &&
|
||||
this._getState().toolarea.currentToolTab !== 'files')) // Make sound
|
||||
if (!store.getState().toolarea.toolAreaOpen ||
|
||||
(store.getState().toolarea.toolAreaOpen &&
|
||||
store.getState().toolarea.currentToolTab !== 'files')) // Make sound
|
||||
{
|
||||
this._soundNotification();
|
||||
}
|
||||
|
|
@ -1287,7 +1295,7 @@ export default class RoomClient
|
|||
{
|
||||
logger.warn('mediasoup Peer/Room remotely closed [appData:%o]', appData);
|
||||
|
||||
this._dispatch(stateActions.setRoomState('closed'));
|
||||
store.dispatch(stateActions.setRoomState('closed'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1350,12 +1358,12 @@ export default class RoomClient
|
|||
});
|
||||
|
||||
// Set our media capabilities.
|
||||
this._dispatch(stateActions.setMediaCapabilities(
|
||||
store.dispatch(stateActions.setMediaCapabilities(
|
||||
{
|
||||
canSendMic : this._room.canSend('audio'),
|
||||
canSendWebcam : this._room.canSend('video')
|
||||
}));
|
||||
this._dispatch(stateActions.setScreenCapabilities(
|
||||
store.dispatch(stateActions.setScreenCapabilities(
|
||||
{
|
||||
canShareScreen : this._room.canSend('video') &&
|
||||
this._screenSharing.isScreenShareAvailable(),
|
||||
|
|
@ -1378,10 +1386,10 @@ export default class RoomClient
|
|||
}
|
||||
}
|
||||
|
||||
this._dispatch(stateActions.setRoomState('connected'));
|
||||
store.dispatch(stateActions.setRoomState('connected'));
|
||||
|
||||
// Clean all the existing notifcations.
|
||||
this._dispatch(stateActions.removeAllNotifications());
|
||||
store.dispatch(stateActions.removeAllNotifications());
|
||||
|
||||
this.getServerHistory();
|
||||
|
||||
|
|
@ -1389,7 +1397,7 @@ export default class RoomClient
|
|||
|
||||
this._spotlights.on('spotlights-updated', (spotlights) =>
|
||||
{
|
||||
this._dispatch(stateActions.setSpotlights(spotlights));
|
||||
store.dispatch(stateActions.setSpotlights(spotlights));
|
||||
this.updateSpotlights(spotlights);
|
||||
});
|
||||
|
||||
|
|
@ -1440,7 +1448,7 @@ export default class RoomClient
|
|||
|
||||
this._micProducer = producer;
|
||||
|
||||
this._dispatch(stateActions.addProducer(
|
||||
store.dispatch(stateActions.addProducer(
|
||||
{
|
||||
id : producer.id,
|
||||
source : 'mic',
|
||||
|
|
@ -1460,7 +1468,7 @@ export default class RoomClient
|
|||
'mic Producer "close" event [originator:%s]', originator);
|
||||
|
||||
this._micProducer = null;
|
||||
this._dispatch(stateActions.removeProducer(producer.id));
|
||||
store.dispatch(stateActions.removeProducer(producer.id));
|
||||
});
|
||||
|
||||
producer.on('pause', (originator) =>
|
||||
|
|
@ -1468,7 +1476,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'mic Producer "pause" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('resume', (originator) =>
|
||||
|
|
@ -1476,7 +1484,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'mic Producer "resume" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('handled', () =>
|
||||
|
|
@ -1512,7 +1520,7 @@ export default class RoomClient
|
|||
if (volume !== producer.volume)
|
||||
{
|
||||
producer.volume = volume;
|
||||
this._dispatch(stateActions.setProducerVolume(producer.id, volume));
|
||||
store.dispatch(stateActions.setProducerVolume(producer.id, volume));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1565,7 +1573,7 @@ export default class RoomClient
|
|||
|
||||
this._screenSharingProducer = producer;
|
||||
|
||||
this._dispatch(stateActions.addProducer(
|
||||
store.dispatch(stateActions.addProducer(
|
||||
{
|
||||
id : producer.id,
|
||||
source : 'screen',
|
||||
|
|
@ -1583,7 +1591,7 @@ export default class RoomClient
|
|||
'webcam Producer "close" event [originator:%s]', originator);
|
||||
|
||||
this._screenSharingProducer = null;
|
||||
this._dispatch(stateActions.removeProducer(producer.id));
|
||||
store.dispatch(stateActions.removeProducer(producer.id));
|
||||
});
|
||||
|
||||
producer.on('trackended', (originator) =>
|
||||
|
|
@ -1599,7 +1607,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'webcam Producer "pause" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('resume', (originator) =>
|
||||
|
|
@ -1607,7 +1615,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'webcam Producer "resume" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('handled', () =>
|
||||
|
|
@ -1677,7 +1685,7 @@ export default class RoomClient
|
|||
|
||||
this._webcamProducer = producer;
|
||||
|
||||
this._dispatch(stateActions.addProducer(
|
||||
store.dispatch(stateActions.addProducer(
|
||||
{
|
||||
id : producer.id,
|
||||
source : 'webcam',
|
||||
|
|
@ -1696,7 +1704,7 @@ export default class RoomClient
|
|||
'webcam Producer "close" event [originator:%s]', originator);
|
||||
|
||||
this._webcamProducer = null;
|
||||
this._dispatch(stateActions.removeProducer(producer.id));
|
||||
store.dispatch(stateActions.removeProducer(producer.id));
|
||||
});
|
||||
|
||||
producer.on('pause', (originator) =>
|
||||
|
|
@ -1704,7 +1712,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'webcam Producer "pause" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerPaused(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('resume', (originator) =>
|
||||
|
|
@ -1712,7 +1720,7 @@ export default class RoomClient
|
|||
logger.debug(
|
||||
'webcam Producer "resume" event [originator:%s]', originator);
|
||||
|
||||
this._dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
store.dispatch(stateActions.setProducerResumed(producer.id, originator));
|
||||
});
|
||||
|
||||
producer.on('handled', () =>
|
||||
|
|
@ -1775,10 +1783,10 @@ export default class RoomClient
|
|||
else if (!this._audioDevices.has(currentAudioDeviceId))
|
||||
this._audioDevice.device = array[0];
|
||||
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setCanChangeAudioDevice(len >= 2));
|
||||
if (len >= 1)
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setAudioDevices(this._audioDevices));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -1823,7 +1831,7 @@ export default class RoomClient
|
|||
this._webcam.device = array[0];
|
||||
|
||||
if (len >= 1)
|
||||
this._dispatch(
|
||||
store.dispatch(
|
||||
stateActions.setWebcamDevices(this._webcams));
|
||||
}
|
||||
catch (error)
|
||||
|
|
@ -1836,7 +1844,7 @@ export default class RoomClient
|
|||
{
|
||||
const displayName = peer.appData.displayName;
|
||||
|
||||
this._dispatch(stateActions.addPeer(
|
||||
store.dispatch(stateActions.addPeer(
|
||||
{
|
||||
name : peer.name,
|
||||
displayName : displayName,
|
||||
|
|
@ -1861,7 +1869,7 @@ export default class RoomClient
|
|||
'peer "close" event [name:"%s", originator:%s]',
|
||||
peer.name, originator);
|
||||
|
||||
this._dispatch(stateActions.removePeer(peer.name));
|
||||
store.dispatch(stateActions.removePeer(peer.name));
|
||||
|
||||
if (this._room.joined)
|
||||
{
|
||||
|
|
@ -1883,7 +1891,7 @@ export default class RoomClient
|
|||
{
|
||||
const codec = consumer.rtpParameters.codecs[0];
|
||||
|
||||
this._dispatch(stateActions.addConsumer(
|
||||
store.dispatch(stateActions.addConsumer(
|
||||
{
|
||||
id : consumer.id,
|
||||
peerName : consumer.peer.name,
|
||||
|
|
@ -1903,7 +1911,7 @@ export default class RoomClient
|
|||
'consumer "close" event [id:%s, originator:%s, consumer:%o]',
|
||||
consumer.id, originator, consumer);
|
||||
|
||||
this._dispatch(stateActions.removeConsumer(
|
||||
store.dispatch(stateActions.removeConsumer(
|
||||
consumer.id, consumer.peer.name));
|
||||
});
|
||||
|
||||
|
|
@ -1938,7 +1946,7 @@ export default class RoomClient
|
|||
if (volume !== consumer.volume)
|
||||
{
|
||||
consumer.volume = volume;
|
||||
this._dispatch(stateActions.setConsumerVolume(consumer.id, volume));
|
||||
store.dispatch(stateActions.setConsumerVolume(consumer.id, volume));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1950,7 +1958,7 @@ export default class RoomClient
|
|||
'consumer "pause" event [id:%s, originator:%s, consumer:%o]',
|
||||
consumer.id, originator, consumer);
|
||||
|
||||
this._dispatch(stateActions.setConsumerPaused(consumer.id, originator));
|
||||
store.dispatch(stateActions.setConsumerPaused(consumer.id, originator));
|
||||
});
|
||||
|
||||
consumer.on('resume', (originator) =>
|
||||
|
|
@ -1959,7 +1967,7 @@ export default class RoomClient
|
|||
'consumer "resume" event [id:%s, originator:%s, consumer:%o]',
|
||||
consumer.id, originator, consumer);
|
||||
|
||||
this._dispatch(stateActions.setConsumerResumed(consumer.id, originator));
|
||||
store.dispatch(stateActions.setConsumerResumed(consumer.id, originator));
|
||||
});
|
||||
|
||||
consumer.on('effectiveprofilechange', (profile) =>
|
||||
|
|
@ -1968,7 +1976,7 @@ export default class RoomClient
|
|||
'consumer "effectiveprofilechange" event [id:%s, consumer:%o, profile:%s]',
|
||||
consumer.id, consumer, profile);
|
||||
|
||||
this._dispatch(stateActions.setConsumerEffectiveProfile(consumer.id, profile));
|
||||
store.dispatch(stateActions.setConsumerEffectiveProfile(consumer.id, profile));
|
||||
});
|
||||
|
||||
// Receive the consumer (if we can).
|
||||
|
|
@ -1985,7 +1993,7 @@ export default class RoomClient
|
|||
consumer.receive(this._recvTransport)
|
||||
.then((track) =>
|
||||
{
|
||||
this._dispatch(stateActions.setConsumerTrack(consumer.id, track));
|
||||
store.dispatch(stateActions.setConsumerTrack(consumer.id, track));
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
|
||||
const RoomContext = React.createContext();
|
||||
|
||||
export default RoomContext;
|
||||
|
||||
export function withRoomContext(Component)
|
||||
{
|
||||
return (props) => ( // eslint-disable-line react/display-name
|
||||
<RoomContext.Consumer>
|
||||
{(roomClient) => <Component {...props} roomClient={roomClient} />}
|
||||
</RoomContext.Consumer>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,17 +1,28 @@
|
|||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import * as stateActions from '../../redux/stateActions';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import MessageList from './MessageList';
|
||||
|
||||
class Chat extends Component
|
||||
{
|
||||
createNewMessage(text, sender, name, picture)
|
||||
{
|
||||
return {
|
||||
type : 'message',
|
||||
text,
|
||||
time : Date.now(),
|
||||
name,
|
||||
sender,
|
||||
picture
|
||||
};
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
senderPlaceHolder,
|
||||
onSendMessage,
|
||||
disabledInput,
|
||||
autofocus,
|
||||
displayName,
|
||||
|
|
@ -23,7 +34,19 @@ class Chat extends Component
|
|||
<MessageList />
|
||||
<form
|
||||
data-component='Sender'
|
||||
onSubmit={(e) => { onSendMessage(e, displayName, picture); }}
|
||||
onSubmit={(e) =>
|
||||
{
|
||||
e.preventDefault();
|
||||
const userInput = e.target.message.value;
|
||||
|
||||
if (userInput)
|
||||
{
|
||||
const message = this.createNewMessage(userInput, 'response', displayName, picture);
|
||||
|
||||
roomClient.sendChatMessage(message);
|
||||
}
|
||||
e.target.message.value = '';
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type='text'
|
||||
|
|
@ -47,8 +70,8 @@ class Chat extends Component
|
|||
|
||||
Chat.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
senderPlaceHolder : PropTypes.string,
|
||||
onSendMessage : PropTypes.func,
|
||||
disabledInput : PropTypes.bool,
|
||||
autofocus : PropTypes.bool,
|
||||
displayName : PropTypes.string,
|
||||
|
|
@ -71,27 +94,8 @@ const mapStateToProps = (state) =>
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onSendMessage : (event, displayName, picture) =>
|
||||
{
|
||||
event.preventDefault();
|
||||
const userInput = event.target.message.value;
|
||||
|
||||
if (userInput)
|
||||
{
|
||||
dispatch(stateActions.addUserMessage(userInput));
|
||||
dispatch(requestActions.sendChatMessage(userInput, displayName, picture));
|
||||
}
|
||||
event.target.message.value = '';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const ChatContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Chat);
|
||||
const ChatContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Chat));
|
||||
|
||||
export default ChatContainer;
|
||||
|
|
|
|||
|
|
@ -30,41 +30,47 @@ class MessageList extends Component
|
|||
|
||||
return (
|
||||
<div data-component='MessageList' id='messages'>
|
||||
{ chatmessages.length > 0 ?
|
||||
chatmessages.map((message, i) =>
|
||||
{
|
||||
const messageTime = new Date(message.time);
|
||||
<Choose>
|
||||
<When condition={chatmessages.length > 0}>
|
||||
{
|
||||
chatmessages.map((message, i) =>
|
||||
{
|
||||
const messageTime = new Date(message.time);
|
||||
|
||||
const picture = (message.sender === 'response' ?
|
||||
message.picture : this.props.myPicture) || 'resources/images/avatar-empty.jpeg';
|
||||
const picture = (message.sender === 'response' ?
|
||||
message.picture : this.props.myPicture) || 'resources/images/avatar-empty.jpeg';
|
||||
|
||||
return (
|
||||
<div className='message' key={i}>
|
||||
<div className={message.sender}>
|
||||
<img className='message-avatar' src={picture} />
|
||||
return (
|
||||
<div className='message' key={i}>
|
||||
<div className={message.sender}>
|
||||
<img className='message-avatar' src={picture} />
|
||||
|
||||
<div className='message-content'>
|
||||
<div
|
||||
className='message-text'
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html : marked.parse(
|
||||
message.text,
|
||||
{ sanitize: true, renderer: linkRenderer }
|
||||
) }}
|
||||
/>
|
||||
<div className='message-content'>
|
||||
<div
|
||||
className='message-text'
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html : marked.parse(
|
||||
message.text,
|
||||
{ sanitize: true, renderer: linkRenderer }
|
||||
) }}
|
||||
/>
|
||||
|
||||
<span className='message-time'>
|
||||
{message.name} - {this.getTimeString(messageTime)}
|
||||
</span>
|
||||
<span className='message-time'>
|
||||
{message.name} - {this.getTimeString(messageTime)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
:<div className='empty'>
|
||||
<p>No one has said anything yet...</p>
|
||||
</div>
|
||||
}
|
||||
);
|
||||
})
|
||||
}
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div className='empty'>
|
||||
<p>No one has said anything yet...</p>
|
||||
</div>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,29 +110,34 @@ class FileEntry extends Component
|
|||
<img className='file-avatar' src={this.props.data.picture || DEFAULT_PICTURE} />
|
||||
|
||||
<div className='file-content'>
|
||||
{this.props.data.me ? (
|
||||
<p>You shared a file.</p>
|
||||
) : (
|
||||
<p>{this.props.data.name} shared a file.</p>
|
||||
)}
|
||||
<Choose>
|
||||
<When condition={this.props.data.me}>
|
||||
<p>You shared a file.</p>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<p>{this.props.data.name} shared a file.</p>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
{!this.state.active && !this.state.files && (
|
||||
<If condition={!this.state.active && !this.state.files}>
|
||||
<div className='file-info'>
|
||||
{WebTorrent.WEBRTC_SUPPORT ? (
|
||||
<span className='button' onClick={this.handleDownload}>
|
||||
<img src='resources/images/download-icon.svg' />
|
||||
</span>
|
||||
) : (
|
||||
<p>
|
||||
Your browser does not support downloading files using WebTorrent.
|
||||
</p>
|
||||
)}
|
||||
|
||||
<Choose>
|
||||
<When condition={WebTorrent.WEBRTC_SUPPORT}>
|
||||
<span className='button' onClick={this.handleDownload}>
|
||||
<img src='resources/images/download-icon.svg' />
|
||||
</span>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<p>
|
||||
Your browser does not support downloading files using WebTorrent.
|
||||
</p>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
<p>{magnet.decode(this.props.data.file.magnet).dn}</p>
|
||||
</div>
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.active && this.state.numPeers === 0 && (
|
||||
<If condition={this.state.active && this.state.numPeers === 0}>
|
||||
<Fragment>
|
||||
<p>
|
||||
Locating peers
|
||||
|
|
@ -145,13 +150,13 @@ class FileEntry extends Component
|
|||
</p>
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.active && this.state.numPeers > 0 && (
|
||||
<If condition={this.state.active && this.state.numPeers > 0}>
|
||||
<progress value={this.state.progress} />
|
||||
)}
|
||||
</If>
|
||||
|
||||
{this.state.files && (
|
||||
<If condition={this.state.files}>
|
||||
<Fragment>
|
||||
<p>Torrent finished downloading.</p>
|
||||
|
||||
|
|
@ -165,7 +170,7 @@ class FileEntry extends Component
|
|||
</div>
|
||||
))}
|
||||
</Fragment>
|
||||
)}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,17 +17,23 @@ class SharedFilesList extends Component
|
|||
|
||||
return (
|
||||
<div className='shared-files'>
|
||||
{ sharing.length > 0 ?
|
||||
sharing.map((entry, i) => (
|
||||
<FileEntry
|
||||
data={entry}
|
||||
key={i}
|
||||
/>
|
||||
))
|
||||
:<div className='empty'>
|
||||
<p>No one has shared files yet...</p>
|
||||
</div>
|
||||
}
|
||||
<Choose>
|
||||
<When condition={sharing.length > 0}>
|
||||
{
|
||||
sharing.map((entry, i) => (
|
||||
<FileEntry
|
||||
data={entry}
|
||||
key={i}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div className='empty'>
|
||||
<p>No one has shared files yet...</p>
|
||||
</div>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import ResizeObserver from 'resize-observer-polyfill';
|
|||
import { connect } from 'react-redux';
|
||||
import debounce from 'lodash/debounce';
|
||||
import classnames from 'classnames';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import Peer from './Peer';
|
||||
import HiddenPeers from './HiddenPeers';
|
||||
|
||||
|
|
@ -114,14 +114,20 @@ class Filmstrip extends Component
|
|||
|
||||
render()
|
||||
{
|
||||
const { peers, advancedMode, spotlights, spotlightsLength } = this.props;
|
||||
const {
|
||||
roomClient,
|
||||
peers,
|
||||
advancedMode,
|
||||
spotlights,
|
||||
spotlightsLength
|
||||
} = this.props;
|
||||
|
||||
const activePeerName = this.getActivePeerName();
|
||||
|
||||
return (
|
||||
<div data-component='Filmstrip'>
|
||||
<div className='active-peer-container' ref={this.activePeerContainer}>
|
||||
{peers[activePeerName] && (
|
||||
<If condition={peers[activePeerName]}>
|
||||
<div
|
||||
className='active-peer'
|
||||
style={{
|
||||
|
|
@ -134,7 +140,7 @@ class Filmstrip extends Component
|
|||
name={activePeerName}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</If>
|
||||
</div>
|
||||
|
||||
<div className='filmstrip'>
|
||||
|
|
@ -142,35 +148,37 @@ class Filmstrip extends Component
|
|||
{
|
||||
Object.keys(peers).map((peerName) =>
|
||||
{
|
||||
return (
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peerName)?
|
||||
<div
|
||||
key={peerName}
|
||||
onClick={() => this.props.setSelectedPeer(peerName)}
|
||||
className={classnames('film', {
|
||||
selected : this.props.selectedPeerName === peerName,
|
||||
active : this.state.lastSpeaker === peerName
|
||||
})}
|
||||
>
|
||||
<div className='film-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peerName}
|
||||
/>
|
||||
</div>
|
||||
<If
|
||||
condition={
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peerName)
|
||||
}
|
||||
>
|
||||
<div
|
||||
key={peerName}
|
||||
onClick={() => roomClient.setSelectedPeer(peerName)}
|
||||
className={classnames('film', {
|
||||
selected : this.props.selectedPeerName === peerName,
|
||||
active : this.state.lastSpeaker === peerName
|
||||
})}
|
||||
>
|
||||
<div className='film-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peerName}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
);
|
||||
</div>
|
||||
</If>;
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className='hidden-peer-container'>
|
||||
{ (spotlightsLength<Object.keys(peers).length)?
|
||||
<If condition={(spotlightsLength<Object.keys(peers).length)}>
|
||||
<HiddenPeers
|
||||
hiddenPeersCount={Object.keys(peers).length-spotlightsLength}
|
||||
/>:null
|
||||
}
|
||||
/>
|
||||
</If>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -179,13 +187,13 @@ class Filmstrip extends Component
|
|||
}
|
||||
|
||||
Filmstrip.propTypes = {
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
activeSpeakerName : PropTypes.string,
|
||||
advancedMode : PropTypes.bool,
|
||||
peers : PropTypes.object.isRequired,
|
||||
consumers : PropTypes.object.isRequired,
|
||||
myName : PropTypes.string.isRequired,
|
||||
selectedPeerName : PropTypes.string,
|
||||
setSelectedPeer : PropTypes.func.isRequired,
|
||||
spotlightsLength : PropTypes.number,
|
||||
spotlights : PropTypes.array.isRequired
|
||||
};
|
||||
|
|
@ -205,11 +213,7 @@ const mapStateToProps = (state) =>
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setSelectedPeer : requestActions.setSelectedPeer
|
||||
};
|
||||
|
||||
export default connect(
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Filmstrip);
|
||||
undefined
|
||||
)(Filmstrip));
|
||||
|
|
|
|||
|
|
@ -31,12 +31,11 @@ const FullScreenView = (props) =>
|
|||
|
||||
return (
|
||||
<div data-component='FullScreenView'>
|
||||
{consumerVisible && !consumer.supported ?
|
||||
<If condition={consumerVisible && !consumer.supported}>
|
||||
<div className='incompatible-video'>
|
||||
<p>incompatible video</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className='controls'>
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -35,12 +35,11 @@ export default class FullView extends React.Component
|
|||
muted={Boolean(true)}
|
||||
/>
|
||||
|
||||
{videoProfile === 'none' ?
|
||||
<If condition={videoProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
|
|||
import classnames from 'classnames';
|
||||
import { getDeviceInfo } from 'mediasoup-client';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import PeerView from './PeerView';
|
||||
import ScreenView from './ScreenView';
|
||||
|
||||
|
|
@ -46,17 +46,13 @@ class Me extends React.Component
|
|||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
connected,
|
||||
me,
|
||||
advancedMode,
|
||||
micProducer,
|
||||
webcamProducer,
|
||||
screenProducer,
|
||||
onChangeDisplayName,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
onEnableWebcam,
|
||||
onDisableWebcam
|
||||
screenProducer
|
||||
} = this.props;
|
||||
|
||||
let micState;
|
||||
|
|
@ -107,7 +103,7 @@ class Me extends React.Component
|
|||
onMouseOut={this.handleMouseOut}
|
||||
>
|
||||
<div className={classnames('view-container', 'webcam')}>
|
||||
{connected ?
|
||||
<If condition={connected}>
|
||||
<div className={classnames('controls', 'visible')}>
|
||||
<div
|
||||
data-tip='keyboard shortcut: ‘m‘'
|
||||
|
|
@ -120,7 +116,9 @@ class Me extends React.Component
|
|||
})}
|
||||
onClick={() =>
|
||||
{
|
||||
micState === 'on' ? onMuteMic() : onUnmuteMic();
|
||||
micState === 'on' ?
|
||||
roomClient.muteMic() :
|
||||
roomClient.unmuteMic();
|
||||
}}
|
||||
/>
|
||||
<ReactTooltip
|
||||
|
|
@ -134,12 +132,13 @@ class Me extends React.Component
|
|||
})}
|
||||
onClick={() =>
|
||||
{
|
||||
webcamState === 'on' ? onDisableWebcam() : onEnableWebcam();
|
||||
webcamState === 'on' ?
|
||||
roomClient.disableWebcam() :
|
||||
roomClient.enableWebcam();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<PeerView
|
||||
isMe
|
||||
|
|
@ -151,11 +150,14 @@ class Me extends React.Component
|
|||
videoVisible={videoVisible}
|
||||
audioCodec={micProducer ? micProducer.codec : null}
|
||||
videoCodec={webcamProducer ? webcamProducer.codec : null}
|
||||
onChangeDisplayName={(displayName) => onChangeDisplayName(displayName)}
|
||||
onChangeDisplayName={(displayName) =>
|
||||
{
|
||||
roomClient.changeDisplayName(displayName);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{screenProducer ?
|
||||
<If condition={screenProducer}>
|
||||
<div className={classnames('view-container', 'screen')}>
|
||||
<ScreenView
|
||||
isMe
|
||||
|
|
@ -165,8 +167,7 @@ class Me extends React.Component
|
|||
screenCodec={screenProducer ? screenProducer.codec : null}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -204,17 +205,13 @@ class Me extends React.Component
|
|||
|
||||
Me.propTypes =
|
||||
{
|
||||
connected : PropTypes.bool.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
micProducer : appPropTypes.Producer,
|
||||
webcamProducer : appPropTypes.Producer,
|
||||
screenProducer : appPropTypes.Producer,
|
||||
onChangeDisplayName : PropTypes.func.isRequired,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
onEnableWebcam : PropTypes.func.isRequired,
|
||||
onDisableWebcam : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
connected : PropTypes.bool.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
micProducer : appPropTypes.Producer,
|
||||
webcamProducer : appPropTypes.Producer,
|
||||
screenProducer : appPropTypes.Producer
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
|
|
@ -236,23 +233,8 @@ const mapStateToProps = (state) =>
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onChangeDisplayName : (displayName) =>
|
||||
{
|
||||
dispatch(requestActions.changeDisplayName(displayName));
|
||||
},
|
||||
onMuteMic : () => dispatch(requestActions.muteMic()),
|
||||
onUnmuteMic : () => dispatch(requestActions.unmuteMic()),
|
||||
onEnableWebcam : () => dispatch(requestActions.enableWebcam()),
|
||||
onDisableWebcam : () => dispatch(requestActions.disableWebcam())
|
||||
};
|
||||
};
|
||||
|
||||
const MeContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Me);
|
||||
const MeContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Me));
|
||||
|
||||
export default MeContainer;
|
||||
|
|
|
|||
|
|
@ -3,18 +3,15 @@ import { connect } from 'react-redux';
|
|||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
|
||||
const ListPeer = (props) =>
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
peer,
|
||||
micConsumer,
|
||||
screenConsumer,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
onDisableScreen,
|
||||
onEnableScreen
|
||||
screenConsumer
|
||||
} = props;
|
||||
|
||||
const micEnabled = (
|
||||
|
|
@ -39,7 +36,7 @@ const ListPeer = (props) =>
|
|||
{peer.displayName}
|
||||
</div>
|
||||
<div className='indicators'>
|
||||
{peer.raiseHandState ?
|
||||
<If condition={peer.raiseHandState}>
|
||||
<div className={
|
||||
classnames(
|
||||
'icon', 'raise-hand', {
|
||||
|
|
@ -49,14 +46,13 @@ const ListPeer = (props) =>
|
|||
)
|
||||
}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
<div className='volume-container'>
|
||||
<div className={classnames('bar', `level${micEnabled && micConsumer ? micConsumer.volume:0}`)} />
|
||||
</div>
|
||||
<div className='controls'>
|
||||
{ screenConsumer ?
|
||||
<If condition={screenConsumer}>
|
||||
<div
|
||||
className={classnames('button', 'screen', {
|
||||
on : screenVisible,
|
||||
|
|
@ -67,11 +63,11 @@ const ListPeer = (props) =>
|
|||
{
|
||||
e.stopPropagation();
|
||||
screenVisible ?
|
||||
onDisableScreen(peer.name) : onEnableScreen(peer.name);
|
||||
roomClient.pausePeerScreen(peer.name) :
|
||||
roomClient.resumePeerScreen(peer.name);
|
||||
}}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
<div
|
||||
className={classnames('button', 'mic', {
|
||||
on : micEnabled,
|
||||
|
|
@ -81,7 +77,9 @@ const ListPeer = (props) =>
|
|||
onClick={(e) =>
|
||||
{
|
||||
e.stopPropagation();
|
||||
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
|
||||
micEnabled ?
|
||||
roomClient.mutePeerAudio(peer.name) :
|
||||
roomClient.unmutePeerAudio(peer.name);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -91,17 +89,12 @@ const ListPeer = (props) =>
|
|||
|
||||
ListPeer.propTypes =
|
||||
{
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
onEnableWebcam : PropTypes.func.isRequired,
|
||||
onDisableWebcam : PropTypes.func.isRequired,
|
||||
onEnableScreen : PropTypes.func.isRequired,
|
||||
onDisableScreen : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, { name }) =>
|
||||
|
|
@ -124,40 +117,8 @@ const mapStateToProps = (state, { name }) =>
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onMuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.mutePeerAudio(peerName));
|
||||
},
|
||||
onUnmuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.unmutePeerAudio(peerName));
|
||||
},
|
||||
onEnableWebcam : (peerName) =>
|
||||
{
|
||||
|
||||
dispatch(requestActions.resumePeerVideo(peerName));
|
||||
},
|
||||
onDisableWebcam : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.pausePeerVideo(peerName));
|
||||
},
|
||||
onEnableScreen : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.resumePeerScreen(peerName));
|
||||
},
|
||||
onDisableScreen : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.pausePeerScreen(peerName));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const ListPeerContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ListPeer);
|
||||
const ListPeerContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(ListPeer));
|
||||
|
||||
export default ListPeerContainer;
|
||||
|
|
|
|||
|
|
@ -2,16 +2,16 @@ import React from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
import * as appPropTypes from '../appPropTypes';
|
||||
import * as requestActions from '../../redux/requestActions';
|
||||
import { withRoomContext } from '../../RoomContext';
|
||||
import PropTypes from 'prop-types';
|
||||
import ListPeer from './ListPeer';
|
||||
import ListMe from './ListMe';
|
||||
|
||||
const ParticipantList =
|
||||
({
|
||||
roomClient,
|
||||
advancedMode,
|
||||
peers,
|
||||
setSelectedPeer,
|
||||
selectedPeerName,
|
||||
spotlights
|
||||
}) => (
|
||||
|
|
@ -33,7 +33,7 @@ const ParticipantList =
|
|||
className={classNames('list-item', {
|
||||
selected : peer.name === selectedPeerName
|
||||
})}
|
||||
onClick={() => setSelectedPeer(peer.name)}
|
||||
onClick={() => roomClient.setSelectedPeer(peer.name)}
|
||||
>
|
||||
<ListPeer name={peer.name} advancedMode={advancedMode} />
|
||||
</li>
|
||||
|
|
@ -52,7 +52,7 @@ const ParticipantList =
|
|||
className={classNames('list-item', {
|
||||
selected : peer.name === selectedPeerName
|
||||
})}
|
||||
onClick={() => setSelectedPeer(peer.name)}
|
||||
onClick={() => roomClient.setSelectedPeer(peer.name)}
|
||||
>
|
||||
<ListPeer name={peer.name} advancedMode={advancedMode} />
|
||||
</li>
|
||||
|
|
@ -64,9 +64,9 @@ const ParticipantList =
|
|||
|
||||
ParticipantList.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peers : PropTypes.arrayOf(appPropTypes.Peer).isRequired,
|
||||
setSelectedPeer : PropTypes.func.isRequired,
|
||||
selectedPeerName : PropTypes.string,
|
||||
spotlights : PropTypes.array.isRequired
|
||||
};
|
||||
|
|
@ -82,13 +82,8 @@ const mapStateToProps = (state) =>
|
|||
};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setSelectedPeer : requestActions.setSelectedPeer
|
||||
};
|
||||
|
||||
const ParticipantListContainer = connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(ParticipantList);
|
||||
const ParticipantListContainer = withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(ParticipantList));
|
||||
|
||||
export default ParticipantListContainer;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { connect } from 'react-redux';
|
|||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import * as stateActions from '../redux/stateActions';
|
||||
import PeerView from './PeerView';
|
||||
import ScreenView from './ScreenView';
|
||||
|
|
@ -31,13 +31,12 @@ class Peer extends Component
|
|||
render()
|
||||
{
|
||||
const {
|
||||
roomClient,
|
||||
advancedMode,
|
||||
peer,
|
||||
micConsumer,
|
||||
webcamConsumer,
|
||||
screenConsumer,
|
||||
onMuteMic,
|
||||
onUnmuteMic,
|
||||
toggleConsumerFullscreen,
|
||||
toggleConsumerWindow,
|
||||
style,
|
||||
|
|
@ -81,23 +80,21 @@ class Peer extends Component
|
|||
onMouseOver={this.handleMouseOver}
|
||||
onMouseOut={this.handleMouseOut}
|
||||
>
|
||||
{videoVisible && !webcamConsumer.supported ?
|
||||
<If condition={videoVisible && !webcamConsumer.supported}>
|
||||
<div className='incompatible-video'>
|
||||
<p>incompatible video</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{!videoVisible ?
|
||||
<If condition={!videoVisible}>
|
||||
<div className='paused-video'>
|
||||
<p>this video is paused</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className={classnames('view-container', 'webcam')} style={style}>
|
||||
<div className='indicators'>
|
||||
{peer.raiseHandState ?
|
||||
<If condition={peer.raiseHandState}>
|
||||
<div className={
|
||||
classnames(
|
||||
'icon', 'raise-hand', {
|
||||
|
|
@ -107,8 +104,7 @@ class Peer extends Component
|
|||
)
|
||||
}
|
||||
/>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
<div
|
||||
className={classnames('controls', {
|
||||
|
|
@ -124,7 +120,9 @@ class Peer extends Component
|
|||
onClick={(e) =>
|
||||
{
|
||||
e.stopPropagation();
|
||||
micEnabled ? onMuteMic(peer.name) : onUnmuteMic(peer.name);
|
||||
micEnabled ?
|
||||
roomClient.mutePeerAudio(peer.name) :
|
||||
roomClient.unmutePeerAudio(peer.name);
|
||||
}}
|
||||
/>
|
||||
|
||||
|
|
@ -162,7 +160,7 @@ class Peer extends Component
|
|||
/>
|
||||
</div>
|
||||
|
||||
{screenConsumer ?
|
||||
<If condition={screenConsumer}>
|
||||
<div className={classnames('view-container', 'screen')} style={style}>
|
||||
<div
|
||||
className={classnames('controls', {
|
||||
|
|
@ -195,8 +193,7 @@ class Peer extends Component
|
|||
screenCodec={screenConsumer ? screenConsumer.codec : null}
|
||||
/>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -204,14 +201,13 @@ class Peer extends Component
|
|||
|
||||
Peer.propTypes =
|
||||
{
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
advancedMode : PropTypes.bool,
|
||||
peer : appPropTypes.Peer.isRequired,
|
||||
micConsumer : appPropTypes.Consumer,
|
||||
webcamConsumer : appPropTypes.Consumer,
|
||||
screenConsumer : appPropTypes.Consumer,
|
||||
windowConsumer : PropTypes.number,
|
||||
onMuteMic : PropTypes.func.isRequired,
|
||||
onUnmuteMic : PropTypes.func.isRequired,
|
||||
streamDimensions : PropTypes.object,
|
||||
style : PropTypes.object,
|
||||
toggleConsumerFullscreen : PropTypes.func.isRequired,
|
||||
|
|
@ -242,14 +238,6 @@ const mapStateToProps = (state, { name }) =>
|
|||
const mapDispatchToProps = (dispatch) =>
|
||||
{
|
||||
return {
|
||||
onMuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.mutePeerAudio(peerName));
|
||||
},
|
||||
onUnmuteMic : (peerName) =>
|
||||
{
|
||||
dispatch(requestActions.unmutePeerAudio(peerName));
|
||||
},
|
||||
toggleConsumerFullscreen : (consumer) =>
|
||||
{
|
||||
if (consumer)
|
||||
|
|
@ -263,9 +251,9 @@ const mapDispatchToProps = (dispatch) =>
|
|||
};
|
||||
};
|
||||
|
||||
const PeerContainer = connect(
|
||||
const PeerContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Peer);
|
||||
)(Peer));
|
||||
|
||||
export default PeerContainer;
|
||||
|
|
|
|||
|
|
@ -52,51 +52,50 @@ export default class PeerView extends React.Component
|
|||
return (
|
||||
<div data-component='PeerView'>
|
||||
<div className='info'>
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className={classnames('media', { 'is-me': isMe })}>
|
||||
<div className='box'>
|
||||
{audioCodec ?
|
||||
<If condition={audioCodec}>
|
||||
<p className='codec'>{audioCodec}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{videoCodec ?
|
||||
<If condition={videoCodec}>
|
||||
<p className='codec'>{videoCodec} {videoProfile}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{(videoVisible && videoWidth !== null) ?
|
||||
<If condition={(videoVisible && videoWidth !== null)}>
|
||||
<p className='resolution'>{videoWidth}x{videoHeight}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div className={classnames('peer', { 'is-me': isMe })}>
|
||||
{isMe ?
|
||||
<EditableInput
|
||||
value={peer.displayName}
|
||||
propName='displayName'
|
||||
className='display-name editable'
|
||||
classLoading='loading'
|
||||
classInvalid='invalid'
|
||||
shouldBlockWhileLoading
|
||||
editProps={{
|
||||
maxLength : 20,
|
||||
autoCorrect : false,
|
||||
spellCheck : false
|
||||
}}
|
||||
onChange={({ displayName }) => onChangeDisplayName(displayName)}
|
||||
/>
|
||||
:
|
||||
<span className='display-name'>
|
||||
{peer.displayName}
|
||||
</span>
|
||||
}
|
||||
<Choose>
|
||||
<When condition={isMe}>
|
||||
<EditableInput
|
||||
value={peer.displayName}
|
||||
propName='displayName'
|
||||
className='display-name editable'
|
||||
classLoading='loading'
|
||||
classInvalid='invalid'
|
||||
shouldBlockWhileLoading
|
||||
editProps={{
|
||||
maxLength : 20,
|
||||
autoCorrect : false,
|
||||
spellCheck : false
|
||||
}}
|
||||
onChange={({ displayName }) => onChangeDisplayName(displayName)}
|
||||
/>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<span className='display-name'>
|
||||
{peer.displayName}
|
||||
</span>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className='row'>
|
||||
<span
|
||||
className={classnames('device-icon', peer.device.flag)}
|
||||
|
|
@ -105,8 +104,7 @@ export default class PeerView extends React.Component
|
|||
{peer.device.name} {Math.floor(peer.device.version) || null}
|
||||
</span>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -125,12 +123,11 @@ export default class PeerView extends React.Component
|
|||
<div className={classnames('bar', `level${volume}`)} />
|
||||
</div>
|
||||
|
||||
{videoProfile === 'none' ?
|
||||
<If condition={videoProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,35 +108,36 @@ class Peers extends React.Component
|
|||
{
|
||||
peers.map((peer) =>
|
||||
{
|
||||
return (
|
||||
(spotlights.find(function(spotlightsElement)
|
||||
{ return spotlightsElement == peer.name; }))?
|
||||
<Appear key={peer.name} duration={1000}>
|
||||
<div
|
||||
className={classnames('peer-container', {
|
||||
'selected' : this.props.selectedPeerName === peer.name,
|
||||
'active-speaker' : peer.name === activeSpeakerName
|
||||
})}
|
||||
>
|
||||
<div className='peer-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peer.name}
|
||||
style={style}
|
||||
/>
|
||||
</div>
|
||||
<If
|
||||
condition={
|
||||
spotlights.find((spotlightsElement) => spotlightsElement === peer.name)
|
||||
}
|
||||
>
|
||||
<Appear key={peer.name} duration={1000}>
|
||||
<div
|
||||
className={classnames('peer-container', {
|
||||
'selected' : this.props.selectedPeerName === peer.name,
|
||||
'active-speaker' : peer.name === activeSpeakerName
|
||||
})}
|
||||
>
|
||||
<div className='peer-content'>
|
||||
<Peer
|
||||
advancedMode={advancedMode}
|
||||
name={peer.name}
|
||||
style={style}
|
||||
/>
|
||||
</div>
|
||||
</Appear>
|
||||
:null
|
||||
);
|
||||
</div>
|
||||
</Appear>
|
||||
</If>;
|
||||
})
|
||||
}
|
||||
<div className='hidden-peer-container'>
|
||||
{ (spotlightsLength<peers.length)?
|
||||
<If condition={spotlightsLength < peers.length}>
|
||||
<HiddenPeers
|
||||
hiddenPeersCount={peers.length-spotlightsLength}
|
||||
/>:null
|
||||
}
|
||||
/>
|
||||
</If>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import Me from './Me';
|
|||
import Peers from './Peers';
|
||||
import AudioPeers from './PeerAudio/AudioPeers';
|
||||
import Notifications from './Notifications';
|
||||
// import ToolAreaButton from './ToolArea/ToolAreaButton';
|
||||
import ToolArea from './ToolArea/ToolArea';
|
||||
import FullScreenView from './FullScreenView';
|
||||
import VideoWindow from './VideoWindow/VideoWindow';
|
||||
|
|
@ -97,13 +96,12 @@ class Room extends React.Component
|
|||
|
||||
<Notifications />
|
||||
|
||||
{room.advancedMode ?
|
||||
<If condition={room.advancedMode}>
|
||||
<div className='state' data-tip='Server status'>
|
||||
<div className={classnames('icon', room.state)} />
|
||||
<p className={classnames('text', room.state)}>{room.state}</p>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
<div
|
||||
className={classnames('room-link-wrapper room-controls', {
|
||||
|
|
|
|||
|
|
@ -41,25 +41,21 @@ export default class ScreenView extends React.Component
|
|||
return (
|
||||
<div data-component='ScreenView'>
|
||||
<div className='info'>
|
||||
{advancedMode ?
|
||||
<If condition={advancedMode}>
|
||||
<div className={classnames('media', { 'is-me': isMe })}>
|
||||
{screenVisible ?
|
||||
<If condition={screenVisible}>
|
||||
<div className='box'>
|
||||
{screenCodec ?
|
||||
<If condition={screenCodec}>
|
||||
<p className='codec'>{screenCodec} {screenProfile}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
|
||||
{(screenVisible && screenWidth !== null) ?
|
||||
<If condition={(screenVisible && screenWidth !== null)}>
|
||||
<p className='resolution'>{screenWidth}x{screenHeight}</p>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
|
||||
<video
|
||||
|
|
@ -73,12 +69,11 @@ export default class ScreenView extends React.Component
|
|||
muted={Boolean(true)}
|
||||
/>
|
||||
|
||||
{screenProfile === 'none' ?
|
||||
<If condition={screenProfile === 'none'}>
|
||||
<div className='spinner-container'>
|
||||
<Spinner />
|
||||
</div>
|
||||
:null
|
||||
}
|
||||
</If>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import * as stateActions from '../redux/stateActions';
|
||||
import PropTypes from 'prop-types';
|
||||
import Dropdown from 'react-dropdown';
|
||||
|
|
@ -18,8 +18,11 @@ const modes = [ {
|
|||
const findOption = (options, value) => options.find((option) => option.value === value);
|
||||
|
||||
const Settings = ({
|
||||
room, me, onToggleAdvancedMode, handleChangeWebcam,
|
||||
handleChangeAudioDevice, handleChangeMode
|
||||
roomClient,
|
||||
room,
|
||||
me,
|
||||
onToggleAdvancedMode,
|
||||
handleChangeMode
|
||||
}) =>
|
||||
{
|
||||
let webcams;
|
||||
|
|
@ -48,7 +51,7 @@ const Settings = ({
|
|||
<Dropdown
|
||||
options={webcams}
|
||||
value={findOption(webcams, me.selectedWebcam)}
|
||||
onChange={(webcam) => handleChangeWebcam(webcam.value)}
|
||||
onChange={(webcam) => roomClient.changeWebcam(webcam.value)}
|
||||
placeholder={'Select camera'}
|
||||
/>
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ const Settings = ({
|
|||
disabled={!me.canChangeAudioDevice}
|
||||
options={audioDevices}
|
||||
value={findOption(audioDevices, me.selectedAudioDevice)}
|
||||
onChange={(device) => handleChangeAudioDevice(device.value)}
|
||||
onChange={(device) => roomClient.changeAudioDevice(device.value)}
|
||||
placeholder={audioDevicesText}
|
||||
/>
|
||||
<ReactTooltip
|
||||
|
|
@ -94,12 +97,11 @@ const Settings = ({
|
|||
|
||||
Settings.propTypes =
|
||||
{
|
||||
me : appPropTypes.Me.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
handleChangeWebcam : PropTypes.func.isRequired,
|
||||
handleChangeAudioDevice : PropTypes.func.isRequired,
|
||||
onToggleAdvancedMode : PropTypes.func.isRequired,
|
||||
handleChangeMode : PropTypes.func.isRequired
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
room : appPropTypes.Room.isRequired,
|
||||
onToggleAdvancedMode : PropTypes.func.isRequired,
|
||||
handleChangeMode : PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) =>
|
||||
|
|
@ -111,15 +113,13 @@ const mapStateToProps = (state) =>
|
|||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
handleChangeWebcam : requestActions.changeWebcam,
|
||||
handleChangeAudioDevice : requestActions.changeAudioDevice,
|
||||
onToggleAdvancedMode : stateActions.toggleAdvancedMode,
|
||||
handleChangeMode : stateActions.setDisplayMode
|
||||
onToggleAdvancedMode : stateActions.toggleAdvancedMode,
|
||||
handleChangeMode : stateActions.setDisplayMode
|
||||
};
|
||||
|
||||
const SettingsContainer = connect(
|
||||
const SettingsContainer = withRoomContext(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Settings);
|
||||
)(Settings));
|
||||
|
||||
export default SettingsContainer;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||
import { connect } from 'react-redux';
|
||||
import classnames from 'classnames';
|
||||
import * as appPropTypes from './appPropTypes';
|
||||
import * as requestActions from '../redux/requestActions';
|
||||
import { withRoomContext } from '../RoomContext';
|
||||
import FullScreen from './FullScreen';
|
||||
|
||||
class Sidebar extends Component
|
||||
|
|
@ -56,8 +56,10 @@ class Sidebar extends Component
|
|||
render()
|
||||
{
|
||||
const {
|
||||
toolbarsVisible, me, screenProducer, onLogin, onShareScreen,
|
||||
onUnShareScreen, onNeedExtension, onLeaveMeeting, onLogout, onToggleHand
|
||||
roomClient,
|
||||
toolbarsVisible,
|
||||
me,
|
||||
screenProducer
|
||||
} = this.props;
|
||||
|
||||
let screenState;
|
||||
|
|
@ -91,7 +93,7 @@ class Sidebar extends Component
|
|||
})}
|
||||
data-component='Sidebar'
|
||||
>
|
||||
{this.fullscreen.fullscreenEnabled && (
|
||||
<If condition={this.fullscreen.fullscreenEnabled}>
|
||||
<div
|
||||
className={classnames('button', 'fullscreen', {
|
||||
on : this.state.fullscreen
|
||||
|
|
@ -101,7 +103,7 @@ class Sidebar extends Component
|
|||
data-place='right'
|
||||
data-type='dark'
|
||||
/>
|
||||
)}
|
||||
</If>
|
||||
|
||||
<div
|
||||
className={classnames('button', 'screen', screenState)}
|
||||
|
|
@ -114,17 +116,17 @@ class Sidebar extends Component
|
|||
{
|
||||
case 'on':
|
||||
{
|
||||
onUnShareScreen();
|
||||
roomClient.disableScreenSharing();
|
||||
break;
|
||||
}
|
||||
case 'off':
|
||||
{
|
||||
onShareScreen();
|
||||
roomClient.enableScreenSharing();
|
||||
break;
|
||||
}
|
||||
case 'need-extension':
|
||||
{
|
||||
onNeedExtension();
|
||||
roomClient.installExtension();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -135,25 +137,30 @@ class Sidebar extends Component
|
|||
}}
|
||||
/>
|
||||
|
||||
{me.loginEnabled && (me.loggedIn ? (
|
||||
<div
|
||||
className='button logout'
|
||||
data-tip='Logout'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={onLogout}
|
||||
>
|
||||
<img src={me.picture || 'resources/images/avatar-empty.jpeg'} />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className='button login off'
|
||||
data-tip='Login'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={onLogin}
|
||||
/>
|
||||
))}
|
||||
<If condition={me.loginEnabled}>
|
||||
<Choose>
|
||||
<When condition={me.loggedIn}>
|
||||
<div
|
||||
className='button logout'
|
||||
data-tip='Logout'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => roomClient.logout()}
|
||||
>
|
||||
<img src={me.picture || 'resources/images/avatar-empty.jpeg'} />
|
||||
</div>
|
||||
</When>
|
||||
<Otherwise>
|
||||
<div
|
||||
className='button login off'
|
||||
data-tip='Login'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => roomClient.login()}
|
||||
/>
|
||||
</Otherwise>
|
||||
</Choose>
|
||||
</If>
|
||||
<div
|
||||
className={classnames('button', 'raise-hand', {
|
||||
on : me.raiseHand,
|
||||
|
|
@ -162,7 +169,7 @@ class Sidebar extends Component
|
|||
data-tip='Raise hand'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => onToggleHand(!me.raiseHand)}
|
||||
onClick={() => roomClient.sendRaiseHandState(!me.raiseHand)}
|
||||
/>
|
||||
|
||||
<div
|
||||
|
|
@ -170,7 +177,7 @@ class Sidebar extends Component
|
|||
data-tip='Leave meeting'
|
||||
data-place='right'
|
||||
data-type='dark'
|
||||
onClick={() => onLeaveMeeting()}
|
||||
onClick={() => roomClient.close()}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -178,15 +185,9 @@ class Sidebar extends Component
|
|||
}
|
||||
|
||||
Sidebar.propTypes = {
|
||||
roomClient : PropTypes.any.isRequired,
|
||||
toolbarsVisible : PropTypes.bool.isRequired,
|
||||
me : appPropTypes.Me.isRequired,
|
||||
onShareScreen : PropTypes.func.isRequired,
|
||||
onUnShareScreen : PropTypes.func.isRequired,
|
||||
onNeedExtension : PropTypes.func.isRequired,
|
||||
onToggleHand : PropTypes.func.isRequired,
|
||||
onLeaveMeeting : PropTypes.func.isRequired,
|
||||
onLogin : PropTypes.func.isRequired,
|
||||
onLogout : PropTypes.func.isRequired,
|
||||
screenProducer : appPropTypes.Producer
|
||||
};
|
||||
|
||||
|
|
@ -198,17 +199,6 @@ const mapStateToProps = (state) =>
|
|||
me : state.me
|
||||
});
|
||||
|
||||
const mapDispatchToProps = {
|
||||
onLeaveMeeting : requestActions.leaveRoom,
|
||||
onShareScreen : requestActions.enableScreenSharing,
|
||||
onUnShareScreen : requestActions.disableScreenSharing,
|
||||
onNeedExtension : requestActions.installExtension,
|
||||
onToggleHand : requestActions.toggleHand,
|
||||
onLogin : requestActions.userLogin,
|
||||
onLogout : requestActions.userLogout
|
||||
};
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Sidebar);
|
||||
export default withRoomContext(connect(
|
||||
mapStateToProps
|
||||
)(Sidebar));
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ import { getDeviceInfo } from 'mediasoup-client';
|
|||
import randomString from 'random-string';
|
||||
import Logger from './Logger';
|
||||
import * as utils from './utils';
|
||||
import RoomClient from './RoomClient';
|
||||
import RoomContext from './RoomContext';
|
||||
import * as cookiesManager from './cookiesManager';
|
||||
import * as requestActions from './redux/requestActions';
|
||||
import * as stateActions from './redux/stateActions';
|
||||
import Room from './components/Room';
|
||||
import { loginEnabled } from '../config';
|
||||
|
|
@ -16,6 +17,10 @@ import { store } from './store';
|
|||
|
||||
const logger = new Logger();
|
||||
|
||||
let roomClient;
|
||||
|
||||
RoomClient.init({ store });
|
||||
|
||||
domready(() =>
|
||||
{
|
||||
logger.debug('DOM ready');
|
||||
|
|
@ -93,39 +98,38 @@ function run()
|
|||
device.version = undefined;
|
||||
}
|
||||
|
||||
// NOTE: I don't like this.
|
||||
store.dispatch(
|
||||
stateActions.setRoomUrl(roomUrl));
|
||||
|
||||
// NOTE: I don't like this.
|
||||
store.dispatch(
|
||||
stateActions.setMe({ peerName, displayName, displayNameSet, device, loginEnabled }));
|
||||
|
||||
// NOTE: I don't like this.
|
||||
store.dispatch(
|
||||
requestActions.joinRoom(
|
||||
{ roomId, peerName, displayName, device, useSimulcast, produce }));
|
||||
roomClient = new RoomClient(
|
||||
{ roomId, peerName, displayName, device, useSimulcast, produce });
|
||||
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<Room />
|
||||
<RoomContext.Provider value={roomClient}>
|
||||
<Room />
|
||||
</RoomContext.Provider>
|
||||
</Provider>,
|
||||
document.getElementById('multiparty-meeting')
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: Debugging stuff.
|
||||
global.CLIENT = roomClient;
|
||||
|
||||
setInterval(() =>
|
||||
{
|
||||
if (!global.CLIENT._room.peers[0])
|
||||
if (!roomClient._room.peers[0])
|
||||
{
|
||||
delete global.CONSUMER;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const peer = global.CLIENT._room.peers[0];
|
||||
const peer = roomClient._room.peers[0];
|
||||
|
||||
global.CONSUMER = peer.consumers[peer.consumers.length - 1];
|
||||
}, 2000);
|
||||
|
|
@ -134,20 +138,20 @@ global.sendSdp = function()
|
|||
{
|
||||
logger.debug('---------- SEND_TRANSPORT LOCAL SDP OFFER:');
|
||||
logger.debug(
|
||||
global.CLIENT._sendTransport._handler._pc.localDescription.sdp);
|
||||
roomClient._sendTransport._handler._pc.localDescription.sdp);
|
||||
|
||||
logger.debug('---------- SEND_TRANSPORT REMOTE SDP ANSWER:');
|
||||
logger.debug(
|
||||
global.CLIENT._sendTransport._handler._pc.remoteDescription.sdp);
|
||||
roomClient._sendTransport._handler._pc.remoteDescription.sdp);
|
||||
};
|
||||
|
||||
global.recvSdp = function()
|
||||
{
|
||||
logger.debug('---------- RECV_TRANSPORT REMOTE SDP OFFER:');
|
||||
logger.debug(
|
||||
global.CLIENT._recvTransport._handler._pc.remoteDescription.sdp);
|
||||
roomClient._recvTransport._handler._pc.remoteDescription.sdp);
|
||||
|
||||
logger.debug('---------- RECV_TRANSPORT LOCAL SDP ANSWER:');
|
||||
logger.debug(
|
||||
global.CLIENT._recvTransport._handler._pc.localDescription.sdp);
|
||||
roomClient._recvTransport._handler._pc.localDescription.sdp);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,233 +1,5 @@
|
|||
import randomString from 'random-string';
|
||||
import * as stateActions from './stateActions';
|
||||
import
|
||||
{
|
||||
createNewMessage
|
||||
} from './reducers/helper';
|
||||
|
||||
export const joinRoom = (
|
||||
{ roomId, peerName, displayName, device, useSimulcast, produce }) =>
|
||||
{
|
||||
return {
|
||||
type : 'JOIN_ROOM',
|
||||
payload : { roomId, peerName, displayName, device, useSimulcast, produce }
|
||||
};
|
||||
};
|
||||
|
||||
export const leaveRoom = () =>
|
||||
{
|
||||
return {
|
||||
type : 'LEAVE_ROOM'
|
||||
};
|
||||
};
|
||||
|
||||
export const changeDisplayName = (displayName) =>
|
||||
{
|
||||
return {
|
||||
type : 'CHANGE_DISPLAY_NAME',
|
||||
payload : { displayName }
|
||||
};
|
||||
};
|
||||
|
||||
export const muteMic = () =>
|
||||
{
|
||||
return {
|
||||
type : 'MUTE_MIC'
|
||||
};
|
||||
};
|
||||
|
||||
export const unmuteMic = () =>
|
||||
{
|
||||
return {
|
||||
type : 'UNMUTE_MIC'
|
||||
};
|
||||
};
|
||||
|
||||
export const enableWebcam = () =>
|
||||
{
|
||||
return {
|
||||
type : 'ENABLE_WEBCAM'
|
||||
};
|
||||
};
|
||||
|
||||
export const disableWebcam = () =>
|
||||
{
|
||||
return {
|
||||
type : 'DISABLE_WEBCAM'
|
||||
};
|
||||
};
|
||||
|
||||
export const changeWebcam = (deviceId) =>
|
||||
{
|
||||
return {
|
||||
type : 'CHANGE_WEBCAM',
|
||||
payload : { deviceId }
|
||||
};
|
||||
};
|
||||
|
||||
export const changeAudioDevice = (deviceId) =>
|
||||
{
|
||||
return {
|
||||
type : 'CHANGE_AUDIO_DEVICE',
|
||||
payload : { deviceId }
|
||||
};
|
||||
};
|
||||
|
||||
export const enableAudioOnly = () =>
|
||||
{
|
||||
return {
|
||||
type : 'ENABLE_AUDIO_ONLY'
|
||||
};
|
||||
};
|
||||
|
||||
export const disableAudioOnly = () =>
|
||||
{
|
||||
return {
|
||||
type : 'DISABLE_AUDIO_ONLY'
|
||||
};
|
||||
};
|
||||
|
||||
export const mutePeerAudio = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'MUTE_PEER_AUDIO',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const unmutePeerAudio = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'UNMUTE_PEER_AUDIO',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const pausePeerVideo = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'PAUSE_PEER_VIDEO',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const resumePeerVideo = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'RESUME_PEER_VIDEO',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const pausePeerScreen = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'PAUSE_PEER_SCREEN',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const resumePeerScreen = (peerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'RESUME_PEER_SCREEN',
|
||||
payload : { peerName }
|
||||
};
|
||||
};
|
||||
|
||||
export const userLogin = () =>
|
||||
{
|
||||
return {
|
||||
type : 'USER_LOGIN'
|
||||
};
|
||||
};
|
||||
|
||||
export const userLogout = () =>
|
||||
{
|
||||
return {
|
||||
type : 'USER_LOGOUT'
|
||||
};
|
||||
};
|
||||
|
||||
export const raiseHand = () =>
|
||||
{
|
||||
return {
|
||||
type : 'RAISE_HAND'
|
||||
};
|
||||
};
|
||||
|
||||
export const lowerHand = () =>
|
||||
{
|
||||
return {
|
||||
type : 'LOWER_HAND'
|
||||
};
|
||||
};
|
||||
|
||||
export const restartIce = () =>
|
||||
{
|
||||
return {
|
||||
type : 'RESTART_ICE'
|
||||
};
|
||||
};
|
||||
|
||||
export const enableScreenSharing = () =>
|
||||
{
|
||||
return {
|
||||
type : 'ENABLE_SCREEN_SHARING'
|
||||
};
|
||||
};
|
||||
|
||||
export const disableScreenSharing = () =>
|
||||
{
|
||||
return {
|
||||
type : 'DISABLE_SCREEN_SHARING'
|
||||
};
|
||||
};
|
||||
|
||||
export const installExtension = () =>
|
||||
{
|
||||
return {
|
||||
type : 'INSTALL_EXTENSION'
|
||||
};
|
||||
};
|
||||
|
||||
export const toggleHand = (enable) =>
|
||||
{
|
||||
if (enable)
|
||||
return {
|
||||
type : 'RAISE_HAND'
|
||||
};
|
||||
else
|
||||
return {
|
||||
type : 'LOWER_HAND'
|
||||
};
|
||||
};
|
||||
|
||||
export const sendChatMessage = (text, name, picture) =>
|
||||
{
|
||||
const message = createNewMessage(text, 'response', name, picture);
|
||||
|
||||
return {
|
||||
type : 'SEND_CHAT_MESSAGE',
|
||||
payload : { message }
|
||||
};
|
||||
};
|
||||
|
||||
export const sendFile = (file, name, picture) =>
|
||||
{
|
||||
return {
|
||||
type : 'SEND_FILE',
|
||||
payload : { file, name, picture }
|
||||
};
|
||||
};
|
||||
|
||||
export const setSelectedPeer = (selectedPeerName) =>
|
||||
{
|
||||
return {
|
||||
type : 'REQUEST_SELECTED_PEER',
|
||||
payload : { selectedPeerName }
|
||||
};
|
||||
};
|
||||
|
||||
// This returns a redux-thunk action (a function).
|
||||
export const notify = ({ type = 'info', text, timeout }) =>
|
||||
|
|
|
|||
|
|
@ -1,253 +0,0 @@
|
|||
import RoomClient from '../RoomClient';
|
||||
|
||||
export default ({ dispatch, getState }) => (next) =>
|
||||
{
|
||||
let client;
|
||||
|
||||
return (action) =>
|
||||
{
|
||||
switch (action.type)
|
||||
{
|
||||
case 'JOIN_ROOM':
|
||||
{
|
||||
const {
|
||||
roomId,
|
||||
peerName,
|
||||
displayName,
|
||||
device,
|
||||
useSimulcast,
|
||||
produce
|
||||
} = action.payload;
|
||||
|
||||
client = new RoomClient(
|
||||
{
|
||||
roomId,
|
||||
peerName,
|
||||
displayName,
|
||||
device,
|
||||
useSimulcast,
|
||||
produce,
|
||||
dispatch,
|
||||
getState
|
||||
});
|
||||
|
||||
// TODO: TMP
|
||||
global.CLIENT = client;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'LEAVE_ROOM':
|
||||
{
|
||||
client.close();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'CHANGE_DISPLAY_NAME':
|
||||
{
|
||||
const { displayName } = action.payload;
|
||||
|
||||
client.changeDisplayName(displayName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'MUTE_MIC':
|
||||
{
|
||||
client.muteMic();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'UNMUTE_MIC':
|
||||
{
|
||||
client.unmuteMic();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ENABLE_WEBCAM':
|
||||
{
|
||||
client.enableWebcam();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'DISABLE_WEBCAM':
|
||||
{
|
||||
client.disableWebcam();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'CHANGE_WEBCAM':
|
||||
{
|
||||
const { deviceId } = action.payload;
|
||||
|
||||
client.changeWebcam(deviceId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'CHANGE_AUDIO_DEVICE':
|
||||
{
|
||||
const { deviceId } = action.payload;
|
||||
|
||||
client.changeAudioDevice(deviceId);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ENABLE_AUDIO_ONLY':
|
||||
{
|
||||
client.enableAudioOnly();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'DISABLE_AUDIO_ONLY':
|
||||
{
|
||||
client.disableAudioOnly();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'MUTE_PEER_AUDIO':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.mutePeerAudio(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'UNMUTE_PEER_AUDIO':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.unmutePeerAudio(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'PAUSE_PEER_VIDEO':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.pausePeerVideo(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'RESUME_PEER_VIDEO':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.resumePeerVideo(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'PAUSE_PEER_SCREEN':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.pausePeerScreen(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'RESUME_PEER_SCREEN':
|
||||
{
|
||||
const { peerName } = action.payload;
|
||||
|
||||
client.resumePeerScreen(peerName);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'RAISE_HAND':
|
||||
{
|
||||
client.sendRaiseHandState(true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'USER_LOGIN':
|
||||
{
|
||||
client.login();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'USER_LOGOUT':
|
||||
{
|
||||
client.logout();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'LOWER_HAND':
|
||||
{
|
||||
client.sendRaiseHandState(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'RESTART_ICE':
|
||||
{
|
||||
client.restartIce();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'ENABLE_SCREEN_SHARING':
|
||||
{
|
||||
client.enableScreenSharing();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'DISABLE_SCREEN_SHARING':
|
||||
{
|
||||
client.disableScreenSharing();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'INSTALL_EXTENSION':
|
||||
{
|
||||
client.installExtension();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'SEND_CHAT_MESSAGE':
|
||||
{
|
||||
const { message } = action.payload;
|
||||
|
||||
client.sendChatMessage(message);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 'SEND_FILE':
|
||||
{
|
||||
client.sendFile(action.payload);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'REQUEST_SELECTED_PEER':
|
||||
{
|
||||
const { selectedPeerName } = action.payload;
|
||||
|
||||
client.setSelectedPeer(selectedPeerName);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
};
|
||||
};
|
||||
|
|
@ -6,12 +6,10 @@ import {
|
|||
import thunk from 'redux-thunk';
|
||||
import { createLogger } from 'redux-logger';
|
||||
import reducers from './redux/reducers';
|
||||
import roomClientMiddleware from './redux/roomClientMiddleware';
|
||||
|
||||
const reduxMiddlewares =
|
||||
[
|
||||
thunk,
|
||||
roomClientMiddleware
|
||||
thunk
|
||||
];
|
||||
|
||||
if (process.env.NODE_ENV === 'development')
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
"@babel/plugin-transform-runtime": "^7.1.0",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"babel-plugin-jsx-control-statements": "^3.2.8",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babelify": "^10.0.0",
|
||||
"browser-sync": "^2.26.3",
|
||||
|
|
|
|||
401
app/test/DATA.js
401
app/test/DATA.js
|
|
@ -1,401 +0,0 @@
|
|||
/* eslint-disable key-spacing */
|
||||
|
||||
exports.ROOM_OPTIONS =
|
||||
{
|
||||
requestTimeout: 10000,
|
||||
transportOptions:
|
||||
{
|
||||
tcp: false
|
||||
},
|
||||
__turnServers:
|
||||
[
|
||||
{
|
||||
urls: [ 'turn:worker2.versatica.com:3478?transport=udp' ],
|
||||
username: 'testuser1',
|
||||
credential: 'testpasswd1'
|
||||
}
|
||||
],
|
||||
hidden: false
|
||||
};
|
||||
|
||||
exports.ROOM_RTP_CAPABILITIES =
|
||||
{
|
||||
codecs:
|
||||
[
|
||||
{
|
||||
name: 'PCMA',
|
||||
mimeType: 'audio/PCMA',
|
||||
kind: 'audio',
|
||||
clockRate: 8000,
|
||||
preferredPayloadType: 8,
|
||||
rtcpFeedback: [],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'opus',
|
||||
mimeType: 'audio/opus',
|
||||
kind: 'audio',
|
||||
clockRate: 48000,
|
||||
channels: 2,
|
||||
preferredPayloadType: 96,
|
||||
rtcpFeedback: [],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'SILK',
|
||||
mimeType: 'audio/SILK',
|
||||
kind: 'audio',
|
||||
clockRate: 16000,
|
||||
preferredPayloadType: 97,
|
||||
rtcpFeedback: [],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'VP9',
|
||||
mimeType: 'video/VP9',
|
||||
kind: 'video',
|
||||
clockRate: 90000,
|
||||
preferredPayloadType: 102,
|
||||
rtcpFeedback:
|
||||
[
|
||||
{
|
||||
parameter: '',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: 'pli',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: '',
|
||||
type: 'goog-remb'
|
||||
},
|
||||
{
|
||||
parameter: 'bar',
|
||||
type: 'foo'
|
||||
}
|
||||
],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'rtx',
|
||||
mimeType: 'video/rtx',
|
||||
kind: 'video',
|
||||
clockRate: 90000,
|
||||
preferredPayloadType: 103,
|
||||
rtcpFeedback: [],
|
||||
parameters: {
|
||||
apt: 102
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'VP8',
|
||||
mimeType: 'video/VP8',
|
||||
kind: 'video',
|
||||
clockRate: 90000,
|
||||
preferredPayloadType: 100,
|
||||
rtcpFeedback:
|
||||
[
|
||||
{
|
||||
parameter: '',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: 'pli',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: '',
|
||||
type: 'goog-remb'
|
||||
},
|
||||
{
|
||||
parameter: 'bar',
|
||||
type: 'foo'
|
||||
}
|
||||
],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'rtx',
|
||||
mimeType: 'video/rtx',
|
||||
kind: 'video',
|
||||
clockRate: 90000,
|
||||
preferredPayloadType: 101,
|
||||
rtcpFeedback: [],
|
||||
parameters: {
|
||||
apt: 100
|
||||
}
|
||||
}
|
||||
],
|
||||
headerExtensions: [
|
||||
{
|
||||
kind: 'audio',
|
||||
uri: 'urn:ietf:params:rtp-hdrext:ssrc-audio-level',
|
||||
preferredId: 10
|
||||
},
|
||||
{
|
||||
kind: 'video',
|
||||
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time',
|
||||
preferredId: 11
|
||||
},
|
||||
{
|
||||
kind: 'video',
|
||||
uri: 'http://foo.bar',
|
||||
preferredId: 12
|
||||
}
|
||||
],
|
||||
fecMechanisms: []
|
||||
};
|
||||
|
||||
exports.QUERY_ROOM_RESPONSE =
|
||||
{
|
||||
rtpCapabilities: exports.ROOM_RTP_CAPABILITIES
|
||||
};
|
||||
|
||||
exports.JOIN_ROOM_RESPONSE =
|
||||
{
|
||||
peers:
|
||||
[
|
||||
{
|
||||
name: 'alice',
|
||||
appData: 'Alice iPad Pro',
|
||||
consumers:
|
||||
[
|
||||
{
|
||||
id: 3333,
|
||||
kind: 'audio',
|
||||
paused: false,
|
||||
appData: 'ALICE_MIC',
|
||||
rtpParameters:
|
||||
{
|
||||
muxId: null,
|
||||
codecs:
|
||||
[
|
||||
{
|
||||
name: 'PCMA',
|
||||
mimeType: 'audio/PCMA',
|
||||
clockRate: 8000,
|
||||
payloadType: 8,
|
||||
rtcpFeedback: [],
|
||||
parameters: {}
|
||||
}
|
||||
],
|
||||
headerExtensions:
|
||||
[
|
||||
{
|
||||
uri: 'urn:ietf:params:rtp-hdrext:ssrc-audio-level',
|
||||
id: 1
|
||||
}
|
||||
],
|
||||
encodings:
|
||||
[
|
||||
{
|
||||
ssrc: 33333333
|
||||
}
|
||||
],
|
||||
rtcp:
|
||||
{
|
||||
cname: 'ALICECNAME',
|
||||
reducedSize: true,
|
||||
mux: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'bob',
|
||||
appData: 'Bob HP Laptop',
|
||||
consumers:
|
||||
[
|
||||
{
|
||||
id: 6666,
|
||||
kind: 'audio',
|
||||
paused: false,
|
||||
appData: 'BOB_MIC',
|
||||
rtpParameters:
|
||||
{
|
||||
muxId: null,
|
||||
codecs:
|
||||
[
|
||||
{
|
||||
name: 'opus',
|
||||
mimeType: 'audio/opus',
|
||||
clockRate: 48000,
|
||||
channels: 2,
|
||||
payloadType: 96,
|
||||
rtcpFeedback: [],
|
||||
parameters: {}
|
||||
}
|
||||
],
|
||||
headerExtensions:
|
||||
[
|
||||
{
|
||||
uri: 'urn:ietf:params:rtp-hdrext:ssrc-audio-level',
|
||||
id: 1
|
||||
}
|
||||
],
|
||||
encodings:
|
||||
[
|
||||
{
|
||||
ssrc: 66666666
|
||||
}
|
||||
],
|
||||
rtcp:
|
||||
{
|
||||
cname: 'BOBCNAME',
|
||||
reducedSize: true,
|
||||
mux: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
exports.CREATE_TRANSPORT_1_RESPONSE =
|
||||
{
|
||||
iceParameters:
|
||||
{
|
||||
usernameFragment: 'server-usernamefragment-12345678',
|
||||
password: 'server-password-xxxxxxxx',
|
||||
iceLite: true
|
||||
},
|
||||
iceCandidates:
|
||||
[
|
||||
{
|
||||
foundation: 'F1',
|
||||
priority: 1234,
|
||||
ip: '1.2.3.4',
|
||||
protocol: 'udp',
|
||||
port: 9999,
|
||||
type: 'host'
|
||||
}
|
||||
],
|
||||
dtlsParameters:
|
||||
{
|
||||
fingerprints:
|
||||
[
|
||||
{
|
||||
algorithm: 'sha-256',
|
||||
value: 'FF:FF:39:66:A4:E2:66:60:30:18:A7:59:B3:AF:A5:33:58:5E:7F:69:A4:62:A6:D4:EB:9F:B7:42:05:35:FF:FF'
|
||||
}
|
||||
],
|
||||
role: 'client'
|
||||
}
|
||||
};
|
||||
|
||||
exports.CREATE_TRANSPORT_2_RESPONSE =
|
||||
{
|
||||
iceParameters:
|
||||
{
|
||||
usernameFragment: 'server-usernamefragment-12345678',
|
||||
password: 'server-password-xxxxxxxx',
|
||||
iceLite: true
|
||||
},
|
||||
iceCandidates:
|
||||
[
|
||||
{
|
||||
foundation: 'F1',
|
||||
priority: 1234,
|
||||
ip: '1.2.3.4',
|
||||
protocol: 'udp',
|
||||
port: 9999,
|
||||
type: 'host'
|
||||
}
|
||||
],
|
||||
dtlsParameters:
|
||||
{
|
||||
fingerprints:
|
||||
[
|
||||
{
|
||||
algorithm: 'sha-256',
|
||||
value: 'FF:FF:39:66:A4:E2:66:60:30:18:A7:59:B3:AF:A5:33:58:5E:7F:69:A4:62:A6:D4:EB:9F:B7:42:05:35:FF:FF'
|
||||
}
|
||||
],
|
||||
role: 'auto'
|
||||
}
|
||||
};
|
||||
|
||||
exports.ALICE_WEBCAM_NEW_CONSUMER_NOTIFICATION =
|
||||
{
|
||||
method: 'newConsumer',
|
||||
notification: true,
|
||||
id: 4444,
|
||||
peerName: 'alice',
|
||||
kind: 'video',
|
||||
paused: true,
|
||||
appData: 'ALICE_WEBCAM',
|
||||
rtpParameters:
|
||||
{
|
||||
muxId: null,
|
||||
codecs:
|
||||
[
|
||||
{
|
||||
name: 'VP8',
|
||||
mimeType: 'video/VP8',
|
||||
clockRate: 90000,
|
||||
payloadType: 100,
|
||||
rtcpFeedback:
|
||||
[
|
||||
{
|
||||
parameter: '',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: 'pli',
|
||||
type: 'nack'
|
||||
},
|
||||
{
|
||||
parameter: '',
|
||||
type: 'goog-remb'
|
||||
},
|
||||
{
|
||||
parameter: 'bar',
|
||||
type: 'foo'
|
||||
}
|
||||
],
|
||||
parameters: {}
|
||||
},
|
||||
{
|
||||
name: 'rtx',
|
||||
mimeType: 'video/rtx',
|
||||
clockRate: 90000,
|
||||
payloadType: 101,
|
||||
rtcpFeedback: [],
|
||||
parameters: {
|
||||
apt: 100
|
||||
}
|
||||
}
|
||||
],
|
||||
headerExtensions:
|
||||
[
|
||||
{
|
||||
kind: 'video',
|
||||
uri: 'http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time',
|
||||
id: 11
|
||||
},
|
||||
{
|
||||
kind: 'video',
|
||||
uri: 'http://foo.bar',
|
||||
id: 12
|
||||
}
|
||||
],
|
||||
encodings:
|
||||
[
|
||||
{
|
||||
ssrc: 444444441,
|
||||
rtx: {
|
||||
ssrc: 444444442
|
||||
}
|
||||
}
|
||||
],
|
||||
rtcp:
|
||||
{
|
||||
cname: 'ALICECNAME',
|
||||
reducedSize: true,
|
||||
mux: true
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,145 +0,0 @@
|
|||
const path = require('path');
|
||||
const gulp = require('gulp');
|
||||
const gutil = require('gulp-util');
|
||||
const plumber = require('gulp-plumber');
|
||||
const rename = require('gulp-rename');
|
||||
const browserify = require('browserify');
|
||||
const watchify = require('watchify');
|
||||
const envify = require('envify/custom');
|
||||
const source = require('vinyl-source-stream');
|
||||
const buffer = require('vinyl-buffer');
|
||||
const eslint = require('gulp-eslint');
|
||||
const browserSync = require('browser-sync');
|
||||
|
||||
const OUTPUT_DIR = 'output';
|
||||
const APP_NAME = 'mediasoup-client-test';
|
||||
|
||||
// Node environment.
|
||||
process.env.NODE_ENV = 'development';
|
||||
|
||||
function logError(error)
|
||||
{
|
||||
gutil.log(gutil.colors.red(error.stack));
|
||||
}
|
||||
|
||||
gulp.task('lint', () =>
|
||||
{
|
||||
const src =
|
||||
[
|
||||
'gulpfile.js',
|
||||
'**/*.js',
|
||||
'**/*.jsx'
|
||||
];
|
||||
|
||||
return gulp.src(src)
|
||||
.pipe(plumber())
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format());
|
||||
});
|
||||
|
||||
gulp.task('html', () =>
|
||||
{
|
||||
return gulp.src('index.html')
|
||||
.pipe(gulp.dest(OUTPUT_DIR));
|
||||
});
|
||||
|
||||
gulp.task('bundle', () =>
|
||||
{
|
||||
const watch = true;
|
||||
|
||||
let bundler = browserify(
|
||||
{
|
||||
entries : 'index.jsx',
|
||||
extensions : [ '.js', '.jsx' ],
|
||||
// required for sourcemaps (must be false otherwise).
|
||||
debug : process.env.NODE_ENV === 'development',
|
||||
// required for watchify.
|
||||
cache : {},
|
||||
// required for watchify.
|
||||
packageCache : {},
|
||||
// required to be true only for watchify.
|
||||
fullPaths : watch
|
||||
})
|
||||
.transform('babelify',
|
||||
{
|
||||
presets : [ 'es2015', 'es2017', 'react' ],
|
||||
plugins :
|
||||
[
|
||||
'transform-runtime',
|
||||
'transform-object-assign',
|
||||
'transform-object-rest-spread'
|
||||
]
|
||||
})
|
||||
.transform(envify(
|
||||
{
|
||||
NODE_ENV : process.env.NODE_ENV,
|
||||
_ : 'purge'
|
||||
}));
|
||||
|
||||
if (watch)
|
||||
{
|
||||
bundler = watchify(bundler);
|
||||
|
||||
bundler.on('update', () =>
|
||||
{
|
||||
const start = Date.now();
|
||||
|
||||
gutil.log('bundling...');
|
||||
rebundle();
|
||||
gutil.log('bundle took %sms', (Date.now() - start));
|
||||
});
|
||||
}
|
||||
|
||||
function rebundle()
|
||||
{
|
||||
return bundler.bundle()
|
||||
.on('error', logError)
|
||||
.pipe(plumber())
|
||||
.pipe(source(`${APP_NAME}.js`))
|
||||
.pipe(buffer())
|
||||
.pipe(rename(`${APP_NAME}.js`))
|
||||
.pipe(gulp.dest(OUTPUT_DIR));
|
||||
}
|
||||
|
||||
return rebundle();
|
||||
});
|
||||
|
||||
gulp.task('livebrowser', (done) =>
|
||||
{
|
||||
browserSync(
|
||||
{
|
||||
server :
|
||||
{
|
||||
baseDir : OUTPUT_DIR
|
||||
},
|
||||
ghostMode : false,
|
||||
files : path.join(OUTPUT_DIR, '**', '*')
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('watch', (done) =>
|
||||
{
|
||||
// Watch changes in HTML.
|
||||
gulp.watch([ 'index.html' ], gulp.series(
|
||||
'html'
|
||||
));
|
||||
|
||||
// Watch changes in JS files.
|
||||
gulp.watch([ 'gulpfile.js', '**/*.js', '**/*.jsx' ], gulp.series(
|
||||
'lint'
|
||||
));
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('live', gulp.series(
|
||||
'lint',
|
||||
'html',
|
||||
'bundle',
|
||||
'watch',
|
||||
'livebrowser'
|
||||
));
|
||||
|
||||
gulp.task('default', gulp.series('live'));
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>mediasoup-client test</title>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'>
|
||||
<meta name='description' content='mediasoup-client test'>
|
||||
|
||||
<script async src='/mediasoup-client-test.js'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>mediasoup-client test</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,692 +0,0 @@
|
|||
import * as mediasoupClient from 'mediasoup-client';
|
||||
import domready from 'domready';
|
||||
import Logger from '../lib/Logger';
|
||||
const DATA = require('./DATA');
|
||||
|
||||
window.mediasoupClient = mediasoupClient;
|
||||
|
||||
const logger = new Logger();
|
||||
|
||||
|
||||
const SEND = true;
|
||||
const SEND_AUDIO = true;
|
||||
const SEND_VIDEO = false;
|
||||
const RECV = true;
|
||||
|
||||
|
||||
domready(() =>
|
||||
{
|
||||
logger.debug('DOM ready');
|
||||
|
||||
run();
|
||||
});
|
||||
|
||||
function run()
|
||||
{
|
||||
logger.debug('run() [environment:%s]', process.env.NODE_ENV);
|
||||
|
||||
let transport1;
|
||||
let transport2;
|
||||
let audioTrack;
|
||||
let videoTrack;
|
||||
let audioProducer1;
|
||||
let audioProducer2;
|
||||
let videoProducer;
|
||||
|
||||
logger.debug('calling room = new mediasoupClient.Room()');
|
||||
|
||||
// const room = new mediasoupClient.Room();
|
||||
const room = new mediasoupClient.Room(DATA.ROOM_OPTIONS);
|
||||
|
||||
window.room = room;
|
||||
|
||||
room.on('closed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'room "closed" event [originator:%s, appData:%o]', originator, appData);
|
||||
});
|
||||
|
||||
room.on('request', (request, callback, errback) =>
|
||||
{
|
||||
logger.warn('sending request [method:%s]:%o', request.method, request);
|
||||
|
||||
switch (request.method)
|
||||
{
|
||||
case 'queryRoom':
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
callback(DATA.QUERY_ROOM_RESPONSE);
|
||||
errback('upppps');
|
||||
}, 200);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'joinRoom':
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
callback(DATA.JOIN_ROOM_RESPONSE);
|
||||
// errback('upppps');
|
||||
}, 200);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'createTransport':
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
switch (request.appData)
|
||||
{
|
||||
case 'TRANSPORT_1':
|
||||
callback(DATA.CREATE_TRANSPORT_1_RESPONSE);
|
||||
break;
|
||||
case 'TRANSPORT_2':
|
||||
callback(DATA.CREATE_TRANSPORT_2_RESPONSE);
|
||||
break;
|
||||
default:
|
||||
errback('upppps');
|
||||
}
|
||||
}, 250);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'createProducer':
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
callback();
|
||||
}, 250);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'enableConsumer':
|
||||
{
|
||||
setTimeout(() =>
|
||||
{
|
||||
callback();
|
||||
}, 500);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
errback(`NO IDEA ABOUT REQUEST METHOD "${request.method}"`);
|
||||
}
|
||||
});
|
||||
|
||||
room.on('notify', (notification) =>
|
||||
{
|
||||
logger.warn(
|
||||
'sending notification [method:%s]:%o', notification.method, notification);
|
||||
|
||||
switch (notification.method)
|
||||
{
|
||||
case 'leaveRoom':
|
||||
case 'updateTransport':
|
||||
case 'closeTransport':
|
||||
case 'closeProducer':
|
||||
case 'pauseProducer':
|
||||
case 'resumeProducer':
|
||||
case 'pauseConsumer':
|
||||
case 'resumeConsumer':
|
||||
break;
|
||||
|
||||
default:
|
||||
logger.error(`NO IDEA ABOUT NOTIFICATION METHOD "${notification.method}"`);
|
||||
}
|
||||
});
|
||||
|
||||
room.on('newpeer', (peer) =>
|
||||
{
|
||||
logger.warn('room "newpeer" event [name:"%s", peer:%o]', peer.name, peer);
|
||||
|
||||
handlePeer(peer);
|
||||
});
|
||||
|
||||
Promise.resolve()
|
||||
.then(() =>
|
||||
{
|
||||
logger.debug('calling room.join()');
|
||||
|
||||
const deviceInfo = mediasoupClient.getDeviceInfo();
|
||||
const appData =
|
||||
{
|
||||
device : `${deviceInfo.name} ${deviceInfo.version}`
|
||||
};
|
||||
|
||||
return room.join(null, appData);
|
||||
// return room.join(DATA.ROOM_RTP_CAPABILITIES, appData);
|
||||
})
|
||||
.then((peers) =>
|
||||
{
|
||||
if (!RECV)
|
||||
return;
|
||||
|
||||
logger.debug('room.join() succeeded');
|
||||
|
||||
logger.debug('calling transport2 = room.createTransport("recv")');
|
||||
|
||||
transport2 = room.createTransport('recv', 'TRANSPORT_2');
|
||||
window.transport2 = transport2;
|
||||
window.pc2 = transport2._handler._pc;
|
||||
|
||||
handleTransport(transport2);
|
||||
|
||||
for (const peer of peers)
|
||||
{
|
||||
handlePeer(peer);
|
||||
}
|
||||
})
|
||||
.then(() =>
|
||||
{
|
||||
if (!SEND)
|
||||
return;
|
||||
|
||||
if (room.canSend('audio'))
|
||||
logger.debug('can send audio');
|
||||
else
|
||||
logger.warn('cannot send audio');
|
||||
|
||||
if (room.canSend('video'))
|
||||
logger.debug('can send video');
|
||||
else
|
||||
logger.warn('cannot send video');
|
||||
|
||||
logger.debug('calling transport1 = room.createTransport("send")');
|
||||
|
||||
transport1 = room.createTransport('send', 'TRANSPORT_1');
|
||||
window.transport1 = transport1;
|
||||
window.pc1 = transport1._handler._pc;
|
||||
|
||||
handleTransport(transport1);
|
||||
|
||||
logger.debug('calling getUserMedia()');
|
||||
|
||||
return navigator.mediaDevices
|
||||
.getUserMedia({ audio: SEND_AUDIO, video: SEND_VIDEO });
|
||||
})
|
||||
.then((stream) =>
|
||||
{
|
||||
if (!SEND)
|
||||
return;
|
||||
|
||||
audioTrack = stream.getAudioTracks()[0];
|
||||
videoTrack = stream.getVideoTracks()[0];
|
||||
window.audioTrack = audioTrack;
|
||||
window.videoTrack = videoTrack;
|
||||
})
|
||||
// Add Producers.
|
||||
.then(() =>
|
||||
{
|
||||
if (audioTrack)
|
||||
{
|
||||
const deviceId = audioTrack.getSettings().deviceId;
|
||||
|
||||
logger.debug('calling audioProducer1 = room.createProducer(audioTrack)');
|
||||
|
||||
try
|
||||
{
|
||||
audioProducer1 = room.createProducer(audioTrack, `${deviceId}-1`);
|
||||
window.audioProducer1 = audioProducer1;
|
||||
|
||||
handleProducer(audioProducer1);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
logger.error(error);
|
||||
}
|
||||
|
||||
logger.debug('calling audioProducer2 = room.createProducer(audioTrack)');
|
||||
|
||||
try
|
||||
{
|
||||
audioProducer2 = room.createProducer(audioTrack, `${deviceId}-2`);
|
||||
window.audioProducer2 = audioProducer2;
|
||||
|
||||
handleProducer(audioProducer2);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (videoTrack)
|
||||
{
|
||||
const deviceId = videoTrack.getSettings().deviceId;
|
||||
|
||||
logger.debug('calling videoProducer = room.createProducer(videoTrack)');
|
||||
|
||||
try
|
||||
{
|
||||
videoProducer = room.createProducer(videoTrack, `${deviceId}-1`);
|
||||
window.videoProducer = videoProducer;
|
||||
|
||||
handleProducer(videoProducer);
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
logger.error(error);
|
||||
}
|
||||
}
|
||||
})
|
||||
// Receive notifications.
|
||||
.then(() =>
|
||||
{
|
||||
if (!RECV)
|
||||
return;
|
||||
|
||||
setTimeout(() =>
|
||||
{
|
||||
room.receiveNotification(DATA.ALICE_WEBCAM_NEW_CONSUMER_NOTIFICATION);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
function handleTransport(transport)
|
||||
{
|
||||
logger.warn(
|
||||
'handleTransport() [direction:%s, appData:"%s", transport:%o]',
|
||||
transport.direction, transport.appData, transport);
|
||||
|
||||
transport.on('closed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'transport "closed" event [originator:%s, appData:%o, transport:%o]',
|
||||
originator, appData, transport);
|
||||
});
|
||||
|
||||
transport.on('connectionstatechange', (state) =>
|
||||
{
|
||||
logger.warn(
|
||||
'transport "connectionstatechange" event [direction:%s, state:%s, transport:%o]',
|
||||
transport.direction, state, transport);
|
||||
});
|
||||
|
||||
setInterval(() =>
|
||||
{
|
||||
const queue = transport._commandQueue._queue;
|
||||
|
||||
if (queue.length !== 0)
|
||||
logger.error('queue not empty [transport:%o, queue:%o]', transport, queue);
|
||||
}, 15000);
|
||||
}
|
||||
|
||||
function handlePeer(peer)
|
||||
{
|
||||
logger.warn('handlePeer() [name:"%s", peer:%o]', peer.name, peer);
|
||||
|
||||
switch (peer.name)
|
||||
{
|
||||
case 'alice':
|
||||
window.alice = peer;
|
||||
break;
|
||||
case 'bob':
|
||||
window.bob = peer;
|
||||
break;
|
||||
}
|
||||
|
||||
for (const consumer of peer.consumers)
|
||||
{
|
||||
handleConsumer(consumer);
|
||||
}
|
||||
|
||||
peer.on('closed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'peer "closed" event [name:"%s", originator:%s, appData:%o]',
|
||||
peer.name, originator, appData);
|
||||
});
|
||||
|
||||
peer.on('newconsumer', (consumer) =>
|
||||
{
|
||||
logger.warn(
|
||||
'peer "newconsumer" event [name:"%s", id:%s, consumer:%o]',
|
||||
peer.name, consumer.id, consumer);
|
||||
|
||||
handleConsumer(consumer);
|
||||
});
|
||||
}
|
||||
|
||||
function handleProducer(producer)
|
||||
{
|
||||
const transport1 = window.transport1;
|
||||
|
||||
logger.debug(
|
||||
'handleProducer() [id:"%s", appData:%o, producer:%o]',
|
||||
producer.id, producer.appData, producer);
|
||||
|
||||
logger.debug('handleProducer() | calling transport1.send(producer)');
|
||||
|
||||
transport1.send(producer)
|
||||
.then(() =>
|
||||
{
|
||||
logger.debug('transport1.send(producer) succeeded');
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('transport1.send(producer) failed: %o', error);
|
||||
});
|
||||
|
||||
producer.on('closed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'producer "closed" event [id:%s, originator:%s, appData:%o, producer:%o]',
|
||||
producer.id, originator, appData, producer);
|
||||
});
|
||||
|
||||
producer.on('paused', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'producer "paused" event [id:%s, originator:%s, appData:%o, producer:%o]',
|
||||
producer.id, originator, appData, producer);
|
||||
});
|
||||
|
||||
producer.on('resumed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'producer "resumed" event [id:%s, originator:%s, appData:%o, producer:%o]',
|
||||
producer.id, originator, appData, producer);
|
||||
});
|
||||
|
||||
producer.on('unhandled', () =>
|
||||
{
|
||||
logger.warn(
|
||||
'producer "unhandled" event [id:%s, producer:%o]', producer.id, producer);
|
||||
});
|
||||
}
|
||||
|
||||
function handleConsumer(consumer)
|
||||
{
|
||||
const transport2 = window.transport2;
|
||||
|
||||
logger.debug(
|
||||
'handleConsumer() [id:"%s", appData:%o, consumer:%o]',
|
||||
consumer.id, consumer.appData, consumer);
|
||||
|
||||
switch (consumer.appData)
|
||||
{
|
||||
case 'ALICE_MIC':
|
||||
window.aliceAudioConsumer = consumer;
|
||||
break;
|
||||
case 'ALICE_WEBCAM':
|
||||
window.aliceVideoConsumer = consumer;
|
||||
break;
|
||||
case 'BOB_MIC':
|
||||
window.bobAudioConsumer = consumer;
|
||||
break;
|
||||
}
|
||||
|
||||
logger.debug('handleConsumer() calling transport2.receive(consumer)');
|
||||
|
||||
transport2.receive(consumer)
|
||||
.then((track) =>
|
||||
{
|
||||
logger.warn(
|
||||
'transport2.receive(consumer) succeeded [track:%o]', track);
|
||||
})
|
||||
.catch((error) =>
|
||||
{
|
||||
logger.error('transport2.receive() failed:%o', error);
|
||||
});
|
||||
|
||||
consumer.on('closed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'consumer "closed" event [id:%s, originator:%s, appData:%o, consumer:%o]',
|
||||
consumer.id, originator, appData, consumer);
|
||||
});
|
||||
|
||||
consumer.on('paused', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'consumer "paused" event [id:%s, originator:%s, appData:%o, consumer:%o]',
|
||||
consumer.id, originator, appData, consumer);
|
||||
});
|
||||
|
||||
consumer.on('resumed', (originator, appData) =>
|
||||
{
|
||||
logger.warn(
|
||||
'consumer "resumed" event [id:%s, originator:%s, appData:%o, consumer:%o]',
|
||||
consumer.id, originator, appData, consumer);
|
||||
});
|
||||
|
||||
consumer.on('unhandled', () =>
|
||||
{
|
||||
logger.warn(
|
||||
'consumer "unhandled" event [id:%s, consumer:%o]', consumer.id, consumer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Trigger server notifications.
|
||||
|
||||
window.notifyRoomClosed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'roomClosed',
|
||||
notification : true,
|
||||
appData : 'ha cascao la room remota!!!'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyTransportClosed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'transportClosed',
|
||||
notification : true,
|
||||
id : room.transports[0].id,
|
||||
appData : 'admin closed your transport'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAudioProducer1Closed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'producerClosed',
|
||||
notification : true,
|
||||
id : window.audioProducer1.id,
|
||||
appData : 'te paro el micro por la fuerza'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAudioProducer1Paused = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'producerPaused',
|
||||
notification : true,
|
||||
id : window.audioProducer1.id,
|
||||
appData : 'te pause el micro por la fuerza'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAudioProducer1Resumed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'producerResumed',
|
||||
notification : true,
|
||||
id : window.audioProducer1.id,
|
||||
appData : 'te resumo el micro'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAlicePeerClosed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'peerClosed',
|
||||
notification : true,
|
||||
name : 'alice',
|
||||
appData : 'peer left'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAliceAudioConsumerClosed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'consumerClosed',
|
||||
notification : true,
|
||||
peerName : 'alice',
|
||||
id : 3333,
|
||||
appData : 'mic broken'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAliceVideoConsumerClosed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'consumerClosed',
|
||||
notification : true,
|
||||
peerName : 'alice',
|
||||
id : 4444,
|
||||
appData : 'webcam broken'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAliceVideoConsumerPaused = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'consumerPaused',
|
||||
notification : true,
|
||||
peerName : 'alice',
|
||||
id : 4444,
|
||||
appData : 'webcam paused'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
window.notifyAliceVideoConsumerResumed = function()
|
||||
{
|
||||
const room = window.room;
|
||||
const notification =
|
||||
{
|
||||
method : 'consumerResumed',
|
||||
notification : true,
|
||||
peerName : 'alice',
|
||||
id : 4444,
|
||||
appData : 'webcam resumed'
|
||||
};
|
||||
|
||||
room.receiveNotification(notification);
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Test pause/resume.
|
||||
|
||||
window.testPauseResume = function()
|
||||
{
|
||||
logger.debug('testPauseResume() with audioProducer1');
|
||||
|
||||
const producer = window.audioProducer1;
|
||||
|
||||
// producer.once('paused', () =>
|
||||
// {
|
||||
// producer.resume('I RESUME TO FUACK!!!');
|
||||
// });
|
||||
|
||||
logger.debug('testPauseResume() | (1) calling producer.pause()');
|
||||
|
||||
if (producer.pause('I PAUSE (1)'))
|
||||
{
|
||||
logger.warn(
|
||||
'testPauseResume() | (1) producer.pause() succeeded [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error(
|
||||
'testPauseResume() | (1) producer.pause() failed [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
|
||||
logger.debug('testPauseResume() | (2) calling producer.pause()');
|
||||
|
||||
if (producer.pause('I PAUSE (2)'))
|
||||
{
|
||||
logger.warn(
|
||||
'testPauseResume() | (2) producer.pause() succeeded [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error(
|
||||
'testPauseResume() | (2) producer.pause() failed [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
|
||||
logger.debug('testPauseResume() | (3) calling producer.resume()');
|
||||
|
||||
if (producer.resume('I RESUME (3)'))
|
||||
{
|
||||
logger.warn(
|
||||
'testPauseResume() | (3) producer.resume() succeeded [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.error(
|
||||
'testPauseResume() | (3) producer.resume() failed [locallyPaused:%s]',
|
||||
producer.locallyPaused);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// NOTE: For debugging.
|
||||
|
||||
window.dump1 = function()
|
||||
{
|
||||
const transport1 = window.transport1;
|
||||
const pc1 = transport1._handler._pc;
|
||||
|
||||
if (pc1 && pc1.localDescription)
|
||||
logger.warn('PC1 SEND LOCAL OFFER:\n%s', pc1.localDescription.sdp);
|
||||
|
||||
if (pc1 && pc1.remoteDescription)
|
||||
logger.warn('PC1 SEND REMOTE ANSWER:\n%s', pc1.remoteDescription.sdp);
|
||||
};
|
||||
|
||||
window.dump2 = function()
|
||||
{
|
||||
const transport2 = window.transport2;
|
||||
const pc2 = transport2._handler._pc;
|
||||
|
||||
if (pc2 && pc2.remoteDescription)
|
||||
logger.warn('PC2 RECV REMOTE OFFER:\n%s', pc2.remoteDescription.sdp);
|
||||
|
||||
if (pc2 && pc2.localDescription)
|
||||
logger.warn('PC2 RECV LOCAL ANSWER:\n%s', pc2.localDescription.sdp);
|
||||
};
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>mediasoup-client test</title>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'>
|
||||
<meta name='description' content='mediasoup-client test'>
|
||||
|
||||
<script async src='/mediasoup-client-test.js'></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>mediasoup-client test</h1>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue