Merge branch 'develop' into feat-network-indicator
commit
ddd8c36c67
|
|
@ -0,0 +1,2 @@
|
||||||
|
REACT_APP_VERSION=$npm_package_version
|
||||||
|
REACT_APP_NAME=$npm_package_name
|
||||||
|
|
@ -159,6 +159,12 @@
|
||||||
"no-inner-declarations": 2,
|
"no-inner-declarations": 2,
|
||||||
"no-invalid-regexp": 2,
|
"no-invalid-regexp": 2,
|
||||||
"no-irregular-whitespace": 2,
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-trailing-spaces": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreComments": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"no-lonely-if": 2,
|
"no-lonely-if": 2,
|
||||||
"no-mixed-operators": 2,
|
"no-mixed-operators": 2,
|
||||||
"no-mixed-spaces-and-tabs": 2,
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,26 @@ var config =
|
||||||
developmentPort : 3443,
|
developmentPort : 3443,
|
||||||
productionPort : 443,
|
productionPort : 443,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported browsers version
|
||||||
|
* in bowser satisfy format.
|
||||||
|
* See more:
|
||||||
|
* https://www.npmjs.com/package/bowser#filtering-browsers
|
||||||
|
* Otherwise you got a unsupported browser page
|
||||||
|
*/
|
||||||
|
supportedBrowsers :
|
||||||
|
{
|
||||||
|
'windows' : {
|
||||||
|
'internet explorer' : '>12',
|
||||||
|
'microsoft edge' : '>18'
|
||||||
|
},
|
||||||
|
'safari' : '>12',
|
||||||
|
'firefox' : '>=60',
|
||||||
|
'chrome' : '>=74',
|
||||||
|
'opera' : '>=62',
|
||||||
|
'samsung internet for android' : '>=11.1.1.52'
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If defaultResolution is set, it will override user settings when joining:
|
* If defaultResolution is set, it will override user settings when joining:
|
||||||
* low ~ 320x240
|
* low ~ 320x240
|
||||||
|
|
@ -26,6 +46,15 @@ var config =
|
||||||
{ scaleResolutionDownBy: 1 }
|
{ scaleResolutionDownBy: 1 }
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative simulcast setting:
|
||||||
|
* [
|
||||||
|
* { maxBitRate: 50000 },
|
||||||
|
* { maxBitRate: 1000000 },
|
||||||
|
* { maxBitRate: 4800000 }
|
||||||
|
*],
|
||||||
|
**/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* White listing browsers that support audio output device selection.
|
* White listing browsers that support audio output device selection.
|
||||||
* It is not yet fully implemented in Firefox.
|
* It is not yet fully implemented in Firefox.
|
||||||
|
|
@ -37,12 +66,13 @@ var config =
|
||||||
'opera'
|
'opera'
|
||||||
],
|
],
|
||||||
// Socket.io request timeout
|
// Socket.io request timeout
|
||||||
requestTimeout : 10000,
|
requestTimeout : 20000,
|
||||||
|
requestRetries : 3,
|
||||||
transportOptions :
|
transportOptions :
|
||||||
{
|
{
|
||||||
tcp : true
|
tcp : true
|
||||||
},
|
},
|
||||||
defaultAudio :
|
defaultAudio :
|
||||||
{
|
{
|
||||||
sampleRate : 48000,
|
sampleRate : 48000,
|
||||||
channelCount : 1,
|
channelCount : 1,
|
||||||
|
|
@ -55,14 +85,16 @@ var config =
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the auto mute / Push To Talk threshold
|
* Set max number participants in one room that join
|
||||||
* default value is 4
|
* unmuted. Next participant will join automatically muted
|
||||||
|
* Default value is 4
|
||||||
*
|
*
|
||||||
* Set it to 0 to disable auto mute functionality,
|
* Set it to 0 to auto mute all,
|
||||||
|
* Set it to negative (-1) to never automatically auto mute
|
||||||
* but use it with caution
|
* but use it with caution
|
||||||
* full mesh audio strongly decrease room capacity!
|
* full mesh audio strongly decrease room capacity!
|
||||||
*/
|
*/
|
||||||
autoMuteThreshold : 4,
|
autoMuteThreshold : 4,
|
||||||
background : 'images/background.jpg',
|
background : 'images/background.jpg',
|
||||||
defaultLayout : 'democratic', // democratic, filmstrip
|
defaultLayout : 'democratic', // democratic, filmstrip
|
||||||
// If true, will show media control buttons in separate
|
// If true, will show media control buttons in separate
|
||||||
|
|
@ -75,9 +107,12 @@ var config =
|
||||||
notificationPosition : 'right',
|
notificationPosition : 'right',
|
||||||
// Timeout for autohiding topbar and button control bar
|
// Timeout for autohiding topbar and button control bar
|
||||||
hideTimeout : 3000,
|
hideTimeout : 3000,
|
||||||
|
// max number of participant that will be visible in
|
||||||
|
// as speaker
|
||||||
lastN : 4,
|
lastN : 4,
|
||||||
mobileLastN : 1,
|
mobileLastN : 1,
|
||||||
// Highest number of speakers user can select
|
// Highest number of lastN the user can select manually in
|
||||||
|
// userinteface
|
||||||
maxLastN : 5,
|
maxLastN : 5,
|
||||||
// If truthy, users can NOT change number of speakers visible
|
// If truthy, users can NOT change number of speakers visible
|
||||||
lockLastN : false,
|
lockLastN : false,
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,44 @@
|
||||||
<title>Multiparty Meeting</title>
|
<title>Multiparty Meeting</title>
|
||||||
|
|
||||||
<script src='%PUBLIC_URL%/config/config.js' type='text/javascript'></script>
|
<script src='%PUBLIC_URL%/config/config.js' type='text/javascript'></script>
|
||||||
|
|
||||||
|
<!-- Show an error page to IE browsers -->
|
||||||
|
<script type='text/javascript'>
|
||||||
|
var fallback = '<style type="text/css">body{margin:40px auto;max-width:650px;line-height:1.6;font-size:18px;color:#444;padding:0 10px}h1,h2,h3{line-height:1.2}</style><header><h1>Your browser is not supported</h1><aside>You need to change to a different browser.</aside></header><h3>Supported browsers</h3><ul><li>Google Chrome/Chromium 55 +</li><li>Microsoft Edge 18 +</li><li>Mozilla Firefox 60 +</li><li>Apple Safari 12 +</li><li>Opera 62 +</li><li>Samsung Internet 11.1.1.52 +</li></ul>';
|
||||||
|
|
||||||
|
var fallbackCall = function() {
|
||||||
|
document.body.innerHTML = fallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(navigator.userAgent.indexOf('MSIE') !== -1)
|
||||||
|
{
|
||||||
|
document.attachEvent('onreadystatechange', function() {
|
||||||
|
if (document.readyState === 'complete')
|
||||||
|
{
|
||||||
|
document.detachEvent('onreadystatechange', arguments.callee);
|
||||||
|
|
||||||
|
fallbackCall();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigator.appVersion.indexOf('Trident/') > -1)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
document.readyState === 'complete' ||
|
||||||
|
(document.readyState !== 'loading' && !document.documentElement.doScroll)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
document.removeEventListener('DOMContentLoaded', fallbackCall);
|
||||||
|
|
||||||
|
fallbackCall();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
document.addEventListener('DOMContentLoaded', fallbackCall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import Logger from './Logger';
|
import Logger from './Logger';
|
||||||
import hark from 'hark';
|
import hark from 'hark';
|
||||||
import { getSignalingUrl } from './urlFactory';
|
import { getSignalingUrl } from './urlFactory';
|
||||||
|
import { SocketTimeoutError } from './utils';
|
||||||
import * as requestActions from './actions/requestActions';
|
import * as requestActions from './actions/requestActions';
|
||||||
import * as meActions from './actions/meActions';
|
import * as meActions from './actions/meActions';
|
||||||
import * as roomActions from './actions/roomActions';
|
import * as roomActions from './actions/roomActions';
|
||||||
|
|
@ -315,7 +316,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
const newPeerId = this._spotlights.getNextAsSelected(
|
const newPeerId = this._spotlights.getNextAsSelected(
|
||||||
store.getState().room.selectedPeerId);
|
store.getState().room.selectedPeerId);
|
||||||
|
|
||||||
if (newPeerId) this.setSelectedPeer(newPeerId);
|
if (newPeerId) this.setSelectedPeer(newPeerId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -575,7 +576,7 @@ export default class RoomClient
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
ROOM_OPTIONS.requestTimeout
|
ROOM_OPTIONS.requestTimeout
|
||||||
);
|
);
|
||||||
|
|
@ -591,13 +592,13 @@ export default class RoomClient
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest(method, data)
|
_sendRequest(method, data)
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
if (!this._signalingSocket)
|
if (!this._signalingSocket)
|
||||||
{
|
{
|
||||||
reject('No socket connection.');
|
reject('No socket connection');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -607,13 +608,9 @@ export default class RoomClient
|
||||||
this.timeoutCallback((err, response) =>
|
this.timeoutCallback((err, response) =>
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
{
|
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
resolve(response);
|
resolve(response);
|
||||||
}
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -650,6 +647,33 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendRequest(method, data)
|
||||||
|
{
|
||||||
|
logger.debug('sendRequest() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = window.config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('sendRequest() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async changeDisplayName(displayName)
|
async changeDisplayName(displayName)
|
||||||
{
|
{
|
||||||
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
logger.debug('changeDisplayName() [displayName:"%s"]', displayName);
|
||||||
|
|
@ -805,7 +829,7 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
torrent.on('done', () =>
|
torrent.on('done', () =>
|
||||||
{
|
{
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
fileActions.setFileDone(
|
fileActions.setFileDone(
|
||||||
|
|
@ -955,7 +979,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
await this.sendRequest(
|
await this.sendRequest(
|
||||||
'resumeProducer', { producerId: this._micProducer.id });
|
'resumeProducer', { producerId: this._micProducer.id });
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
producerActions.setProducerResumed(this._micProducer.id));
|
producerActions.setProducerResumed(this._micProducer.id));
|
||||||
}
|
}
|
||||||
|
|
@ -1007,23 +1031,23 @@ export default class RoomClient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectLocalHark()
|
disconnectLocalHark()
|
||||||
{
|
{
|
||||||
logger.debug('disconnectLocalHark() | Stopping harkStream.');
|
logger.debug('disconnectLocalHark() | Stopping harkStream.');
|
||||||
if (this._harkStream != null)
|
if (this._harkStream != null)
|
||||||
{
|
{
|
||||||
this._harkStream.getAudioTracks()[0].stop();
|
this._harkStream.getAudioTracks()[0].stop();
|
||||||
this._harkStream = null;
|
this._harkStream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._hark != null)
|
if (this._hark != null)
|
||||||
{
|
{
|
||||||
logger.debug('disconnectLocalHark() Stopping hark.');
|
logger.debug('disconnectLocalHark() Stopping hark.');
|
||||||
this._hark.stop();
|
this._hark.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
connectLocalHark(track)
|
connectLocalHark(track)
|
||||||
{
|
{
|
||||||
logger.debug('connectLocalHark() | Track:%o', track);
|
logger.debug('connectLocalHark() | Track:%o', track);
|
||||||
this._harkStream = new MediaStream();
|
this._harkStream = new MediaStream();
|
||||||
|
|
@ -1034,23 +1058,23 @@ export default class RoomClient
|
||||||
if (!this._harkStream.getAudioTracks()[0])
|
if (!this._harkStream.getAudioTracks()[0])
|
||||||
throw new Error('getMicStream():something went wrong with hark');
|
throw new Error('getMicStream():something went wrong with hark');
|
||||||
|
|
||||||
this._hark = hark(this._harkStream,
|
this._hark = hark(this._harkStream,
|
||||||
{
|
{
|
||||||
play : false,
|
play : false,
|
||||||
interval : 5,
|
interval : 10,
|
||||||
threshold : store.getState().settings.noiseThreshold,
|
threshold : store.getState().settings.noiseThreshold,
|
||||||
history : 30
|
history : 100
|
||||||
});
|
});
|
||||||
this._hark.lastVolume = -100;
|
this._hark.lastVolume = -100;
|
||||||
|
|
||||||
this._hark.on('volume_change', (volume) =>
|
this._hark.on('volume_change', (volume) =>
|
||||||
{
|
{
|
||||||
volume = Math.round(volume);
|
volume = Math.round(volume);
|
||||||
if (this._micProducer && volume !== Math.round(this._hark.lastVolume))
|
if (this._micProducer && (volume !== Math.round(this._hark.lastVolume)))
|
||||||
{
|
{
|
||||||
if (volume < this._hark.lastVolume * 1.02)
|
if (volume < this._hark.lastVolume)
|
||||||
{
|
{
|
||||||
volume = this._hark.lastVolume * 1.02;
|
volume = this._hark.lastVolume - Math.pow((volume - this._hark.lastVolume)/(100 + this._hark.lastVolume),4)*2;
|
||||||
}
|
}
|
||||||
this._hark.lastVolume = volume;
|
this._hark.lastVolume = volume;
|
||||||
store.dispatch(peerVolumeActions.setPeerVolume(this._peerId, volume));
|
store.dispatch(peerVolumeActions.setPeerVolume(this._peerId, volume));
|
||||||
|
|
@ -1059,7 +1083,7 @@ export default class RoomClient
|
||||||
this._hark.on('speaking', () =>
|
this._hark.on('speaking', () =>
|
||||||
{
|
{
|
||||||
store.dispatch(meActions.setIsSpeaking(true));
|
store.dispatch(meActions.setIsSpeaking(true));
|
||||||
if ((store.getState().settings.voiceActivatedUnmute ||
|
if ((store.getState().settings.voiceActivatedUnmute ||
|
||||||
store.getState().me.isAutoMuted) &&
|
store.getState().me.isAutoMuted) &&
|
||||||
this._micProducer &&
|
this._micProducer &&
|
||||||
this._micProducer.paused)
|
this._micProducer.paused)
|
||||||
|
|
@ -1071,9 +1095,9 @@ export default class RoomClient
|
||||||
this._hark.on('stopped_speaking', () =>
|
this._hark.on('stopped_speaking', () =>
|
||||||
{
|
{
|
||||||
store.dispatch(meActions.setIsSpeaking(false));
|
store.dispatch(meActions.setIsSpeaking(false));
|
||||||
if (store.getState().settings.voiceActivatedUnmute &&
|
if (store.getState().settings.voiceActivatedUnmute &&
|
||||||
this._micProducer &&
|
this._micProducer &&
|
||||||
!this._micProducer.paused)
|
!this._micProducer.paused)
|
||||||
{
|
{
|
||||||
this._micProducer.pause();
|
this._micProducer.pause();
|
||||||
store.dispatch(meActions.setAutoMuted(true));
|
store.dispatch(meActions.setAutoMuted(true));
|
||||||
|
|
@ -1089,7 +1113,7 @@ export default class RoomClient
|
||||||
meActions.setAudioInProgress(true));
|
meActions.setAudioInProgress(true));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const device = this._audioDevices[deviceId];
|
const device = this._audioDevices[deviceId];
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
|
|
@ -1208,7 +1232,7 @@ export default class RoomClient
|
||||||
...VIDEO_CONSTRAINS[resolution]
|
...VIDEO_CONSTRAINS[resolution]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
const track = stream.getVideoTracks()[0];
|
const track = stream.getVideoTracks()[0];
|
||||||
|
|
@ -1219,15 +1243,15 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
await this._webcamProducer.replaceTrack({ track });
|
await this._webcamProducer.replaceTrack({ track });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._webcamProducer = await this._sendTransport.produce({
|
this._webcamProducer = await this._sendTransport.produce({
|
||||||
track,
|
track,
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'webcam'
|
source : 'webcam'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
|
|
@ -1237,7 +1261,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
logger.warn('getVideoTracks Error: First Video Track is null');
|
logger.warn('getVideoTracks Error: First Video Track is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1271,7 +1295,7 @@ export default class RoomClient
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no webcam devices');
|
throw new Error('no webcam devices');
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'changeWebcam() | new selected webcam [device:%o]',
|
'changeWebcam() | new selected webcam [device:%o]',
|
||||||
device);
|
device);
|
||||||
|
|
@ -1299,17 +1323,17 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
await this._webcamProducer.replaceTrack({ track });
|
await this._webcamProducer.replaceTrack({ track });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this._webcamProducer = await this._sendTransport.produce({
|
this._webcamProducer = await this._sendTransport.produce({
|
||||||
track,
|
track,
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'webcam'
|
source : 'webcam'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
producerActions.setProducerTrack(this._webcamProducer.id, track));
|
producerActions.setProducerTrack(this._webcamProducer.id, track));
|
||||||
|
|
||||||
|
|
@ -1318,7 +1342,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
logger.warn('getVideoTracks Error: First Video Track is null');
|
logger.warn('getVideoTracks Error: First Video Track is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -2106,7 +2130,7 @@ export default class RoomClient
|
||||||
|
|
||||||
const { displayName } = store.getState().settings;
|
const { displayName } = store.getState().settings;
|
||||||
const { picture } = store.getState().me;
|
const { picture } = store.getState().me;
|
||||||
|
|
||||||
await this.sendRequest('changeDisplayName', { displayName });
|
await this.sendRequest('changeDisplayName', { displayName });
|
||||||
await this.sendRequest('changePicture', { picture });
|
await this.sendRequest('changePicture', { picture });
|
||||||
break;
|
break;
|
||||||
|
|
@ -2115,10 +2139,10 @@ export default class RoomClient
|
||||||
case 'signInRequired':
|
case 'signInRequired':
|
||||||
{
|
{
|
||||||
store.dispatch(roomActions.setSignInRequired(true));
|
store.dispatch(roomActions.setSignInRequired(true));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'overRoomLimit':
|
case 'overRoomLimit':
|
||||||
{
|
{
|
||||||
store.dispatch(roomActions.setOverRoomLimit(true));
|
store.dispatch(roomActions.setOverRoomLimit(true));
|
||||||
|
|
@ -2134,24 +2158,24 @@ export default class RoomClient
|
||||||
|
|
||||||
store.dispatch(roomActions.toggleJoined());
|
store.dispatch(roomActions.toggleJoined());
|
||||||
store.dispatch(roomActions.setInLobby(false));
|
store.dispatch(roomActions.setInLobby(false));
|
||||||
|
|
||||||
await this._joinRoom({ joinVideo });
|
await this._joinRoom({ joinVideo });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'roomBack':
|
case 'roomBack':
|
||||||
{
|
{
|
||||||
await this._joinRoom({ joinVideo });
|
await this._joinRoom({ joinVideo });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'lockRoom':
|
case 'lockRoom':
|
||||||
{
|
{
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setRoomLocked());
|
roomActions.setRoomLocked());
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
|
|
@ -2159,15 +2183,15 @@ export default class RoomClient
|
||||||
defaultMessage : 'Room is now locked'
|
defaultMessage : 'Room is now locked'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'unlockRoom':
|
case 'unlockRoom':
|
||||||
{
|
{
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setRoomUnLocked());
|
roomActions.setRoomUnLocked());
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
|
|
@ -2175,21 +2199,21 @@ export default class RoomClient
|
||||||
defaultMessage : 'Room is now unlocked'
|
defaultMessage : 'Room is now unlocked'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'parkedPeer':
|
case 'parkedPeer':
|
||||||
{
|
{
|
||||||
const { peerId } = notification.data;
|
const { peerId } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
lobbyPeerActions.addLobbyPeer(peerId));
|
lobbyPeerActions.addLobbyPeer(peerId));
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setToolbarsVisible(true));
|
roomActions.setToolbarsVisible(true));
|
||||||
|
|
||||||
this._soundNotification();
|
this._soundNotification();
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
|
|
@ -2197,7 +2221,7 @@ export default class RoomClient
|
||||||
defaultMessage : 'New participant entered the lobby'
|
defaultMessage : 'New participant entered the lobby'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2226,7 +2250,7 @@ export default class RoomClient
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setToolbarsVisible(true));
|
roomActions.setToolbarsVisible(true));
|
||||||
|
|
||||||
|
|
@ -2243,14 +2267,14 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'lobby:peerClosed':
|
case 'lobby:peerClosed':
|
||||||
{
|
{
|
||||||
const { peerId } = notification.data;
|
const { peerId } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
lobbyPeerActions.removeLobbyPeer(peerId));
|
lobbyPeerActions.removeLobbyPeer(peerId));
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
|
|
@ -2258,10 +2282,10 @@ export default class RoomClient
|
||||||
defaultMessage : 'Participant in lobby left'
|
defaultMessage : 'Participant in lobby left'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'lobby:promotedPeer':
|
case 'lobby:promotedPeer':
|
||||||
{
|
{
|
||||||
const { peerId } = notification.data;
|
const { peerId } = notification.data;
|
||||||
|
|
@ -2271,7 +2295,7 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'lobby:changeDisplayName':
|
case 'lobby:changeDisplayName':
|
||||||
{
|
{
|
||||||
const { peerId, displayName } = notification.data;
|
const { peerId, displayName } = notification.data;
|
||||||
|
|
@ -2291,11 +2315,11 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'lobby:changePicture':
|
case 'lobby:changePicture':
|
||||||
{
|
{
|
||||||
const { peerId, picture } = notification.data;
|
const { peerId, picture } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
lobbyPeerActions.setLobbyPeerPicture(picture, peerId));
|
lobbyPeerActions.setLobbyPeerPicture(picture, peerId));
|
||||||
|
|
||||||
|
|
@ -2313,7 +2337,7 @@ export default class RoomClient
|
||||||
case 'setAccessCode':
|
case 'setAccessCode':
|
||||||
{
|
{
|
||||||
const { accessCode } = notification.data;
|
const { accessCode } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setAccessCode(accessCode));
|
roomActions.setAccessCode(accessCode));
|
||||||
|
|
||||||
|
|
@ -2327,14 +2351,14 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'setJoinByAccessCode':
|
case 'setJoinByAccessCode':
|
||||||
{
|
{
|
||||||
const { joinByAccessCode } = notification.data;
|
const { joinByAccessCode } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setJoinByAccessCode(joinByAccessCode));
|
roomActions.setJoinByAccessCode(joinByAccessCode));
|
||||||
|
|
||||||
if (joinByAccessCode)
|
if (joinByAccessCode)
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
|
|
@ -2345,7 +2369,7 @@ export default class RoomClient
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
|
|
@ -2358,20 +2382,20 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'activeSpeaker':
|
case 'activeSpeaker':
|
||||||
{
|
{
|
||||||
const { peerId } = notification.data;
|
const { peerId } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
roomActions.setRoomActiveSpeaker(peerId));
|
roomActions.setRoomActiveSpeaker(peerId));
|
||||||
|
|
||||||
if (peerId && peerId !== this._peerId)
|
if (peerId && peerId !== this._peerId)
|
||||||
this._spotlights.handleActiveSpeaker(peerId);
|
this._spotlights.handleActiveSpeaker(peerId);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'changeDisplayName':
|
case 'changeDisplayName':
|
||||||
{
|
{
|
||||||
const { peerId, displayName, oldDisplayName } = notification.data;
|
const { peerId, displayName, oldDisplayName } = notification.data;
|
||||||
|
|
@ -2579,74 +2603,74 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
const { consumerId } = notification.data;
|
const { consumerId } = notification.data;
|
||||||
const consumer = this._consumers.get(consumerId);
|
const consumer = this._consumers.get(consumerId);
|
||||||
|
|
||||||
if (!consumer)
|
if (!consumer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
consumer.close();
|
consumer.close();
|
||||||
|
|
||||||
if (consumer.hark != null)
|
if (consumer.hark != null)
|
||||||
consumer.hark.stop();
|
consumer.hark.stop();
|
||||||
|
|
||||||
this._consumers.delete(consumerId);
|
this._consumers.delete(consumerId);
|
||||||
|
|
||||||
const { peerId } = consumer.appData;
|
const { peerId } = consumer.appData;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
consumerActions.removeConsumer(consumerId, peerId));
|
consumerActions.removeConsumer(consumerId, peerId));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'consumerPaused':
|
case 'consumerPaused':
|
||||||
{
|
{
|
||||||
const { consumerId } = notification.data;
|
const { consumerId } = notification.data;
|
||||||
const consumer = this._consumers.get(consumerId);
|
const consumer = this._consumers.get(consumerId);
|
||||||
|
|
||||||
if (!consumer)
|
if (!consumer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
consumerActions.setConsumerPaused(consumerId, 'remote'));
|
consumerActions.setConsumerPaused(consumerId, 'remote'));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'consumerResumed':
|
case 'consumerResumed':
|
||||||
{
|
{
|
||||||
const { consumerId } = notification.data;
|
const { consumerId } = notification.data;
|
||||||
const consumer = this._consumers.get(consumerId);
|
const consumer = this._consumers.get(consumerId);
|
||||||
|
|
||||||
if (!consumer)
|
if (!consumer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
consumerActions.setConsumerResumed(consumerId, 'remote'));
|
consumerActions.setConsumerResumed(consumerId, 'remote'));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'consumerLayersChanged':
|
case 'consumerLayersChanged':
|
||||||
{
|
{
|
||||||
const { consumerId, spatialLayer, temporalLayer } = notification.data;
|
const { consumerId, spatialLayer, temporalLayer } = notification.data;
|
||||||
const consumer = this._consumers.get(consumerId);
|
const consumer = this._consumers.get(consumerId);
|
||||||
|
|
||||||
if (!consumer)
|
if (!consumer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
store.dispatch(consumerActions.setConsumerCurrentLayers(
|
store.dispatch(consumerActions.setConsumerCurrentLayers(
|
||||||
consumerId, spatialLayer, temporalLayer));
|
consumerId, spatialLayer, temporalLayer));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'consumerScore':
|
case 'consumerScore':
|
||||||
{
|
{
|
||||||
const { consumerId, score } = notification.data;
|
const { consumerId, score } = notification.data;
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
consumerActions.setConsumerScore(consumerId, score));
|
consumerActions.setConsumerScore(consumerId, score));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2690,7 +2714,7 @@ export default class RoomClient
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
text : intl.formatMessage({
|
text : intl.formatMessage({
|
||||||
id : 'moderator.muteScreenSharingModerator',
|
id : 'moderator.stopScreenSharing',
|
||||||
defaultMessage : 'Moderator stopped your screen sharing'
|
defaultMessage : 'Moderator stopped your screen sharing'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
|
@ -2760,7 +2784,7 @@ export default class RoomClient
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
logger.error(
|
logger.error(
|
||||||
|
|
@ -2807,7 +2831,7 @@ export default class RoomClient
|
||||||
this._webTorrent.on('error', (error) =>
|
this._webTorrent.on('error', (error) =>
|
||||||
{
|
{
|
||||||
logger.error('Filesharing [error:"%o"]', error);
|
logger.error('Filesharing [error:"%o"]', error);
|
||||||
|
|
||||||
store.dispatch(requestActions.notify(
|
store.dispatch(requestActions.notify(
|
||||||
{
|
{
|
||||||
type : 'error',
|
type : 'error',
|
||||||
|
|
@ -3029,7 +3053,7 @@ export default class RoomClient
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
locked ?
|
locked ?
|
||||||
store.dispatch(roomActions.setRoomLocked()) :
|
store.dispatch(roomActions.setRoomLocked()) :
|
||||||
store.dispatch(roomActions.setRoomUnLocked());
|
store.dispatch(roomActions.setRoomUnLocked());
|
||||||
|
|
||||||
|
|
@ -3053,16 +3077,20 @@ export default class RoomClient
|
||||||
if (!this._muted)
|
if (!this._muted)
|
||||||
{
|
{
|
||||||
await this.enableMic();
|
await this.enableMic();
|
||||||
const { autoMuteThreshold } = store.getState().settings;
|
let autoMuteThreshold = 4;
|
||||||
|
|
||||||
if (autoMuteThreshold && peers.length > autoMuteThreshold)
|
if ('autoMuteThreshold' in window.config)
|
||||||
|
{
|
||||||
|
autoMuteThreshold = window.config.autoMuteThreshold;
|
||||||
|
}
|
||||||
|
if (autoMuteThreshold && peers.length >= autoMuteThreshold)
|
||||||
this.muteMic();
|
this.muteMic();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (joinVideo && this._mediasoupDevice.canProduce('video'))
|
if (joinVideo && this._mediasoupDevice.canProduce('video'))
|
||||||
this.enableWebcam();
|
this.enableWebcam();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this._updateAudioOutputDevices();
|
await this._updateAudioOutputDevices();
|
||||||
|
|
||||||
const { selectedAudioOutputDevice } = store.getState().settings;
|
const { selectedAudioOutputDevice } = store.getState().settings;
|
||||||
|
|
@ -3075,7 +3103,7 @@ export default class RoomClient
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch(roomActions.setRoomState('connected'));
|
store.dispatch(roomActions.setRoomState('connected'));
|
||||||
|
|
||||||
// Clean all the existing notifications.
|
// Clean all the existing notifications.
|
||||||
|
|
@ -3259,7 +3287,7 @@ export default class RoomClient
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no webcam devices');
|
throw new Error('no webcam devices');
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'addExtraVideo() | new selected webcam [device:%o]',
|
'addExtraVideo() | new selected webcam [device:%o]',
|
||||||
device);
|
device);
|
||||||
|
|
@ -3304,7 +3332,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
videoGoogleStartBitrate : 1000
|
videoGoogleStartBitrate : 1000
|
||||||
},
|
},
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'extravideo'
|
source : 'extravideo'
|
||||||
}
|
}
|
||||||
|
|
@ -3314,7 +3342,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
producer = await this._sendTransport.produce({
|
producer = await this._sendTransport.produce({
|
||||||
track,
|
track,
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'extravideo'
|
source : 'extravideo'
|
||||||
}
|
}
|
||||||
|
|
@ -3408,7 +3436,7 @@ export default class RoomClient
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no audio devices');
|
throw new Error('no audio devices');
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'enableMic() | new selected audio device [device:%o]',
|
'enableMic() | new selected audio device [device:%o]',
|
||||||
device);
|
device);
|
||||||
|
|
@ -3445,7 +3473,7 @@ export default class RoomClient
|
||||||
opusPtime : '3',
|
opusPtime : '3',
|
||||||
opusMaxPlaybackRate : 48000
|
opusMaxPlaybackRate : 48000
|
||||||
},
|
},
|
||||||
appData :
|
appData :
|
||||||
{ source: 'mic' }
|
{ source: 'mic' }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -3605,7 +3633,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
videoGoogleStartBitrate : 1000
|
videoGoogleStartBitrate : 1000
|
||||||
},
|
},
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'screen'
|
source : 'screen'
|
||||||
}
|
}
|
||||||
|
|
@ -3615,7 +3643,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
this._screenSharingProducer = await this._sendTransport.produce({
|
this._screenSharingProducer = await this._sendTransport.produce({
|
||||||
track,
|
track,
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'screen'
|
source : 'screen'
|
||||||
}
|
}
|
||||||
|
|
@ -3733,7 +3761,7 @@ export default class RoomClient
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
throw new Error('no webcam devices');
|
throw new Error('no webcam devices');
|
||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'_setWebcamProducer() | new selected webcam [device:%o]',
|
'_setWebcamProducer() | new selected webcam [device:%o]',
|
||||||
device);
|
device);
|
||||||
|
|
@ -3776,7 +3804,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
videoGoogleStartBitrate : 1000
|
videoGoogleStartBitrate : 1000
|
||||||
},
|
},
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'webcam'
|
source : 'webcam'
|
||||||
}
|
}
|
||||||
|
|
@ -3786,7 +3814,7 @@ export default class RoomClient
|
||||||
{
|
{
|
||||||
this._webcamProducer = await this._sendTransport.produce({
|
this._webcamProducer = await this._sendTransport.produce({
|
||||||
track,
|
track,
|
||||||
appData :
|
appData :
|
||||||
{
|
{
|
||||||
source : 'webcam'
|
source : 'webcam'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export default class Spotlights extends EventEmitter
|
||||||
const oldIndex = this._unmutablePeerList.indexOf(peerId);
|
const oldIndex = this._unmutablePeerList.indexOf(peerId);
|
||||||
|
|
||||||
let index = oldIndex;
|
let index = oldIndex;
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
for (let i = 0; i < this._unmutablePeerList.length; i++)
|
for (let i = 0; i < this._unmutablePeerList.length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -94,7 +94,7 @@ export default class Spotlights extends EventEmitter
|
||||||
const oldIndex = this._unmutablePeerList.indexOf(peerId);
|
const oldIndex = this._unmutablePeerList.indexOf(peerId);
|
||||||
|
|
||||||
let index = oldIndex;
|
let index = oldIndex;
|
||||||
|
|
||||||
index--;
|
index--;
|
||||||
for (let i = 0; i < this._unmutablePeerList.length; i++)
|
for (let i = 0; i < this._unmutablePeerList.length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -119,7 +119,7 @@ export default class Spotlights extends EventEmitter
|
||||||
logger.debug('setPeerSpotlight() [peerId:"%s"]', peerId);
|
logger.debug('setPeerSpotlight() [peerId:"%s"]', peerId);
|
||||||
|
|
||||||
const index = this._selectedSpotlights.indexOf(peerId);
|
const index = this._selectedSpotlights.indexOf(peerId);
|
||||||
|
|
||||||
if (index !== -1)
|
if (index !== -1)
|
||||||
{
|
{
|
||||||
this._selectedSpotlights = [];
|
this._selectedSpotlights = [];
|
||||||
|
|
@ -177,7 +177,7 @@ export default class Spotlights extends EventEmitter
|
||||||
{
|
{
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'room "newpeer" event [id: "%s"]', id);
|
'room "newpeer" event [id: "%s"]', id);
|
||||||
|
|
||||||
if (this._peerList.indexOf(id) === -1) // We don't have this peer in the list
|
if (this._peerList.indexOf(id) === -1) // We don't have this peer in the list
|
||||||
{
|
{
|
||||||
logger.debug('_handlePeer() | adding peer [peerId: "%s"]', id);
|
logger.debug('_handlePeer() | adding peer [peerId: "%s"]', id);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export const addResponseMessage = (message) =>
|
||||||
type : 'ADD_NEW_RESPONSE_MESSAGE',
|
type : 'ADD_NEW_RESPONSE_MESSAGE',
|
||||||
payload : { message }
|
payload : { message }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const addChatHistory = (chatHistory) =>
|
export const addChatHistory = (chatHistory) =>
|
||||||
({
|
({
|
||||||
type : 'ADD_CHAT_HISTORY',
|
type : 'ADD_CHAT_HISTORY',
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,13 @@ export const setAudioOutputInProgress = (flag) =>
|
||||||
type : 'SET_AUDIO_OUTPUT_IN_PROGRESS',
|
type : 'SET_AUDIO_OUTPUT_IN_PROGRESS',
|
||||||
payload : { flag }
|
payload : { flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setWebcamInProgress = (flag) =>
|
export const setWebcamInProgress = (flag) =>
|
||||||
({
|
({
|
||||||
type : 'SET_WEBCAM_IN_PROGRESS',
|
type : 'SET_WEBCAM_IN_PROGRESS',
|
||||||
payload : { flag }
|
payload : { flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setScreenShareInProgress = (flag) =>
|
export const setScreenShareInProgress = (flag) =>
|
||||||
({
|
({
|
||||||
type : 'SET_SCREEN_SHARE_IN_PROGRESS',
|
type : 'SET_SCREEN_SHARE_IN_PROGRESS',
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,13 @@ export const setPeerVideoInProgress = (peerId, flag) =>
|
||||||
type : 'SET_PEER_VIDEO_IN_PROGRESS',
|
type : 'SET_PEER_VIDEO_IN_PROGRESS',
|
||||||
payload : { peerId, flag }
|
payload : { peerId, flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setPeerAudioInProgress = (peerId, flag) =>
|
export const setPeerAudioInProgress = (peerId, flag) =>
|
||||||
({
|
({
|
||||||
type : 'SET_PEER_AUDIO_IN_PROGRESS',
|
type : 'SET_PEER_AUDIO_IN_PROGRESS',
|
||||||
payload : { peerId, flag }
|
payload : { peerId, flag }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setPeerScreenInProgress = (peerId, flag) =>
|
export const setPeerScreenInProgress = (peerId, flag) =>
|
||||||
({
|
({
|
||||||
type : 'SET_PEER_SCREEN_IN_PROGRESS',
|
type : 'SET_PEER_SCREEN_IN_PROGRESS',
|
||||||
|
|
|
||||||
|
|
@ -73,14 +73,14 @@ export const setNoiseSuppression = (noiseSuppression) =>
|
||||||
|
|
||||||
export const setVoiceActivatedUnmute = (voiceActivatedUnmute) =>
|
export const setVoiceActivatedUnmute = (voiceActivatedUnmute) =>
|
||||||
({
|
({
|
||||||
type: 'SET_VOICE_ACTIVATED_UNMUTE',
|
type : 'SET_VOICE_ACTIVATED_UNMUTE',
|
||||||
payload: { voiceActivatedUnmute }
|
payload : { voiceActivatedUnmute }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setNoiseThreshold = (noiseThreshold) =>
|
export const setNoiseThreshold = (noiseThreshold) =>
|
||||||
({
|
({
|
||||||
type: 'SET_NOISE_THRESHOLD',
|
type : 'SET_NOISE_THRESHOLD',
|
||||||
payload: { noiseThreshold }
|
payload : { noiseThreshold }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setDefaultAudio = (audio) =>
|
export const setDefaultAudio = (audio) =>
|
||||||
|
|
@ -89,21 +89,6 @@ export const setDefaultAudio = (audio) =>
|
||||||
payload : { audio }
|
payload : { audio }
|
||||||
});
|
});
|
||||||
|
|
||||||
export const toggleEchoCancellation = () =>
|
|
||||||
({
|
|
||||||
type : 'TOGGLE_ECHO_CANCELLATION'
|
|
||||||
});
|
|
||||||
|
|
||||||
export const toggleAutoGainControl = () =>
|
|
||||||
({
|
|
||||||
type : 'TOGGLE_AUTO_GAIN_CONTROL'
|
|
||||||
});
|
|
||||||
|
|
||||||
export const toggleNoiseSuppression = () =>
|
|
||||||
({
|
|
||||||
type : 'TOGGLE_NOISE_SUPPRESSION'
|
|
||||||
});
|
|
||||||
|
|
||||||
export const toggleHiddenControls = () =>
|
export const toggleHiddenControls = () =>
|
||||||
({
|
({
|
||||||
type : 'TOGGLE_HIDDEN_CONTROLS'
|
type : 'TOGGLE_HIDDEN_CONTROLS'
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ const ListLobbyPeer = (props) =>
|
||||||
const picture = peer.picture || EmptyAvatar;
|
const picture = peer.picture || EmptyAvatar;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListItem
|
<ListItem
|
||||||
className={classnames(classes.root)}
|
className={classnames(classes.root)}
|
||||||
key={peer.peerId}
|
key={peer.peerId}
|
||||||
button
|
button
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ const LockDialog = ({
|
||||||
/>
|
/>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
{ lobbyPeers.length > 0 ?
|
{ lobbyPeers.length > 0 ?
|
||||||
<List
|
<List
|
||||||
dense
|
dense
|
||||||
subheader={
|
subheader={
|
||||||
<ListSubheader component='div'>
|
<ListSubheader component='div'>
|
||||||
|
|
|
||||||
|
|
@ -287,9 +287,9 @@ const Me = (props) =>
|
||||||
defaultMessage : 'Start screen sharing'
|
defaultMessage : 'Start screen sharing'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const [
|
const [
|
||||||
screenShareTooltipOpen,
|
screenShareTooltipOpen,
|
||||||
screenShareTooltipSetOpen
|
screenShareTooltipSetOpen
|
||||||
] = React.useState(false);
|
] = React.useState(false);
|
||||||
|
|
||||||
const screenShareTooltipHandleClose = () =>
|
const screenShareTooltipHandleClose = () =>
|
||||||
|
|
@ -380,7 +380,7 @@ const Me = (props) =>
|
||||||
}}
|
}}
|
||||||
style={spacingStyle}
|
style={spacingStyle}
|
||||||
>
|
>
|
||||||
|
|
||||||
{ me.browser.platform !== 'mobile' && smallContainer &&
|
{ me.browser.platform !== 'mobile' && smallContainer &&
|
||||||
<div className={classnames(
|
<div className={classnames(
|
||||||
classes.ptt,
|
classes.ptt,
|
||||||
|
|
@ -457,8 +457,8 @@ const Me = (props) =>
|
||||||
className={classes.smallContainer}
|
className={classes.smallContainer}
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
color={
|
color={
|
||||||
micState === 'on' ?
|
micState === 'on' ?
|
||||||
settings.voiceActivatedUnmute && !me.isAutoMuted ?
|
settings.voiceActivatedUnmute && !me.isAutoMuted ?
|
||||||
'primary'
|
'primary'
|
||||||
: 'default'
|
: 'default'
|
||||||
: 'secondary'}
|
: 'secondary'}
|
||||||
|
|
@ -474,7 +474,7 @@ const Me = (props) =>
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{ micState === 'on' ?
|
{ micState === 'on' ?
|
||||||
<MicIcon
|
<MicIcon
|
||||||
color={me.isAutoMuted ? 'secondary' : 'primary'}
|
color={me.isAutoMuted ? 'secondary' : 'primary'}
|
||||||
style={{ opacity: noiseVolume }}
|
style={{ opacity: noiseVolume }}
|
||||||
/>
|
/>
|
||||||
|
|
@ -492,9 +492,9 @@ const Me = (props) =>
|
||||||
})}
|
})}
|
||||||
className={classes.fab}
|
className={classes.fab}
|
||||||
disabled={!me.canSendMic || me.audioInProgress}
|
disabled={!me.canSendMic || me.audioInProgress}
|
||||||
color={micState === 'on' ?
|
color={micState === 'on' ?
|
||||||
settings.voiceActivatedUnmute && !me.isAutoMuted? 'primary'
|
settings.voiceActivatedUnmute && !me.isAutoMuted? 'primary'
|
||||||
: 'default'
|
: 'default'
|
||||||
: 'secondary'}
|
: 'secondary'}
|
||||||
size='large'
|
size='large'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -509,8 +509,10 @@ const Me = (props) =>
|
||||||
>
|
>
|
||||||
{ micState === 'on' ?
|
{ micState === 'on' ?
|
||||||
<MicIcon
|
<MicIcon
|
||||||
color={me.isAutoMuted ? 'secondary' : 'primary'}
|
color={me.isAutoMuted && settings.voiceActivatedUnmute ?
|
||||||
style={me.isAutoMuted ? { opacity: noiseVolume }
|
'secondary' : 'primary'}
|
||||||
|
style={me.isAutoMuted && settings.voiceActivatedUnmute ?
|
||||||
|
{ opacity: noiseVolume }
|
||||||
: { opacity: 1 }}
|
: { opacity: 1 }}
|
||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
|
|
@ -574,9 +576,9 @@ const Me = (props) =>
|
||||||
}
|
}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{ me.browser.platform !== 'mobile' &&
|
{ me.browser.platform !== 'mobile' &&
|
||||||
<Tooltip open={screenShareTooltipOpen}
|
<Tooltip open={screenShareTooltipOpen}
|
||||||
onClose={screenShareTooltipHandleClose}
|
onClose={screenShareTooltipHandleClose}
|
||||||
onOpen={screenShareTooltipHandleOpen}
|
onOpen={screenShareTooltipHandleOpen}
|
||||||
title={screenTip} placement='left'
|
title={screenTip} placement='left'
|
||||||
>
|
>
|
||||||
{ smallContainer ?
|
{ smallContainer ?
|
||||||
|
|
@ -868,7 +870,7 @@ const Me = (props) =>
|
||||||
defaultMessage='ME'
|
defaultMessage='ME'
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
isMe
|
isMe
|
||||||
isScreen
|
isScreen
|
||||||
|
|
@ -913,15 +915,15 @@ const makeMapStateToProps = () =>
|
||||||
const mapStateToProps = (state) =>
|
const mapStateToProps = (state) =>
|
||||||
{
|
{
|
||||||
let volume;
|
let volume;
|
||||||
|
|
||||||
// noiseVolume under threshold
|
// noiseVolume under threshold
|
||||||
if (state.peerVolumes[state.me.id] < state.settings.noiseThreshold)
|
if (state.peerVolumes[state.me.id] < state.settings.noiseThreshold)
|
||||||
{
|
{
|
||||||
// noiseVolume mapped to range 0.5 ... 1 (threshold switch)
|
// noiseVolume mapped to range 0.5 ... 1 (threshold switch)
|
||||||
volume = 1 + ((Math.abs(state.peerVolumes[state.me.id] -
|
volume = 1 + ((Math.abs(state.peerVolumes[state.me.id] -
|
||||||
state.settings.noiseThreshold) / (-120 -
|
state.settings.noiseThreshold) / (-120 -
|
||||||
state.settings.noiseThreshold)));
|
state.settings.noiseThreshold)));
|
||||||
}
|
}
|
||||||
// noiseVolume over threshold: no noise but voice
|
// noiseVolume over threshold: no noise but voice
|
||||||
else { volume = 0; }
|
else { volume = 0; }
|
||||||
|
|
||||||
|
|
@ -949,7 +951,7 @@ export default withRoomContext(connect(
|
||||||
return (
|
return (
|
||||||
prev.room === next.room &&
|
prev.room === next.room &&
|
||||||
prev.me === next.me &&
|
prev.me === next.me &&
|
||||||
Math.round(prev.peerVolumes[prev.me.id]) ===
|
Math.round(prev.peerVolumes[prev.me.id]) ===
|
||||||
Math.round(next.peerVolumes[next.me.id]) &&
|
Math.round(next.peerVolumes[next.me.id]) &&
|
||||||
prev.peers === next.peers &&
|
prev.peers === next.peers &&
|
||||||
prev.producers === next.producers &&
|
prev.producers === next.producers &&
|
||||||
|
|
|
||||||
|
|
@ -228,14 +228,14 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
setHover(true);
|
setHover(true);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
touchTimeout = setTimeout(() =>
|
touchTimeout = setTimeout(() =>
|
||||||
{
|
{
|
||||||
setHover(false);
|
setHover(false);
|
||||||
|
|
@ -445,14 +445,14 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
setHover(true);
|
setHover(true);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
touchTimeout = setTimeout(() =>
|
touchTimeout = setTimeout(() =>
|
||||||
{
|
{
|
||||||
setHover(false);
|
setHover(false);
|
||||||
|
|
@ -471,7 +471,7 @@ const Peer = (props) =>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={classnames(classes.controls, hover ? 'hover' : null)}
|
className={classnames(classes.controls, hover ? 'hover' : null)}
|
||||||
onMouseOver={() => setHover(true)}
|
onMouseOver={() => setHover(true)}
|
||||||
|
|
@ -480,14 +480,14 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
setHover(true);
|
setHover(true);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
touchTimeout = setTimeout(() =>
|
touchTimeout = setTimeout(() =>
|
||||||
{
|
{
|
||||||
setHover(false);
|
setHover(false);
|
||||||
|
|
@ -544,7 +544,7 @@ const Peer = (props) =>
|
||||||
}
|
}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id : 'label.fullscreen',
|
id : 'label.fullscreen',
|
||||||
|
|
@ -588,7 +588,7 @@ const Peer = (props) =>
|
||||||
}
|
}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<VideoView
|
<VideoView
|
||||||
showQuality
|
showQuality
|
||||||
advancedMode={advancedMode}
|
advancedMode={advancedMode}
|
||||||
|
|
@ -629,14 +629,14 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
setHover(true);
|
setHover(true);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
touchTimeout = setTimeout(() =>
|
touchTimeout = setTimeout(() =>
|
||||||
{
|
{
|
||||||
setHover(false);
|
setHover(false);
|
||||||
|
|
@ -663,7 +663,7 @@ const Peer = (props) =>
|
||||||
{
|
{
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
setHover(true);
|
setHover(true);
|
||||||
}}
|
}}
|
||||||
onTouchEnd={() =>
|
onTouchEnd={() =>
|
||||||
|
|
@ -671,7 +671,7 @@ const Peer = (props) =>
|
||||||
|
|
||||||
if (touchTimeout)
|
if (touchTimeout)
|
||||||
clearTimeout(touchTimeout);
|
clearTimeout(touchTimeout);
|
||||||
|
|
||||||
touchTimeout = setTimeout(() =>
|
touchTimeout = setTimeout(() =>
|
||||||
{
|
{
|
||||||
setHover(false);
|
setHover(false);
|
||||||
|
|
|
||||||
|
|
@ -58,27 +58,27 @@ const styles = () =>
|
||||||
'&.level6' :
|
'&.level6' :
|
||||||
{
|
{
|
||||||
height : '60%',
|
height : '60%',
|
||||||
backgroundColor : 'rgba(255, 0, 0, 0.65)'
|
backgroundColor : 'rgba(255, 165, 0, 0.65)'
|
||||||
},
|
},
|
||||||
'&.level7' :
|
'&.level7' :
|
||||||
{
|
{
|
||||||
height : '70%',
|
height : '70%',
|
||||||
backgroundColor : 'rgba(255, 0, 0, 0.65)'
|
backgroundColor : 'rgba(255, 100, 0, 0.65)'
|
||||||
},
|
},
|
||||||
'&.level8' :
|
'&.level8' :
|
||||||
{
|
{
|
||||||
height : '80%',
|
height : '80%',
|
||||||
backgroundColor : 'rgba(0, 0, 0, 0.65)'
|
backgroundColor : 'rgba(255, 60, 0, 0.65)'
|
||||||
},
|
},
|
||||||
'&.level9' :
|
'&.level9' :
|
||||||
{
|
{
|
||||||
height : '90%',
|
height : '90%',
|
||||||
backgroundColor : 'rgba(0, 0, 0, 0.65)'
|
backgroundColor : 'rgba(255, 30, 0, 0.65)'
|
||||||
},
|
},
|
||||||
'&.level10' :
|
'&.level10' :
|
||||||
{
|
{
|
||||||
height : '100%',
|
height : '100%',
|
||||||
backgroundColor : 'rgba(0, 0, 0, 0.65)'
|
backgroundColor : 'rgba(255, 0, 0, 0.65)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
volumeSmall :
|
volumeSmall :
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,9 @@ const styles = (theme) =>
|
||||||
},
|
},
|
||||||
link :
|
link :
|
||||||
{
|
{
|
||||||
display : 'block',
|
display : 'block',
|
||||||
textAlign : 'center'
|
textAlign : 'center',
|
||||||
|
marginBottom : theme.spacing(1)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -68,15 +69,16 @@ const About = ({
|
||||||
/>
|
/>
|
||||||
</DialogTitle>
|
</DialogTitle>
|
||||||
<DialogContent dividers='true'>
|
<DialogContent dividers='true'>
|
||||||
<DialogContentText>
|
<DialogContentText paragraph>
|
||||||
Contributions to this work were made on behalf of the GÉANT
|
Contributions to this work were made on behalf of the GÉANT
|
||||||
project, a project that has received funding from the
|
project, a project that has received funding from the
|
||||||
European Union’s Horizon 2020 research and innovation
|
European Union’s Horizon 2020 research and innovation
|
||||||
programme under Grant Agreement No. 731122 (GN4-2).
|
programme under Grant Agreement No. 731122 (GN4-2).
|
||||||
On behalf of GÉANT project, GÉANT Association is the sole
|
On behalf of GÉANT project, GÉANT Association is the sole
|
||||||
owner of the copyright in all material which was developed
|
owner of the copyright in all material which was developed
|
||||||
by a member of the GÉANT project.<br />
|
by a member of the GÉANT project.
|
||||||
<br />
|
</DialogContentText>
|
||||||
|
<DialogContentText paragraph>
|
||||||
GÉANT Vereniging (Association) is registered with the
|
GÉANT Vereniging (Association) is registered with the
|
||||||
Chamber of Commerce in Amsterdam with registration number
|
Chamber of Commerce in Amsterdam with registration number
|
||||||
40535155 and operates in the UK as a branch of GÉANT
|
40535155 and operates in the UK as a branch of GÉANT
|
||||||
|
|
@ -87,6 +89,13 @@ const About = ({
|
||||||
<Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}>
|
<Link href='https://edumeet.org' target='_blank' rel='noreferrer' color='secondary' variant='h6' className={classes.link}>
|
||||||
https://edumeet.org
|
https://edumeet.org
|
||||||
</Link>
|
</Link>
|
||||||
|
<DialogContentText align='center' variant='h7'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='label.version'
|
||||||
|
defaultMessage='Version'
|
||||||
|
/>
|
||||||
|
:{` ${process.env.REACT_APP_VERSION}`}
|
||||||
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
|
{ window.config.logo && <img alt='Logo' className={classes.logo} src={window.config.logo} /> }
|
||||||
|
|
@ -97,7 +106,7 @@ const About = ({
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,7 +114,7 @@ About.propTypes =
|
||||||
{
|
{
|
||||||
roomClient : PropTypes.object.isRequired,
|
roomClient : PropTypes.object.isRequired,
|
||||||
aboutOpen : PropTypes.bool.isRequired,
|
aboutOpen : PropTypes.bool.isRequired,
|
||||||
handleCloseAbout : PropTypes.func.isRequired,
|
handleCloseAbout : PropTypes.func.isRequired,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,13 +107,13 @@ const Help = ({
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<DialogContent dividers='true'>
|
<DialogContent dividers='true'>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{shortcuts.map((value, index) =>
|
{shortcuts.map((value, index) =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div key={index} className={classes.shortcuts}>
|
<div key={index} className={classes.shortcuts}>
|
||||||
<Paper className={classes.paper}>
|
<Paper className={classes.paper}>
|
||||||
{value.key}
|
{value.key}
|
||||||
</Paper>
|
</Paper>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
|
|
@ -134,7 +134,7 @@ const Help = ({
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ Help.propTypes =
|
||||||
{
|
{
|
||||||
roomClient : PropTypes.object.isRequired,
|
roomClient : PropTypes.object.isRequired,
|
||||||
helpOpen : PropTypes.bool.isRequired,
|
helpOpen : PropTypes.bool.isRequired,
|
||||||
handleCloseHelp : PropTypes.func.isRequired,
|
handleCloseHelp : PropTypes.func.isRequired,
|
||||||
classes : PropTypes.object.isRequired
|
classes : PropTypes.object.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ const TopBar = (props) =>
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes.grow} />
|
<div className={classes.grow} />
|
||||||
<div className={classes.sectionDesktop}>
|
<div className={classes.sectionDesktop}>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id : 'label.moreActions',
|
id : 'label.moreActions',
|
||||||
defaultMessage : 'More actions'
|
defaultMessage : 'More actions'
|
||||||
|
|
@ -350,7 +350,7 @@ const TopBar = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id : 'tooltip.participants',
|
id : 'tooltip.participants',
|
||||||
defaultMessage : 'Show participants'
|
defaultMessage : 'Show participants'
|
||||||
|
|
@ -421,7 +421,7 @@ const TopBar = (props) =>
|
||||||
</span>
|
</span>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{ lobbyPeers.length > 0 &&
|
{ lobbyPeers.length > 0 &&
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id : 'tooltip.lobby',
|
id : 'tooltip.lobby',
|
||||||
defaultMessage : 'Show lobby'
|
defaultMessage : 'Show lobby'
|
||||||
|
|
@ -457,7 +457,7 @@ const TopBar = (props) =>
|
||||||
})}
|
})}
|
||||||
className={classes.actionButton}
|
className={classes.actionButton}
|
||||||
color='inherit'
|
color='inherit'
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
loggedIn ? roomClient.logout() : roomClient.login();
|
loggedIn ? roomClient.logout() : roomClient.login();
|
||||||
}}
|
}}
|
||||||
|
|
@ -472,6 +472,34 @@ const TopBar = (props) =>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={classes.sectionMobile}>
|
<div className={classes.sectionMobile}>
|
||||||
|
{ lobbyPeers.length > 0 &&
|
||||||
|
<Tooltip
|
||||||
|
title={intl.formatMessage({
|
||||||
|
id : 'tooltip.lobby',
|
||||||
|
defaultMessage : 'Show lobby'
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<span className={classes.disabledButton}>
|
||||||
|
<IconButton
|
||||||
|
aria-label={intl.formatMessage({
|
||||||
|
id : 'tooltip.lobby',
|
||||||
|
defaultMessage : 'Show lobby'
|
||||||
|
})}
|
||||||
|
className={classes.actionButton}
|
||||||
|
color='inherit'
|
||||||
|
disabled={!canPromote}
|
||||||
|
onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
|
||||||
|
>
|
||||||
|
<PulsingBadge
|
||||||
|
color='secondary'
|
||||||
|
badgeContent={lobbyPeers.length}
|
||||||
|
>
|
||||||
|
<SecurityIcon />
|
||||||
|
</PulsingBadge>
|
||||||
|
</IconButton>
|
||||||
|
</span>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-haspopup='true'
|
aria-haspopup='true'
|
||||||
onClick={handleMobileMenuOpen}
|
onClick={handleMobileMenuOpen}
|
||||||
|
|
@ -480,34 +508,6 @@ const TopBar = (props) =>
|
||||||
<MoreIcon />
|
<MoreIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</div>
|
</div>
|
||||||
{ lobbyPeers.length > 0 &&
|
|
||||||
<Tooltip
|
|
||||||
title={intl.formatMessage({
|
|
||||||
id : 'tooltip.lobby',
|
|
||||||
defaultMessage : 'Show lobby'
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<span className={classes.disabledButton}>
|
|
||||||
<IconButton
|
|
||||||
aria-label={intl.formatMessage({
|
|
||||||
id : 'tooltip.lobby',
|
|
||||||
defaultMessage : 'Show lobby'
|
|
||||||
})}
|
|
||||||
className={classes.actionButton}
|
|
||||||
color='inherit'
|
|
||||||
disabled={!canPromote}
|
|
||||||
onClick={() => setLockDialogOpen(!room.lockDialogOpen)}
|
|
||||||
>
|
|
||||||
<PulsingBadge
|
|
||||||
color='secondary'
|
|
||||||
badgeContent={lobbyPeers.length}
|
|
||||||
>
|
|
||||||
<SecurityIcon />
|
|
||||||
</PulsingBadge>
|
|
||||||
</IconButton>
|
|
||||||
</span>
|
|
||||||
</Tooltip>
|
|
||||||
}
|
|
||||||
<div className={classes.divider} />
|
<div className={classes.divider} />
|
||||||
<Button
|
<Button
|
||||||
aria-label={intl.formatMessage({
|
aria-label={intl.formatMessage({
|
||||||
|
|
@ -558,8 +558,8 @@ const TopBar = (props) =>
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
handleMenuClose();
|
handleMenuClose();
|
||||||
setHelpOpen(!room.helpOpen);
|
setHelpOpen(!room.helpOpen);
|
||||||
|
|
@ -578,8 +578,8 @@ const TopBar = (props) =>
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
handleMenuClose();
|
handleMenuClose();
|
||||||
setAboutOpen(!room.aboutOpen);
|
setAboutOpen(!room.aboutOpen);
|
||||||
|
|
@ -612,7 +612,7 @@ const TopBar = (props) =>
|
||||||
{ loginEnabled &&
|
{ loginEnabled &&
|
||||||
<MenuItem
|
<MenuItem
|
||||||
aria-label={loginTooltip}
|
aria-label={loginTooltip}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
{
|
{
|
||||||
handleMenuClose();
|
handleMenuClose();
|
||||||
loggedIn ? roomClient.logout() : roomClient.login();
|
loggedIn ? roomClient.logout() : roomClient.login();
|
||||||
|
|
@ -697,33 +697,6 @@ const TopBar = (props) =>
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{ lobbyPeers.length > 0 &&
|
|
||||||
<MenuItem
|
|
||||||
aria-label={intl.formatMessage({
|
|
||||||
id : 'tooltip.lobby',
|
|
||||||
defaultMessage : 'Show lobby'
|
|
||||||
})}
|
|
||||||
disabled={!canPromote}
|
|
||||||
onClick={() =>
|
|
||||||
{
|
|
||||||
handleMenuClose();
|
|
||||||
setLockDialogOpen(!room.lockDialogOpen);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PulsingBadge
|
|
||||||
color='secondary'
|
|
||||||
badgeContent={lobbyPeers.length}
|
|
||||||
>
|
|
||||||
<SecurityIcon />
|
|
||||||
</PulsingBadge>
|
|
||||||
<p className={classes.moreAction}>
|
|
||||||
<FormattedMessage
|
|
||||||
id='tooltip.lobby'
|
|
||||||
defaultMessage='Show lobby'
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
</MenuItem>
|
|
||||||
}
|
|
||||||
<MenuItem
|
<MenuItem
|
||||||
aria-label={intl.formatMessage({
|
aria-label={intl.formatMessage({
|
||||||
id : 'tooltip.participants',
|
id : 'tooltip.participants',
|
||||||
|
|
|
||||||
|
|
@ -327,7 +327,7 @@ const JoinDialog = ({
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
:
|
:
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<DialogContentText
|
<DialogContentText
|
||||||
className={classes.green}
|
className={classes.green}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
import marked from 'marked';
|
import marked from 'marked';
|
||||||
import Paper from '@material-ui/core/Paper';
|
import Paper from '@material-ui/core/Paper';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
|
@ -14,7 +14,7 @@ linkRenderer.link = (href, title, text) =>
|
||||||
{
|
{
|
||||||
title = title ? title : href;
|
title = title ? title : href;
|
||||||
text = text ? text : href;
|
text = text ? text : href;
|
||||||
|
|
||||||
return `<a target='_blank' href='${ href }' title='${ title }'>${ text }</a>`;
|
return `<a target='_blank' href='${ href }' title='${ title }'>${ text }</a>`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ class MessageList extends React.Component
|
||||||
myPicture,
|
myPicture,
|
||||||
classes
|
classes
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes.root} ref={(node) => { this.node = node; }}>
|
<div className={classes.root} ref={(node) => { this.node = node; }}>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -279,7 +279,7 @@ const ListPeer = (props) =>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
}
|
}
|
||||||
{ isModerator && webcamConsumer &&
|
{ isModerator && webcamConsumer &&
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={intl.formatMessage({
|
title={intl.formatMessage({
|
||||||
id : 'tooltip.muteParticipantVideoModerator',
|
id : 'tooltip.muteParticipantVideoModerator',
|
||||||
|
|
|
||||||
|
|
@ -143,13 +143,13 @@ class Filmstrip extends React.PureComponent
|
||||||
let speakerWidth = (availableWidth - PADDING_H);
|
let speakerWidth = (availableWidth - PADDING_H);
|
||||||
|
|
||||||
let speakerHeight = speakerWidth / RATIO;
|
let speakerHeight = speakerWidth / RATIO;
|
||||||
|
|
||||||
if (this.isSharingCamera(this.getActivePeerId()))
|
if (this.isSharingCamera(this.getActivePeerId()))
|
||||||
{
|
{
|
||||||
speakerWidth /= 2;
|
speakerWidth /= 2;
|
||||||
speakerHeight = speakerWidth / RATIO;
|
speakerHeight = speakerWidth / RATIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (speakerHeight > (availableSpeakerHeight - PADDING_V))
|
if (speakerHeight > (availableSpeakerHeight - PADDING_V))
|
||||||
{
|
{
|
||||||
speakerHeight = (availableSpeakerHeight - PADDING_V);
|
speakerHeight = (availableSpeakerHeight - PADDING_V);
|
||||||
|
|
@ -167,7 +167,7 @@ class Filmstrip extends React.PureComponent
|
||||||
let filmStripHeight = availableFilmstripHeight - FILMSTRING_PADDING_V;
|
let filmStripHeight = availableFilmstripHeight - FILMSTRING_PADDING_V;
|
||||||
|
|
||||||
let filmStripWidth = filmStripHeight * RATIO;
|
let filmStripWidth = filmStripHeight * RATIO;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(filmStripWidth * this.props.boxes) >
|
(filmStripWidth * this.props.boxes) >
|
||||||
(availableWidth - FILMSTRING_PADDING_H)
|
(availableWidth - FILMSTRING_PADDING_H)
|
||||||
|
|
@ -254,7 +254,7 @@ class Filmstrip extends React.PureComponent
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classnames(
|
className={classnames(
|
||||||
classes.root,
|
classes.root,
|
||||||
toolbarsVisible || permanentTopBar ?
|
toolbarsVisible || permanentTopBar ?
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export default class PeerAudio extends React.PureComponent
|
||||||
if (prevProps !== this.props)
|
if (prevProps !== this.props)
|
||||||
{
|
{
|
||||||
const { audioTrack, audioOutputDevice } = this.props;
|
const { audioTrack, audioOutputDevice } = this.props;
|
||||||
|
|
||||||
this._setTrack(audioTrack);
|
this._setTrack(audioTrack);
|
||||||
this._setOutputDevice(audioOutputDevice);
|
this._setOutputDevice(audioOutputDevice);
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ export default class PeerAudio extends React.PureComponent
|
||||||
{
|
{
|
||||||
if (this._audioOutputDevice === audioOutputDevice)
|
if (this._audioOutputDevice === audioOutputDevice)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._audioOutputDevice = audioOutputDevice;
|
this._audioOutputDevice = audioOutputDevice;
|
||||||
|
|
||||||
const { audio } = this.refs;
|
const { audio } = this.refs;
|
||||||
|
|
|
||||||
|
|
@ -248,7 +248,7 @@ export const makePermissionSelector = (permission) =>
|
||||||
const permitted = roles.some((role) =>
|
const permitted = roles.some((role) =>
|
||||||
roomPermissions[permission].includes(role)
|
roomPermissions[permission].includes(role)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (permitted)
|
if (permitted)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -265,7 +265,7 @@ export const makePermissionSelector = (permission) =>
|
||||||
).length === 0
|
).length === 0
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,14 @@ import { withStyles } from '@material-ui/core/styles';
|
||||||
import { withRoomContext } from '../../RoomContext';
|
import { withRoomContext } from '../../RoomContext';
|
||||||
import * as settingsActions from '../../actions/settingsActions';
|
import * as settingsActions from '../../actions/settingsActions';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import classnames from 'classnames';
|
||||||
import { useIntl, FormattedMessage } from 'react-intl';
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||||
import FormControl from '@material-ui/core/FormControl';
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
import Select from '@material-ui/core/Select';
|
import Select from '@material-ui/core/Select';
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
import Switch from '@material-ui/core/Switch';
|
||||||
|
|
||||||
const styles = (theme) =>
|
const styles = (theme) =>
|
||||||
({
|
({
|
||||||
|
|
@ -21,6 +22,13 @@ const styles = (theme) =>
|
||||||
formControl :
|
formControl :
|
||||||
{
|
{
|
||||||
display : 'flex'
|
display : 'flex'
|
||||||
|
},
|
||||||
|
switchLabel : {
|
||||||
|
justifyContent : 'space-between',
|
||||||
|
flex : 'auto',
|
||||||
|
display : 'flex',
|
||||||
|
padding : theme.spacing(1),
|
||||||
|
marginRight : 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -37,16 +45,18 @@ const AdvancedSettings = ({
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.advancedMode} onChange={onToggleAdvancedMode} value='advancedMode' />}
|
control={<Switch checked={settings.advancedMode} onChange={onToggleAdvancedMode} value='advancedMode' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.advancedMode',
|
id : 'settings.advancedMode',
|
||||||
defaultMessage : 'Advanced mode'
|
defaultMessage : 'Advanced mode'
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.notificationSounds} onChange={onToggleNotificationSounds} value='notificationSounds' />}
|
control={<Switch checked={settings.notificationSounds} onChange={onToggleNotificationSounds} value='notificationSounds' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.notificationSounds',
|
id : 'settings.notificationSounds',
|
||||||
defaultMessage : 'Notification sounds'
|
defaultMessage : 'Notification sounds'
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import * as appPropTypes from '../appPropTypes';
|
||||||
import { withStyles } from '@material-ui/core/styles';
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
import * as roomActions from '../../actions/roomActions';
|
import * as roomActions from '../../actions/roomActions';
|
||||||
import * as settingsActions from '../../actions/settingsActions';
|
import * as settingsActions from '../../actions/settingsActions';
|
||||||
|
import classnames from 'classnames';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useIntl, FormattedMessage } from 'react-intl';
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
import MenuItem from '@material-ui/core/MenuItem';
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
|
@ -11,7 +12,7 @@ import FormHelperText from '@material-ui/core/FormHelperText';
|
||||||
import FormControl from '@material-ui/core/FormControl';
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
import Select from '@material-ui/core/Select';
|
import Select from '@material-ui/core/Select';
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
import Switch from '@material-ui/core/Switch';
|
||||||
|
|
||||||
const styles = (theme) =>
|
const styles = (theme) =>
|
||||||
({
|
({
|
||||||
|
|
@ -22,6 +23,13 @@ const styles = (theme) =>
|
||||||
formControl :
|
formControl :
|
||||||
{
|
{
|
||||||
display : 'flex'
|
display : 'flex'
|
||||||
|
},
|
||||||
|
switchLabel : {
|
||||||
|
justifyContent : 'space-between',
|
||||||
|
flex : 'auto',
|
||||||
|
display : 'flex',
|
||||||
|
padding : theme.spacing(1),
|
||||||
|
marginRight : 0
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -90,24 +98,28 @@ const AppearenceSettings = ({
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.permanentTopBar} onChange={onTogglePermanentTopBar} value='permanentTopBar' />}
|
control={
|
||||||
|
<Switch checked={settings.permanentTopBar} onChange={onTogglePermanentTopBar} value='permanentTopBar' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.permanentTopBar',
|
id : 'settings.permanentTopBar',
|
||||||
defaultMessage : 'Permanent top bar'
|
defaultMessage : 'Permanent top bar'
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.hiddenControls} onChange={onToggleHiddenControls} value='hiddenControls' />}
|
control={<Switch checked={settings.hiddenControls} onChange={onToggleHiddenControls} value='hiddenControls' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.hiddenControls',
|
id : 'settings.hiddenControls',
|
||||||
defaultMessage : 'Hidden media controls'
|
defaultMessage : 'Hidden media controls'
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.buttonControlBar} onChange={onToggleButtonControlBar} value='buttonControlBar' />}
|
control={<Switch checked={settings.buttonControlBar} onChange={onToggleButtonControlBar} value='buttonControlBar' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.buttonControlBar',
|
id : 'settings.buttonControlBar',
|
||||||
defaultMessage : 'Separate media controls'
|
defaultMessage : 'Separate media controls'
|
||||||
|
|
@ -115,8 +127,9 @@ const AppearenceSettings = ({
|
||||||
/>
|
/>
|
||||||
{ !isMobile &&
|
{ !isMobile &&
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.drawerOverlayed} onChange={onToggleDrawerOverlayed} value='drawerOverlayed' />}
|
control={<Switch checked={settings.drawerOverlayed} onChange={onToggleDrawerOverlayed} value='drawerOverlayed' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.drawerOverlayed',
|
id : 'settings.drawerOverlayed',
|
||||||
defaultMessage : 'Side drawer over content'
|
defaultMessage : 'Side drawer over content'
|
||||||
|
|
@ -124,8 +137,9 @@ const AppearenceSettings = ({
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
className={classes.setting}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
control={<Checkbox checked={settings.showNotifications} onChange={onToggleShowNotifications} value='showNotifications' />}
|
control={<Switch checked={settings.showNotifications} onChange={onToggleShowNotifications} value='showNotifications' />}
|
||||||
|
labelPlacement='start'
|
||||||
label={intl.formatMessage({
|
label={intl.formatMessage({
|
||||||
id : 'settings.showNotifications',
|
id : 'settings.showNotifications',
|
||||||
defaultMessage : 'Show notifications'
|
defaultMessage : 'Show notifications'
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,19 @@ import FormHelperText from '@material-ui/core/FormHelperText';
|
||||||
import FormControl from '@material-ui/core/FormControl';
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||||
import Select from '@material-ui/core/Select';
|
import Select from '@material-ui/core/Select';
|
||||||
import Checkbox from '@material-ui/core/Checkbox';
|
|
||||||
import Slider from '@material-ui/core/Slider';
|
import Slider from '@material-ui/core/Slider';
|
||||||
import Typography from '@material-ui/core/Typography';
|
import Typography from '@material-ui/core/Typography';
|
||||||
|
import Collapse from '@material-ui/core/Collapse';
|
||||||
|
import List from '@material-ui/core/List';
|
||||||
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
|
import ExpandLess from '@material-ui/icons/ExpandLess';
|
||||||
|
import ExpandMore from '@material-ui/icons/ExpandMore';
|
||||||
|
import Switch from '@material-ui/core/Switch';
|
||||||
|
|
||||||
const NoiseSlider = withStyles(
|
const NoiseSlider = withStyles(
|
||||||
{
|
{
|
||||||
root :
|
root :
|
||||||
{
|
{
|
||||||
color : '#3880ff',
|
color : '#3880ff',
|
||||||
height : 2,
|
height : 2,
|
||||||
|
|
@ -48,10 +54,27 @@ const styles = (theme) => ({
|
||||||
{
|
{
|
||||||
padding : theme.spacing(2)
|
padding : theme.spacing(2)
|
||||||
},
|
},
|
||||||
margin :
|
margin :
|
||||||
{
|
{
|
||||||
height : theme.spacing(3)
|
height : theme.spacing(3)
|
||||||
},
|
},
|
||||||
|
root : {
|
||||||
|
width : '100%',
|
||||||
|
backgroundColor : theme.palette.background.paper
|
||||||
|
},
|
||||||
|
switchLabel : {
|
||||||
|
justifyContent : 'space-between',
|
||||||
|
flex : 'auto',
|
||||||
|
display : 'flex',
|
||||||
|
padding : theme.spacing(1)
|
||||||
|
},
|
||||||
|
nested : {
|
||||||
|
display : 'block',
|
||||||
|
paddingTop : 0,
|
||||||
|
paddingBottom : 0,
|
||||||
|
paddingLeft : '25px',
|
||||||
|
paddingRight : '25px'
|
||||||
|
},
|
||||||
formControl :
|
formControl :
|
||||||
{
|
{
|
||||||
display : 'flex'
|
display : 'flex'
|
||||||
|
|
@ -71,7 +94,7 @@ const MediaSettings = ({
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const resolutions = [ {
|
const resolutions = [ {
|
||||||
value : 'low',
|
value : 'low',
|
||||||
label : intl.formatMessage({
|
label : intl.formatMessage({
|
||||||
|
|
@ -121,7 +144,7 @@ const MediaSettings = ({
|
||||||
audioDevices = Object.values(me.audioDevices);
|
audioDevices = Object.values(me.audioDevices);
|
||||||
else
|
else
|
||||||
audioDevices = [];
|
audioDevices = [];
|
||||||
|
|
||||||
let audioOutputDevices;
|
let audioOutputDevices;
|
||||||
|
|
||||||
if (me.audioOutputDevices)
|
if (me.audioOutputDevices)
|
||||||
|
|
@ -129,6 +152,13 @@ const MediaSettings = ({
|
||||||
else
|
else
|
||||||
audioOutputDevices = [];
|
audioOutputDevices = [];
|
||||||
|
|
||||||
|
const [ open, setOpen ] = React.useState(true);
|
||||||
|
|
||||||
|
const advancedAudioSettings = () =>
|
||||||
|
{
|
||||||
|
setOpen(!open);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<form className={classes.setting} autoComplete='off'>
|
||||||
|
|
@ -173,7 +203,7 @@ const MediaSettings = ({
|
||||||
<FormControl className={classes.formControl}>
|
<FormControl className={classes.formControl}>
|
||||||
<Select
|
<Select
|
||||||
value={settings.resolution || ''}
|
value={settings.resolution || ''}
|
||||||
onChange={(event) =>
|
onChange={(event) =>
|
||||||
{
|
{
|
||||||
if (event.target.value)
|
if (event.target.value)
|
||||||
roomClient.changeVideoResolution(event.target.value);
|
roomClient.changeVideoResolution(event.target.value);
|
||||||
|
|
@ -182,7 +212,7 @@ const MediaSettings = ({
|
||||||
autoWidth
|
autoWidth
|
||||||
className={classes.selectEmpty}
|
className={classes.selectEmpty}
|
||||||
>
|
>
|
||||||
{resolutions.map((resolution, index) =>
|
{resolutions.map((resolution, index) =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<MenuItem key={index} value={resolution.value}>
|
<MenuItem key={index} value={resolution.value}>
|
||||||
|
|
@ -287,90 +317,120 @@ const MediaSettings = ({
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</form>
|
</form>
|
||||||
}
|
}
|
||||||
<form className={classes.setting} autoComplete='off'>
|
<List className={classes.root} component='nav'>
|
||||||
<FormControlLabel
|
<ListItem button onClick={advancedAudioSettings}>
|
||||||
className={classes.setting}
|
<ListItemText primary={intl.formatMessage({
|
||||||
control={
|
id : 'settings.showAdvancedAudio',
|
||||||
<Checkbox checked={settings.echoCancellation} onChange={
|
defaultMessage : 'Show advanced audio settings'
|
||||||
(event) =>
|
|
||||||
{
|
|
||||||
setEchoCancellation(event.target.checked);
|
|
||||||
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
|
||||||
}}
|
|
||||||
/>}
|
|
||||||
label={intl.formatMessage({
|
|
||||||
id : 'settings.echoCancellation',
|
|
||||||
defaultMessage : 'Echo cancellation'
|
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
{open ? <ExpandLess /> : <ExpandMore />}
|
||||||
className={classes.setting}
|
</ListItem>
|
||||||
control={
|
<Collapse in={!open} timeout='auto'>
|
||||||
<Checkbox checked={settings.autoGainControl} onChange={
|
<List component='div'>
|
||||||
(event) =>
|
<ListItem className={classes.nested}>
|
||||||
{
|
<FormControlLabel
|
||||||
setAutoGainControl(event.target.checked);
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
control={
|
||||||
}}
|
<Switch color='secondary'
|
||||||
/>}
|
checked={settings.echoCancellation}
|
||||||
label={intl.formatMessage({
|
onChange={
|
||||||
id : 'settings.autoGainControl',
|
(event) =>
|
||||||
defaultMessage : 'Auto gain control'
|
{
|
||||||
})}
|
setEchoCancellation(event.target.checked);
|
||||||
/>
|
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
||||||
<FormControlLabel
|
}}
|
||||||
className={classes.setting}
|
/>}
|
||||||
control={
|
labelPlacement='start'
|
||||||
<Checkbox checked={settings.noiseSuppression} onChange={
|
label={intl.formatMessage({
|
||||||
(event) =>
|
id : 'settings.echoCancellation',
|
||||||
{
|
defaultMessage : 'Echo cancellation'
|
||||||
setNoiseSuppression(event.target.checked);
|
})}
|
||||||
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
/>
|
||||||
}}
|
</ListItem>
|
||||||
/>}
|
<ListItem className={classes.nested}>
|
||||||
label={intl.formatMessage({
|
<FormControlLabel
|
||||||
id : 'settings.noiseSuppression',
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
defaultMessage : 'Noise suppression'
|
control={
|
||||||
})}
|
<Switch color='secondary'
|
||||||
/>
|
checked={settings.autoGainControl} onChange={
|
||||||
<FormControlLabel
|
(event) =>
|
||||||
className={classes.setting}
|
{
|
||||||
control={
|
setAutoGainControl(event.target.checked);
|
||||||
<Checkbox checked={settings.voiceActivatedUnmute} onChange={
|
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
||||||
(event) =>
|
}}
|
||||||
{
|
/>}
|
||||||
setVoiceActivatedUnmute(event.target.checked);
|
labelPlacement='start'
|
||||||
}}
|
label={intl.formatMessage({
|
||||||
/>}
|
id : 'settings.autoGainControl',
|
||||||
label={intl.formatMessage({
|
defaultMessage : 'Auto gain control'
|
||||||
id : 'settings.voiceActivatedUnmute',
|
})}
|
||||||
defaultMessage : 'Voice activated unmute'
|
/>
|
||||||
})}
|
</ListItem>
|
||||||
/>
|
<ListItem className={classes.nested}>
|
||||||
<div className={classes.margin} />
|
<FormControlLabel
|
||||||
<Typography gutterBottom>
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
{
|
control={
|
||||||
intl.formatMessage({
|
<Switch color='secondary'
|
||||||
id : 'settings.noiseThreshold',
|
checked={settings.noiseSuppression} onChange={
|
||||||
defaultMessage : 'Noise threshold:'
|
(event) =>
|
||||||
})
|
{
|
||||||
}
|
setNoiseSuppression(event.target.checked);
|
||||||
</Typography>
|
roomClient.changeAudioDevice(settings.selectedAudioDevice);
|
||||||
<NoiseSlider className={classnames(classes.slider, classnames.setting)}
|
}}
|
||||||
key={'noise-threshold-slider'}
|
/>}
|
||||||
min={-100}
|
labelPlacement='start'
|
||||||
value={settings.noiseThreshold}
|
label={intl.formatMessage({
|
||||||
max={0}
|
id : 'settings.noiseSuppression',
|
||||||
valueLabelDisplay={'off'}
|
defaultMessage : 'Noise suppression'
|
||||||
onChange={
|
})}
|
||||||
(event, value) =>
|
/>
|
||||||
{
|
</ListItem>
|
||||||
roomClient._setNoiseThreshold(value);
|
<ListItem className={classes.nested}>
|
||||||
}}
|
<FormControlLabel
|
||||||
marks={[ { value: volume, label: 'level' } ]}
|
className={classnames(classes.setting, classes.switchLabel)}
|
||||||
/>
|
control={
|
||||||
<div className={classes.margin} />
|
<Switch color='secondary'
|
||||||
</form>
|
checked={settings.voiceActivatedUnmute} onChange={
|
||||||
|
(event) =>
|
||||||
|
{
|
||||||
|
setVoiceActivatedUnmute(event.target.checked);
|
||||||
|
}}
|
||||||
|
/>}
|
||||||
|
labelPlacement='start'
|
||||||
|
label={intl.formatMessage({
|
||||||
|
id : 'settings.voiceActivatedUnmute',
|
||||||
|
defaultMessage : 'Voice activated unmute'
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
<ListItem className={classes.nested}>
|
||||||
|
<div className={classes.margin} />
|
||||||
|
<Typography gutterBottom>
|
||||||
|
{
|
||||||
|
intl.formatMessage({
|
||||||
|
id : 'settings.noiseThreshold',
|
||||||
|
defaultMessage : 'Noise threshold'
|
||||||
|
})
|
||||||
|
}:
|
||||||
|
</Typography>
|
||||||
|
<NoiseSlider className={classnames(classes.slider, classnames.setting)}
|
||||||
|
key={'noise-threshold-slider'}
|
||||||
|
min={-100}
|
||||||
|
value={settings.noiseThreshold}
|
||||||
|
max={0}
|
||||||
|
valueLabelDisplay={'auto'}
|
||||||
|
onChange={
|
||||||
|
(event, value) =>
|
||||||
|
{
|
||||||
|
roomClient._setNoiseThreshold(value);
|
||||||
|
}}
|
||||||
|
marks={[ { value: volume, label: `${volume} dB` } ]}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
</List>
|
||||||
|
</Collapse>
|
||||||
|
</List>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -399,8 +459,8 @@ const mapStateToProps = (state) =>
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
setEchoCancellation : settingsActions.setEchoCancellation,
|
setEchoCancellation : settingsActions.setEchoCancellation,
|
||||||
setAutoGainControl : settingsActions.toggleAutoGainControl,
|
setAutoGainControl : settingsActions.setAutoGainControl,
|
||||||
setNoiseSuppression : settingsActions.toggleNoiseSuppression,
|
setNoiseSuppression : settingsActions.setNoiseSuppression,
|
||||||
setVoiceActivatedUnmute : settingsActions.setVoiceActivatedUnmute
|
setVoiceActivatedUnmute : settingsActions.setVoiceActivatedUnmute
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,154 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { withStyles } from '@material-ui/core/styles';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import Dialog from '@material-ui/core/Dialog';
|
||||||
|
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||||
|
import DialogContent from '@material-ui/core/DialogContent';
|
||||||
|
import Grid from '@material-ui/core/Grid';
|
||||||
|
import List from '@material-ui/core/List';
|
||||||
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
|
import ListItemText from '@material-ui/core/ListItemText';
|
||||||
|
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||||
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
|
import WebAssetIcon from '@material-ui/icons/WebAsset';
|
||||||
|
import ErrorIcon from '@material-ui/icons/Error';
|
||||||
|
import Hidden from '@material-ui/core/Hidden';
|
||||||
|
|
||||||
|
const styles = (theme) =>
|
||||||
|
({
|
||||||
|
dialogPaper :
|
||||||
|
{
|
||||||
|
width : '40vw',
|
||||||
|
[theme.breakpoints.down('lg')] :
|
||||||
|
{
|
||||||
|
width : '40vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('md')] :
|
||||||
|
{
|
||||||
|
width : '50vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('sm')] :
|
||||||
|
{
|
||||||
|
width : '70vw'
|
||||||
|
},
|
||||||
|
[theme.breakpoints.down('xs')] :
|
||||||
|
{
|
||||||
|
width : '90vw'
|
||||||
|
}
|
||||||
|
// display : 'flex',
|
||||||
|
// flexDirection : 'column'
|
||||||
|
},
|
||||||
|
list : {
|
||||||
|
backgroundColor : theme.palette.background.paper
|
||||||
|
},
|
||||||
|
errorAvatar : {
|
||||||
|
width : theme.spacing(20),
|
||||||
|
height : theme.spacing(20)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const open=true;
|
||||||
|
const dividers=true;
|
||||||
|
|
||||||
|
let dense=false;
|
||||||
|
|
||||||
|
const supportedBrowsers=[
|
||||||
|
{ name: 'Chrome/Chromium', version: '74', vendor: 'Google' },
|
||||||
|
{ name: 'Edge', version: '18', vendor: 'Microsoft' },
|
||||||
|
{ name: 'Firefox', version: '60', vendor: 'Mozilla' },
|
||||||
|
{ name: 'Safari', version: '12', vendor: 'Apple' },
|
||||||
|
{ name: 'Opera', version: '62', vendor: '' },
|
||||||
|
// { name: 'Brave', version: '1.5', vendor: '' },
|
||||||
|
// { name: 'Vivaldi', version: '3', vendor: '' },
|
||||||
|
{ name: 'Samsung Internet', version: '11.1.1.52', vendor: '' }
|
||||||
|
];
|
||||||
|
|
||||||
|
const UnsupportedBrowser = ({
|
||||||
|
platform,
|
||||||
|
webrtcUnavailable,
|
||||||
|
classes
|
||||||
|
}) =>
|
||||||
|
{
|
||||||
|
if (platform !== 'desktop')
|
||||||
|
{
|
||||||
|
dense=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
open={open}
|
||||||
|
scroll={'body'}
|
||||||
|
classes={{
|
||||||
|
paper : classes.dialogPaper
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogTitle id='form-dialog-title'>
|
||||||
|
{!webrtcUnavailable &&
|
||||||
|
<FormattedMessage
|
||||||
|
id='unsupportedBrowser.titleUnsupportedBrowser'
|
||||||
|
defaultMessage='Detected unsupported browser!'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{webrtcUnavailable &&
|
||||||
|
<FormattedMessage
|
||||||
|
id='unsupportedBrowser.titlewebrtcUnavailable'
|
||||||
|
defaultMessage='Required functionality not availble in your browser!'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent dividers={dividers} >
|
||||||
|
<FormattedMessage
|
||||||
|
id='unsupportedBrowser.bodyText'
|
||||||
|
defaultMessage='This meeting service requires a
|
||||||
|
functionality that is not supported by your browser.
|
||||||
|
Please upgrade, or switch to a different browser, or
|
||||||
|
check your settings. Supported browsers:'
|
||||||
|
/>
|
||||||
|
<Grid container spacing={2} justify='center' alignItems='center'>
|
||||||
|
<Grid item xs={12} md={7}>
|
||||||
|
|
||||||
|
<div className={classes.list}>
|
||||||
|
<List dense={dense}>
|
||||||
|
{supportedBrowsers.map((browser, index) =>
|
||||||
|
{
|
||||||
|
const supportedBrowser = `${browser.vendor} ${browser.name}`;
|
||||||
|
const supportedVersion = `${browser.version}+`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ListItem key={index}>
|
||||||
|
<ListItemAvatar>
|
||||||
|
<Avatar>
|
||||||
|
<WebAssetIcon />
|
||||||
|
</Avatar>
|
||||||
|
</ListItemAvatar>
|
||||||
|
<ListItemText
|
||||||
|
primary={supportedBrowser}
|
||||||
|
secondary={supportedVersion}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</List>
|
||||||
|
</div>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} md={5} align='center'>
|
||||||
|
<Hidden mdDown>
|
||||||
|
<ErrorIcon className={classes.errorAvatar} color='error'/>
|
||||||
|
</Hidden>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
UnsupportedBrowser.propTypes =
|
||||||
|
{
|
||||||
|
webrtcUnavailable : PropTypes.bool.isRequired,
|
||||||
|
platform : PropTypes.string.isRequired,
|
||||||
|
classes : PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(UnsupportedBrowser);
|
||||||
|
|
@ -223,50 +223,50 @@ class VideoView extends React.PureComponent
|
||||||
if (videoScore || audioScore)
|
if (videoScore || audioScore)
|
||||||
{
|
{
|
||||||
const score = videoScore ? videoScore : audioScore;
|
const score = videoScore ? videoScore : audioScore;
|
||||||
|
|
||||||
switch (isMe ? score.score : score.producerScore)
|
switch (isMe ? score.score : score.producerScore)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
quality = <SignalCellular0BarIcon style={{ color: red[500] }}/>;
|
quality = <SignalCellular0BarIcon style={{ color: red[500] }}/>;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
quality = <SignalCellular1BarIcon style={{ color: red[500] }}/>;
|
quality = <SignalCellular1BarIcon style={{ color: red[500] }}/>;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
{
|
{
|
||||||
quality = <SignalCellular2BarIcon style={{ color: orange[500] }}/>;
|
quality = <SignalCellular2BarIcon style={{ color: orange[500] }}/>;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
{
|
{
|
||||||
quality = <SignalCellular3BarIcon style={{ color: yellow[500] }}/>;
|
quality = <SignalCellular3BarIcon style={{ color: yellow[500] }}/>;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
{
|
{
|
||||||
quality = null;
|
quality = null;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
@ -351,7 +351,7 @@ class VideoView extends React.PureComponent
|
||||||
</div>
|
</div>
|
||||||
{ showQuality &&
|
{ showQuality &&
|
||||||
<div className={classnames(classes.box, 'right')}>
|
<div className={classnames(classes.box, 'right')}>
|
||||||
{
|
{
|
||||||
quality
|
quality
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import RoomClient from './RoomClient';
|
||||||
import RoomContext from './RoomContext';
|
import RoomContext from './RoomContext';
|
||||||
import deviceInfo from './deviceInfo';
|
import deviceInfo from './deviceInfo';
|
||||||
import * as meActions from './actions/meActions';
|
import * as meActions from './actions/meActions';
|
||||||
|
import UnsupportedBrowser from './components/UnsupportedBrowser';
|
||||||
import ChooseRoom from './components/ChooseRoom';
|
import ChooseRoom from './components/ChooseRoom';
|
||||||
import LoadingView from './components/LoadingView';
|
import LoadingView from './components/LoadingView';
|
||||||
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
|
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
|
||||||
|
|
@ -20,7 +21,7 @@ import { persistor, store } from './store';
|
||||||
import { SnackbarProvider } from 'notistack';
|
import { SnackbarProvider } from 'notistack';
|
||||||
import * as serviceWorker from './serviceWorker';
|
import * as serviceWorker from './serviceWorker';
|
||||||
import { ReactLazyPreload } from './components/ReactLazyPreload';
|
import { ReactLazyPreload } from './components/ReactLazyPreload';
|
||||||
|
import { detectDevice } from 'mediasoup-client';
|
||||||
// import messagesEnglish from './translations/en';
|
// import messagesEnglish from './translations/en';
|
||||||
import messagesNorwegian from './translations/nb';
|
import messagesNorwegian from './translations/nb';
|
||||||
import messagesGerman from './translations/de';
|
import messagesGerman from './translations/de';
|
||||||
|
|
@ -70,6 +71,18 @@ const messages =
|
||||||
'lv' : messagesLatvian
|
'lv' : messagesLatvian
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const supportedBrowsers={
|
||||||
|
'windows' : {
|
||||||
|
'internet explorer' : '>12',
|
||||||
|
'microsoft edge' : '>18'
|
||||||
|
},
|
||||||
|
'safari' : '>12',
|
||||||
|
'firefox' : '>=60',
|
||||||
|
'chrome' : '>=74',
|
||||||
|
'opera' : '>=62',
|
||||||
|
'samsung internet for android' : '>=11.1.1.52'
|
||||||
|
};
|
||||||
|
|
||||||
const browserLanguage = (navigator.language || navigator.browserLanguage).toLowerCase();
|
const browserLanguage = (navigator.language || navigator.browserLanguage).toLowerCase();
|
||||||
|
|
||||||
let locale = browserLanguage.split(/[-_]/)[0]; // language without region code
|
let locale = browserLanguage.split(/[-_]/)[0]; // language without region code
|
||||||
|
|
@ -134,10 +147,62 @@ function run()
|
||||||
|
|
||||||
if (!basePath)
|
if (!basePath)
|
||||||
basePath = '/';
|
basePath = '/';
|
||||||
|
|
||||||
// Get current device.
|
// Get current device.
|
||||||
const device = deviceInfo();
|
const device = deviceInfo();
|
||||||
|
|
||||||
|
let unsupportedBrowser=false;
|
||||||
|
|
||||||
|
let webrtcUnavailable=false;
|
||||||
|
|
||||||
|
if (detectDevice() === undefined)
|
||||||
|
{
|
||||||
|
logger.error('Unsupported browser detected by mediasoup client detectDevice! deviceInfo: %o', device);
|
||||||
|
unsupportedBrowser=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (
|
||||||
|
navigator.mediaDevices === undefined ||
|
||||||
|
navigator.mediaDevices.getUserMedia === undefined ||
|
||||||
|
window.RTCPeerConnection === undefined
|
||||||
|
)
|
||||||
|
{
|
||||||
|
logger.error('WebRTC is unavialable in your browser! deviceInfo: %o', device);
|
||||||
|
webrtcUnavailable=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!device.bowser.satisfies(
|
||||||
|
window.config.supportedBrowsers ? window.config.supportedBrowsers : supportedBrowsers)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
logger.error(
|
||||||
|
'Your browser is not on the supported list! Ask your server admin to add your browser to the supported list, if you think that your browser should be supported! deviceInfo: %o',
|
||||||
|
device
|
||||||
|
);
|
||||||
|
unsupportedBrowser=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.debug('Supported Browser! deviceInfo: %o', device);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unsupportedBrowser || webrtcUnavailable)
|
||||||
|
{
|
||||||
|
render(
|
||||||
|
<MuiThemeProvider theme={theme}>
|
||||||
|
<RawIntlProvider value={intl}>
|
||||||
|
<UnsupportedBrowser
|
||||||
|
webrtcUnavailable={webrtcUnavailable}
|
||||||
|
platform={device.platform}
|
||||||
|
/>
|
||||||
|
</RawIntlProvider>
|
||||||
|
</MuiThemeProvider>,
|
||||||
|
document.getElementById('multiparty-meeting')
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
meActions.setMe({
|
meActions.setMe({
|
||||||
peerId,
|
peerId,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
|
||||||
|
class AudioAnalyzer extends EventEmitter
|
||||||
|
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
this._debug = debug(`${APP_NAME}:${prefix}`);
|
||||||
|
this._warn = debug(`${APP_NAME}:WARN:${prefix}`);
|
||||||
|
this._error = debug(`${APP_NAME}:ERROR:${prefix}`);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this._debug = debug(APP_NAME);
|
||||||
|
this._warn = debug(`${APP_NAME}:WARN`);
|
||||||
|
this._error = debug(`${APP_NAME}:ERROR`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
this._debug.log = console.info.bind(console);
|
||||||
|
this._warn.log = console.warn.bind(console);
|
||||||
|
this._error.log = console.error.bind(console);
|
||||||
|
/* eslint-enable no-console */
|
||||||
|
}
|
||||||
|
|
||||||
|
get debug()
|
||||||
|
{
|
||||||
|
return this._debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
get warn()
|
||||||
|
{
|
||||||
|
return this._warn;
|
||||||
|
}
|
||||||
|
|
||||||
|
get error()
|
||||||
|
{
|
||||||
|
return this._error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const lobbyPeer = (state = {}, action) =>
|
const lobbyPeer = (state = {}, action) =>
|
||||||
{
|
{
|
||||||
switch (action.type)
|
switch (action.type)
|
||||||
{
|
{
|
||||||
case 'ADD_LOBBY_PEER':
|
case 'ADD_LOBBY_PEER':
|
||||||
return { id: action.payload.peerId };
|
return { id: action.payload.peerId };
|
||||||
|
|
@ -42,7 +42,7 @@ const lobbyPeers = (state = {}, action) =>
|
||||||
{
|
{
|
||||||
const oldLobbyPeer = state[action.payload.peerId];
|
const oldLobbyPeer = state[action.payload.peerId];
|
||||||
|
|
||||||
if (!oldLobbyPeer)
|
if (!oldLobbyPeer)
|
||||||
{
|
{
|
||||||
// Tried to update non-existent lobbyPeer. Has probably been promoted, or left.
|
// Tried to update non-existent lobbyPeer. Has probably been promoted, or left.
|
||||||
return state;
|
return state;
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ const peerVolumes = (state = initialState, action) =>
|
||||||
peerId
|
peerId
|
||||||
} = action.payload;
|
} = action.payload;
|
||||||
|
|
||||||
return { ...state, [peerId]: 0 };
|
return { ...state, [peerId]: -100 };
|
||||||
}
|
}
|
||||||
case 'ADD_PEER':
|
case 'ADD_PEER':
|
||||||
{
|
{
|
||||||
const { peer } = action.payload;
|
const { peer } = action.payload;
|
||||||
|
|
||||||
return { ...state, [peer.id]: 0 };
|
return { ...state, [peer.id]: -100 };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'REMOVE_PEER':
|
case 'REMOVE_PEER':
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const initialState = {};
|
||||||
|
|
||||||
const peer = (state = initialState, action) =>
|
const peer = (state = initialState, action) =>
|
||||||
{
|
{
|
||||||
switch (action.type)
|
switch (action.type)
|
||||||
{
|
{
|
||||||
case 'ADD_PEER':
|
case 'ADD_PEER':
|
||||||
return action.payload.peer;
|
return action.payload.peer;
|
||||||
|
|
@ -21,7 +21,7 @@ const peer = (state = initialState, action) =>
|
||||||
|
|
||||||
case 'SET_PEER_KICK_IN_PROGRESS':
|
case 'SET_PEER_KICK_IN_PROGRESS':
|
||||||
return { ...state, peerKickInProgress: action.payload.flag };
|
return { ...state, peerKickInProgress: action.payload.flag };
|
||||||
|
|
||||||
case 'SET_PEER_RAISED_HAND':
|
case 'SET_PEER_RAISED_HAND':
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
|
@ -34,7 +34,7 @@ const peer = (state = initialState, action) =>
|
||||||
...state,
|
...state,
|
||||||
raisedHandInProgress : action.payload.flag
|
raisedHandInProgress : action.payload.flag
|
||||||
};
|
};
|
||||||
|
|
||||||
case 'ADD_CONSUMER':
|
case 'ADD_CONSUMER':
|
||||||
{
|
{
|
||||||
const consumers = [ ...state.consumers, action.payload.consumer.id ];
|
const consumers = [ ...state.consumers, action.payload.consumer.id ];
|
||||||
|
|
@ -127,14 +127,14 @@ const peers = (state = initialState, action) =>
|
||||||
{
|
{
|
||||||
const oldPeer = state[action.payload.peerId];
|
const oldPeer = state[action.payload.peerId];
|
||||||
|
|
||||||
if (!oldPeer)
|
if (!oldPeer)
|
||||||
{
|
{
|
||||||
throw new Error('no Peer found');
|
throw new Error('no Peer found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return { ...state, [oldPeer.id]: peer(oldPeer, action) };
|
return { ...state, [oldPeer.id]: peer(oldPeer, action) };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_PEER_KICK_IN_PROGRESS':
|
case 'SET_PEER_KICK_IN_PROGRESS':
|
||||||
case 'REMOVE_CONSUMER':
|
case 'REMOVE_CONSUMER':
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const initialState =
|
||||||
// access code to the room if locked and joinByAccessCode == true
|
// access code to the room if locked and joinByAccessCode == true
|
||||||
accessCode : '',
|
accessCode : '',
|
||||||
// if true: accessCode is a possibility to open the room
|
// if true: accessCode is a possibility to open the room
|
||||||
joinByAccessCode : true,
|
joinByAccessCode : true,
|
||||||
activeSpeakerId : null,
|
activeSpeakerId : null,
|
||||||
torrentSupport : false,
|
torrentSupport : false,
|
||||||
showSettings : false,
|
showSettings : false,
|
||||||
|
|
@ -107,7 +107,7 @@ const room = (state = initialState, action) =>
|
||||||
|
|
||||||
return { ...state, lockDialogOpen };
|
return { ...state, lockDialogOpen };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_SETTINGS_OPEN':
|
case 'SET_SETTINGS_OPEN':
|
||||||
{
|
{
|
||||||
const { settingsOpen } = action.payload;
|
const { settingsOpen } = action.payload;
|
||||||
|
|
@ -135,7 +135,7 @@ const room = (state = initialState, action) =>
|
||||||
|
|
||||||
return { ...state, aboutOpen };
|
return { ...state, aboutOpen };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_SETTINGS_TAB':
|
case 'SET_SETTINGS_TAB':
|
||||||
{
|
{
|
||||||
const { tab } = action.payload;
|
const { tab } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ const initialState =
|
||||||
notificationSounds : true,
|
notificationSounds : true,
|
||||||
buttonControlBar : window.config.buttonControlBar || false,
|
buttonControlBar : window.config.buttonControlBar || false,
|
||||||
drawerOverlayed : window.config.drawerOverlayed || true,
|
drawerOverlayed : window.config.drawerOverlayed || true,
|
||||||
autoMuteThreshold : window.config.autoMuteThreshold || 4,
|
|
||||||
...window.config.defaultAudio
|
...window.config.defaultAudio
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -44,7 +43,7 @@ const settings = (state = initialState, action) =>
|
||||||
{
|
{
|
||||||
return { ...state, selectedAudioOutputDevice: action.payload.deviceId };
|
return { ...state, selectedAudioOutputDevice: action.payload.deviceId };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'SET_DISPLAY_NAME':
|
case 'SET_DISPLAY_NAME':
|
||||||
{
|
{
|
||||||
const { displayName } = action.payload;
|
const { displayName } = action.payload;
|
||||||
|
|
@ -122,27 +121,6 @@ const settings = (state = initialState, action) =>
|
||||||
return { ...state, audio };
|
return { ...state, audio };
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'TOGGLE_AUTO_GAIN_CONTROL':
|
|
||||||
{
|
|
||||||
const autoGainControl = !state.autoGainControl;
|
|
||||||
|
|
||||||
return { ...state, autoGainControl };
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'TOGGLE_ECHO_CANCELLATION':
|
|
||||||
{
|
|
||||||
const echoCancellation = !state.echoCancellation;
|
|
||||||
|
|
||||||
return { ...state, echoCancellation };
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'TOGGLE_NOISE_SUPPRESSION':
|
|
||||||
{
|
|
||||||
const noiseSuppression = !state.noiseSuppression;
|
|
||||||
|
|
||||||
return { ...state, noiseSuppression };
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'SET_SAMPLE_SIZE':
|
case 'SET_SAMPLE_SIZE':
|
||||||
{
|
{
|
||||||
const { sampleSize } = action.payload;
|
const { sampleSize } = action.payload;
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "设置",
|
"settings.settings": "设置",
|
||||||
"settings.camera": "视频设备",
|
"settings.camera": "视频设备",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "无法保存文件",
|
"filesharing.saveFileError": "无法保存文件",
|
||||||
"filesharing.startingFileShare": "正在尝试共享文件",
|
"filesharing.startingFileShare": "正在尝试共享文件",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -118,6 +118,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Nastavení",
|
"settings.settings": "Nastavení",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -143,6 +144,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Není možné uložit soubor",
|
"filesharing.saveFileError": "Není možné uložit soubor",
|
||||||
"filesharing.startingFileShare": "Pokouším se sdílet soubor",
|
"filesharing.startingFileShare": "Pokouším se sdílet soubor",
|
||||||
|
|
@ -188,5 +191,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Video hinzufügen",
|
"label.addVideo": "Video hinzufügen",
|
||||||
"label.promoteAllPeers": "Alle Teilnehmer reinlassen",
|
"label.promoteAllPeers": "Alle Teilnehmer reinlassen",
|
||||||
"label.moreActions": "Weitere Aktionen",
|
"label.moreActions": "Weitere Aktionen",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Einstellungen",
|
"settings.settings": "Einstellungen",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Automatische Pegelregelung (Audioeingang)",
|
"settings.autoGainControl": "Automatische Pegelregelung (Audioeingang)",
|
||||||
"settings.noiseSuppression": "Rauschunterdrückung",
|
"settings.noiseSuppression": "Rauschunterdrückung",
|
||||||
"settings.drawerOverlayed": "Seitenpanel verdeckt Hauptinhalt",
|
"settings.drawerOverlayed": "Seitenpanel verdeckt Hauptinhalt",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Fehler beim Speichern der Datei",
|
"filesharing.saveFileError": "Fehler beim Speichern der Datei",
|
||||||
"filesharing.startingFileShare": "Starte Teilen der Datei",
|
"filesharing.startingFileShare": "Starte Teilen der Datei",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Moderator hat geteilte Dateiliste gelöscht",
|
"moderator.clearFiles": "Moderator hat geteilte Dateiliste gelöscht",
|
||||||
"moderator.muteAudio": "Moderator hat dich stummgeschaltet",
|
"moderator.muteAudio": "Moderator hat dich stummgeschaltet",
|
||||||
"moderator.muteVideo": "Moderator hat dein Video gestoppt",
|
"moderator.muteVideo": "Moderator hat dein Video gestoppt",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Indstillinger",
|
"settings.settings": "Indstillinger",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Kan ikke gemme fil",
|
"filesharing.saveFileError": "Kan ikke gemme fil",
|
||||||
"filesharing.startingFileShare": "Forsøger at dele filen",
|
"filesharing.startingFileShare": "Forsøger at dele filen",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ρυθμίσεις",
|
"settings.settings": "Ρυθμίσεις",
|
||||||
"settings.camera": "Κάμερα",
|
"settings.camera": "Κάμερα",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Αδυναμία αποθήκευσης του αρχείου",
|
"filesharing.saveFileError": "Αδυναμία αποθήκευσης του αρχείου",
|
||||||
"filesharing.startingFileShare": "Προσπάθεια διαμοιρασμού αρχείου",
|
"filesharing.startingFileShare": "Προσπάθεια διαμοιρασμού αρχείου",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Add video",
|
"label.addVideo": "Add video",
|
||||||
"label.promoteAllPeers": "Promote all",
|
"label.promoteAllPeers": "Promote all",
|
||||||
"label.moreActions": "More actions",
|
"label.moreActions": "More actions",
|
||||||
|
"label.version": "Version",
|
||||||
|
|
||||||
"settings.settings": "Settings",
|
"settings.settings": "Settings",
|
||||||
"settings.camera": "Camera",
|
"settings.camera": "Camera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Auto gain control",
|
"settings.autoGainControl": "Auto gain control",
|
||||||
"settings.noiseSuppression": "Noise suppression",
|
"settings.noiseSuppression": "Noise suppression",
|
||||||
"settings.drawerOverlayed": "Side drawer over content",
|
"settings.drawerOverlayed": "Side drawer over content",
|
||||||
|
"settings.voiceActivatedUnmute": "Voice activated unmute",
|
||||||
|
"settings.noiseThreshold": "Noise threshold",
|
||||||
|
|
||||||
"filesharing.saveFileError": "Unable to save file",
|
"filesharing.saveFileError": "Unable to save file",
|
||||||
"filesharing.startingFileShare": "Attempting to share file",
|
"filesharing.startingFileShare": "Attempting to share file",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Moderator cleared the files",
|
"moderator.clearFiles": "Moderator cleared the files",
|
||||||
"moderator.muteAudio": "Moderator muted your audio",
|
"moderator.muteAudio": "Moderator muted your audio",
|
||||||
"moderator.muteVideo": "Moderator muted your video",
|
"moderator.muteVideo": "Moderator muted your video",
|
||||||
"moderator.muteScreenSharing": "Moderator muted your screen sharing"
|
"moderator.stopScreenSharing": "Moderator stopped your screen sharing",
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUsnsupportedBrowser": "Detected unsupported browser!",
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": "Required functionality not available in your browser!",
|
||||||
|
"unsupportedBrowser.bodyText": "This meeting service requires a functionality that is not supported by your browser. Please upgrade, or switch to a different browser, or check your settings. Supported browsers:"
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ajustes",
|
"settings.settings": "Ajustes",
|
||||||
"settings.camera": "Cámara",
|
"settings.camera": "Cámara",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "No ha sido posible guardar el fichero",
|
"filesharing.saveFileError": "No ha sido posible guardar el fichero",
|
||||||
"filesharing.startingFileShare": "Intentando compartir el fichero",
|
"filesharing.startingFileShare": "Intentando compartir el fichero",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Paramètres",
|
"settings.settings": "Paramètres",
|
||||||
"settings.camera": "Caméra",
|
"settings.camera": "Caméra",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Impossible d'enregistrer le fichier",
|
"filesharing.saveFileError": "Impossible d'enregistrer le fichier",
|
||||||
"filesharing.startingFileShare": "Début du transfert de fichier",
|
"filesharing.startingFileShare": "Début du transfert de fichier",
|
||||||
|
|
@ -188,5 +191,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Dodaj video",
|
"label.addVideo": "Dodaj video",
|
||||||
"label.promoteAllPeers": "Promoviraj sve",
|
"label.promoteAllPeers": "Promoviraj sve",
|
||||||
"label.moreActions": "Više akcija",
|
"label.moreActions": "Više akcija",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Postavke",
|
"settings.settings": "Postavke",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Automatsko upravljanje jačinom zvuka",
|
"settings.autoGainControl": "Automatsko upravljanje jačinom zvuka",
|
||||||
"settings.noiseSuppression": "Poništavanje šuma",
|
"settings.noiseSuppression": "Poništavanje šuma",
|
||||||
"settings.drawerOverlayed": "Bočni izbornik iznad sadržaja",
|
"settings.drawerOverlayed": "Bočni izbornik iznad sadržaja",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Nije moguće spremiti datoteku",
|
"filesharing.saveFileError": "Nije moguće spremiti datoteku",
|
||||||
"filesharing.startingFileShare": "Pokušaj dijeljenja datoteke",
|
"filesharing.startingFileShare": "Pokušaj dijeljenja datoteke",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Moderator je izbrisao datoteke",
|
"moderator.clearFiles": "Moderator je izbrisao datoteke",
|
||||||
"moderator.muteAudio": "Moderator je utišao tvoj zvuk",
|
"moderator.muteAudio": "Moderator je utišao tvoj zvuk",
|
||||||
"moderator.muteVideo": "Moderator je zaustavio tvoj video",
|
"moderator.muteVideo": "Moderator je zaustavio tvoj video",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
"room.browsePeersSpotlight": "Résztvevők böngészése",
|
"room.browsePeersSpotlight": "Résztvevők böngészése",
|
||||||
"room.stopAllScreenSharing": "Összes képernyőmegosztás leállítása",
|
"room.stopAllScreenSharing": "Összes képernyőmegosztás leállítása",
|
||||||
|
|
||||||
"me.mutedPTT": "Némítva vagy, ha beszélnél nyomd le a szóköz billentyűt",
|
"me.mutedPTT": "Némítva vagy, ha beszélnél nyomd le a SZÓKÖZ billentyűt",
|
||||||
|
|
||||||
"roles.gotRole": "{role} szerepet kaptál",
|
"roles.gotRole": "{role} szerepet kaptál",
|
||||||
"roles.lostRole": "Elvesztetted a {role} szerepet",
|
"roles.lostRole": "Elvesztetted a {role} szerepet",
|
||||||
|
|
@ -86,9 +86,9 @@
|
||||||
"tooltip.muteParticipantVideo": "Résztvevő videóstreamének némítása",
|
"tooltip.muteParticipantVideo": "Résztvevő videóstreamének némítása",
|
||||||
"tooltip.raisedHand": "Jelentkezés",
|
"tooltip.raisedHand": "Jelentkezés",
|
||||||
"tooltip.muteScreenSharing": "Képernyőmegosztás szüneteltetése",
|
"tooltip.muteScreenSharing": "Képernyőmegosztás szüneteltetése",
|
||||||
"tooltip.muteParticipantAudioModerator": "Résztvevő hangjának általános némítása",
|
"tooltip.muteParticipantAudioModerator": "Résztvevő hangjának némítása mindenkinél",
|
||||||
"tooltip.muteParticipantVideoModerator": "Résztvevő videójának általános némítása",
|
"tooltip.muteParticipantVideoModerator": "Résztvevő videójának némítása mindenkinél",
|
||||||
"tooltip.muteScreenSharingModerator": "Résztvevő képernyőmegosztásának általános némítása",
|
"tooltip.muteScreenSharingModerator": "Résztvevő képernyőmegosztásának leállítása mindenkinél",
|
||||||
|
|
||||||
"label.roomName": "Konferencia",
|
"label.roomName": "Konferencia",
|
||||||
"label.chooseRoomButton": "Tovább",
|
"label.chooseRoomButton": "Tovább",
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Videó hozzáadása",
|
"label.addVideo": "Videó hozzáadása",
|
||||||
"label.promoteAllPeers": "Mindenkit beengedek",
|
"label.promoteAllPeers": "Mindenkit beengedek",
|
||||||
"label.moreActions": "További műveletek",
|
"label.moreActions": "További műveletek",
|
||||||
|
"label.version": "Verzió",
|
||||||
|
|
||||||
"settings.settings": "Beállítások",
|
"settings.settings": "Beállítások",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Automatikus hangerő",
|
"settings.autoGainControl": "Automatikus hangerő",
|
||||||
"settings.noiseSuppression": "Zajelnyomás",
|
"settings.noiseSuppression": "Zajelnyomás",
|
||||||
"settings.drawerOverlayed": "Oldalsáv a tartalom felett",
|
"settings.drawerOverlayed": "Oldalsáv a tartalom felett",
|
||||||
|
"settings.voiceActivatedUnmute": "Beszéd aktivált mikrofon némítás",
|
||||||
|
"settings.noiseThreshold": "Zajszint",
|
||||||
|
|
||||||
"filesharing.saveFileError": "A file-t nem sikerült elmenteni",
|
"filesharing.saveFileError": "A file-t nem sikerült elmenteni",
|
||||||
"filesharing.startingFileShare": "Fájl megosztása",
|
"filesharing.startingFileShare": "Fájl megosztása",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "A moderátor kiürítette a file megosztás történelmet",
|
"moderator.clearFiles": "A moderátor kiürítette a file megosztás történelmet",
|
||||||
"moderator.muteAudio": "A moderátor elnémította a hangod",
|
"moderator.muteAudio": "A moderátor elnémította a hangod",
|
||||||
"moderator.muteVideo": "A moderátor elnémította a videód",
|
"moderator.muteVideo": "A moderátor elnémította a videód",
|
||||||
"moderator.muteScreenSharing": "A moderátor leállította képernyőmegosztásod"
|
"moderator.stopScreenSharing": "A moderátor leállította a képernyőmegosztásod",
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": "A bőngésző verziód sajnos nem támogatott! :-(",
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": "A böngésződ egy szükséges funkciója nem elérhető!",
|
||||||
|
"unsupportedBrowser.bodyText": "Kérlek frissítsd a böngésződ, válts másik böngészőre, vagy ellenőrizd a böngésződ beállításait! Támogatott böngészők:"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Aggiungi video",
|
"label.addVideo": "Aggiungi video",
|
||||||
"label.promoteAllPeers": "Promuovi tutti",
|
"label.promoteAllPeers": "Promuovi tutti",
|
||||||
"label.moreActions": "Altre azioni",
|
"label.moreActions": "Altre azioni",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Impostazioni",
|
"settings.settings": "Impostazioni",
|
||||||
"settings.camera": "Videocamera",
|
"settings.camera": "Videocamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Controllo guadagno automatico",
|
"settings.autoGainControl": "Controllo guadagno automatico",
|
||||||
"settings.noiseSuppression": "Riduzione del rumore",
|
"settings.noiseSuppression": "Riduzione del rumore",
|
||||||
"settings.drawerOverlayed": "Barra laterale sovrapposta",
|
"settings.drawerOverlayed": "Barra laterale sovrapposta",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Impossibile salvare file",
|
"filesharing.saveFileError": "Impossibile salvare file",
|
||||||
"filesharing.startingFileShare": "Tentativo di condivisione file",
|
"filesharing.startingFileShare": "Tentativo di condivisione file",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Il moderatore ha pulito i file",
|
"moderator.clearFiles": "Il moderatore ha pulito i file",
|
||||||
"moderator.muteAudio": "Il moderatore ha mutato il tuo audio",
|
"moderator.muteAudio": "Il moderatore ha mutato il tuo audio",
|
||||||
"moderator.muteVideo": "Il moderatore ha fermato il tuo video",
|
"moderator.muteVideo": "Il moderatore ha fermato il tuo video",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
}
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@
|
||||||
"label.advanced": "Advancēts",
|
"label.advanced": "Advancēts",
|
||||||
"label.addVideo": "Pievienot video",
|
"label.addVideo": "Pievienot video",
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Iestatījumi",
|
"settings.settings": "Iestatījumi",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -138,6 +139,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Nav iespējams saglabāt failu",
|
"filesharing.saveFileError": "Nav iespējams saglabāt failu",
|
||||||
"filesharing.startingFileShare": "Tiek mēģināts kopīgot failu",
|
"filesharing.startingFileShare": "Tiek mēģināts kopīgot failu",
|
||||||
|
|
@ -183,5 +186,9 @@
|
||||||
"moderator.clearFiles": "Moderators notīrīja failus",
|
"moderator.clearFiles": "Moderators notīrīja failus",
|
||||||
"moderator.muteAudio": "Moderators noklusināja jūsu mikrofonu",
|
"moderator.muteAudio": "Moderators noklusināja jūsu mikrofonu",
|
||||||
"moderator.muteVideo": "Moderators atslēdza jūsu kameru",
|
"moderator.muteVideo": "Moderators atslēdza jūsu kameru",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Legg til video",
|
"label.addVideo": "Legg til video",
|
||||||
"label.promoteAllPeers": "Slipp inn alle",
|
"label.promoteAllPeers": "Slipp inn alle",
|
||||||
"label.moreActions": "Flere handlinger",
|
"label.moreActions": "Flere handlinger",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Innstillinger",
|
"settings.settings": "Innstillinger",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Auto gain kontroll",
|
"settings.autoGainControl": "Auto gain kontroll",
|
||||||
"settings.noiseSuppression": "Støy reduksjon",
|
"settings.noiseSuppression": "Støy reduksjon",
|
||||||
"settings.drawerOverlayed": "Sidemeny over innhold",
|
"settings.drawerOverlayed": "Sidemeny over innhold",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Klarte ikke å lagre fil",
|
"filesharing.saveFileError": "Klarte ikke å lagre fil",
|
||||||
"filesharing.startingFileShare": "Starter fildeling",
|
"filesharing.startingFileShare": "Starter fildeling",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Moderator fjernet filer",
|
"moderator.clearFiles": "Moderator fjernet filer",
|
||||||
"moderator.muteAudio": "Moderator mutet lyden din",
|
"moderator.muteAudio": "Moderator mutet lyden din",
|
||||||
"moderator.muteVideo": "Moderator mutet videoen din",
|
"moderator.muteVideo": "Moderator mutet videoen din",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": "Dodaj wideo",
|
"label.addVideo": "Dodaj wideo",
|
||||||
"label.promoteAllPeers": "Wpuść wszystkich",
|
"label.promoteAllPeers": "Wpuść wszystkich",
|
||||||
"label.moreActions": "Więcej akcji",
|
"label.moreActions": "Więcej akcji",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ustawienia",
|
"settings.settings": "Ustawienia",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": "Auto korekta wzmocnienia",
|
"settings.autoGainControl": "Auto korekta wzmocnienia",
|
||||||
"settings.noiseSuppression": "Wyciszenie szumów",
|
"settings.noiseSuppression": "Wyciszenie szumów",
|
||||||
"settings.drawerOverlayed": "Szuflada nad zawartością",
|
"settings.drawerOverlayed": "Szuflada nad zawartością",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Nie można zapisać pliku",
|
"filesharing.saveFileError": "Nie można zapisać pliku",
|
||||||
"filesharing.startingFileShare": "Próba udostępnienia pliku",
|
"filesharing.startingFileShare": "Próba udostępnienia pliku",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": "Moderator wyczyścił pliki",
|
"moderator.clearFiles": "Moderator wyczyścił pliki",
|
||||||
"moderator.muteAudio": "Moderator wyciszył audio",
|
"moderator.muteAudio": "Moderator wyciszył audio",
|
||||||
"moderator.muteVideo": "Moderator wyciszył twoje video",
|
"moderator.muteVideo": "Moderator wyciszył twoje video",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Definições",
|
"settings.settings": "Definições",
|
||||||
"settings.camera": "Camera",
|
"settings.camera": "Camera",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Impossível de gravar o ficheiro",
|
"filesharing.saveFileError": "Impossível de gravar o ficheiro",
|
||||||
"filesharing.startingFileShare": "Tentando partilha de ficheiro",
|
"filesharing.startingFileShare": "Tentando partilha de ficheiro",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Setări",
|
"settings.settings": "Setări",
|
||||||
"settings.camera": "Cameră video",
|
"settings.camera": "Cameră video",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Încercarea de a salva fișierul a eșuat",
|
"filesharing.saveFileError": "Încercarea de a salva fișierul a eșuat",
|
||||||
"filesharing.startingFileShare": "Partajarea fișierului",
|
"filesharing.startingFileShare": "Partajarea fișierului",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Ayarlar",
|
"settings.settings": "Ayarlar",
|
||||||
"settings.camera": "Kamera",
|
"settings.camera": "Kamera",
|
||||||
|
|
@ -141,6 +142,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Dosya kaydedilemiyor",
|
"filesharing.saveFileError": "Dosya kaydedilemiyor",
|
||||||
"filesharing.startingFileShare": "Paylaşılan dosyaya erişiliyor",
|
"filesharing.startingFileShare": "Paylaşılan dosyaya erişiliyor",
|
||||||
|
|
@ -181,5 +184,14 @@
|
||||||
|
|
||||||
"devices.cameraDisconnected": "Kamera bağlı değil",
|
"devices.cameraDisconnected": "Kamera bağlı değil",
|
||||||
"devices.cameraError": "Kameranıza erişilirken bir hata oluştu",
|
"devices.cameraError": "Kameranıza erişilirken bir hata oluştu",
|
||||||
"moderator.muteScreenSharing": null
|
|
||||||
|
"moderator.clearChat": null,
|
||||||
|
"moderator.clearFiles": null,
|
||||||
|
"moderator.muteAudio": null,
|
||||||
|
"moderator.muteVideo": null,
|
||||||
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,7 @@
|
||||||
"label.addVideo": "新增視訊",
|
"label.addVideo": "新增視訊",
|
||||||
"label.promoteAllPeers": "提升全部",
|
"label.promoteAllPeers": "提升全部",
|
||||||
"label.moreActions": "更多",
|
"label.moreActions": "更多",
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "設置",
|
"settings.settings": "設置",
|
||||||
"settings.camera": "視訊來源",
|
"settings.camera": "視訊來源",
|
||||||
|
|
@ -143,6 +144,8 @@
|
||||||
"settings.autoGainControl": "自動增益控制",
|
"settings.autoGainControl": "自動增益控制",
|
||||||
"settings.noiseSuppression": "噪音消除",
|
"settings.noiseSuppression": "噪音消除",
|
||||||
"settings.drawerOverlayed": "側邊欄覆蓋畫面",
|
"settings.drawerOverlayed": "側邊欄覆蓋畫面",
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "無法保存文件",
|
"filesharing.saveFileError": "無法保存文件",
|
||||||
"filesharing.startingFileShare": "開始分享文件",
|
"filesharing.startingFileShare": "開始分享文件",
|
||||||
|
|
@ -188,5 +191,9 @@
|
||||||
"moderator.clearFiles": "管理員清除了所有檔案",
|
"moderator.clearFiles": "管理員清除了所有檔案",
|
||||||
"moderator.muteAudio": "您已被管理員靜音",
|
"moderator.muteAudio": "您已被管理員靜音",
|
||||||
"moderator.muteVideo": "您的視訊已被管理員關閉",
|
"moderator.muteVideo": "您的視訊已被管理員關閉",
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -119,6 +119,7 @@
|
||||||
"label.addVideo": null,
|
"label.addVideo": null,
|
||||||
"label.promoteAllPeers": null,
|
"label.promoteAllPeers": null,
|
||||||
"label.moreActions": null,
|
"label.moreActions": null,
|
||||||
|
"label.version": null,
|
||||||
|
|
||||||
"settings.settings": "Налаштування",
|
"settings.settings": "Налаштування",
|
||||||
"settings.camera": "Камера",
|
"settings.camera": "Камера",
|
||||||
|
|
@ -144,6 +145,8 @@
|
||||||
"settings.autoGainControl": null,
|
"settings.autoGainControl": null,
|
||||||
"settings.noiseSuppression": null,
|
"settings.noiseSuppression": null,
|
||||||
"settings.drawerOverlayed": null,
|
"settings.drawerOverlayed": null,
|
||||||
|
"settings.voiceActivatedUnmute": null,
|
||||||
|
"settings.noiseThreshold": null,
|
||||||
|
|
||||||
"filesharing.saveFileError": "Неможливо зберегти файл",
|
"filesharing.saveFileError": "Неможливо зберегти файл",
|
||||||
"filesharing.startingFileShare": "Спроба поділитися файлом",
|
"filesharing.startingFileShare": "Спроба поділитися файлом",
|
||||||
|
|
@ -189,5 +192,9 @@
|
||||||
"moderator.clearFiles": null,
|
"moderator.clearFiles": null,
|
||||||
"moderator.muteAudio": null,
|
"moderator.muteAudio": null,
|
||||||
"moderator.muteVideo": null,
|
"moderator.muteVideo": null,
|
||||||
"moderator.muteScreenSharing": null
|
"moderator.stopScreenSharing": null,
|
||||||
|
|
||||||
|
"unsupportedBrowser.titleUnsupportedBrowser": null,
|
||||||
|
"unsupportedBrowser.titlewebrtcUnavailable": null,
|
||||||
|
"unsupportedBrowser.bodyText": null
|
||||||
}
|
}
|
||||||
|
|
@ -3,17 +3,35 @@
|
||||||
* after the given amount of milliseconds has passed since
|
* after the given amount of milliseconds has passed since
|
||||||
* the last time the callback function was called.
|
* the last time the callback function was called.
|
||||||
*/
|
*/
|
||||||
export const idle = (callback, delay) =>
|
export const idle = (callback, delay) =>
|
||||||
{
|
{
|
||||||
let handle;
|
let handle;
|
||||||
|
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
if (handle)
|
if (handle)
|
||||||
{
|
{
|
||||||
clearTimeout(handle);
|
clearTimeout(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = setTimeout(callback, delay);
|
handle = setTimeout(callback, delay);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
export class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -106,6 +106,12 @@
|
||||||
"no-invalid-regexp": 2,
|
"no-invalid-regexp": 2,
|
||||||
"no-invalid-this": 2,
|
"no-invalid-this": 2,
|
||||||
"no-irregular-whitespace": 2,
|
"no-irregular-whitespace": 2,
|
||||||
|
"no-trailing-spaces": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"ignoreComments": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"no-lonely-if": 2,
|
"no-lonely-if": 2,
|
||||||
"no-mixed-operators": 2,
|
"no-mixed-operators": 2,
|
||||||
"no-mixed-spaces-and-tabs": 2,
|
"no-mixed-spaces-and-tabs": 2,
|
||||||
|
|
|
||||||
|
|
@ -276,6 +276,10 @@ module.exports =
|
||||||
// maxUsersPerRoom : 20,
|
// maxUsersPerRoom : 20,
|
||||||
// Room size before spreading to new router
|
// Room size before spreading to new router
|
||||||
routerScaleSize : 40,
|
routerScaleSize : 40,
|
||||||
|
// Socket timout value
|
||||||
|
requestTimeout : 20000,
|
||||||
|
// Socket retries when timeout
|
||||||
|
requestRetries : 3,
|
||||||
// Mediasoup settings
|
// Mediasoup settings
|
||||||
mediasoup :
|
mediasoup :
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,9 @@ class Peer extends EventEmitter
|
||||||
{
|
{
|
||||||
if (this.closed)
|
if (this.closed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
logger.debug('"disconnect" event [id:%s]', this.id);
|
logger.debug('"disconnect" event [id:%s]', this.id);
|
||||||
|
|
||||||
this.close();
|
this.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +208,7 @@ class Peer extends EventEmitter
|
||||||
const oldDisplayName = this._displayName;
|
const oldDisplayName = this._displayName;
|
||||||
|
|
||||||
this._displayName = displayName;
|
this._displayName = displayName;
|
||||||
|
|
||||||
this.emit('displayNameChanged', { oldDisplayName });
|
this.emit('displayNameChanged', { oldDisplayName });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +225,7 @@ class Peer extends EventEmitter
|
||||||
const oldPicture = this._picture;
|
const oldPicture = this._picture;
|
||||||
|
|
||||||
this._picture = picture;
|
this._picture = picture;
|
||||||
|
|
||||||
this.emit('pictureChanged', { oldPicture });
|
this.emit('pictureChanged', { oldPicture });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const AwaitQueue = require('awaitqueue');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
const Logger = require('./Logger');
|
const Logger = require('./Logger');
|
||||||
const Lobby = require('./Lobby');
|
const Lobby = require('./Lobby');
|
||||||
|
const { SocketTimeoutError } = require('./errors');
|
||||||
const { v4: uuidv4 } = require('uuid');
|
const { v4: uuidv4 } = require('uuid');
|
||||||
const jwt = require('jsonwebtoken');
|
const jwt = require('jsonwebtoken');
|
||||||
const userRoles = require('../userRoles');
|
const userRoles = require('../userRoles');
|
||||||
|
|
@ -492,7 +493,7 @@ class Room extends EventEmitter
|
||||||
peer.socket.handshake.session.save();
|
peer.socket.handshake.session.save();
|
||||||
|
|
||||||
let turnServers;
|
let turnServers;
|
||||||
|
|
||||||
if ('turnAPIURI' in config)
|
if ('turnAPIURI' in config)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
@ -506,7 +507,7 @@ class Room extends EventEmitter
|
||||||
'ip' : peer.socket.request.connection.remoteAddress
|
'ip' : peer.socket.request.connection.remoteAddress
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
turnServers = [ {
|
turnServers = [ {
|
||||||
urls : data.uris,
|
urls : data.uris,
|
||||||
username : data.username,
|
username : data.username,
|
||||||
|
|
@ -517,7 +518,7 @@ class Room extends EventEmitter
|
||||||
{
|
{
|
||||||
if ('backupTurnServers' in config)
|
if ('backupTurnServers' in config)
|
||||||
turnServers = config.backupTurnServers;
|
turnServers = config.backupTurnServers;
|
||||||
|
|
||||||
logger.error('_peerJoining() | error on REST turn [error:"%o"]', error);
|
logger.error('_peerJoining() | error on REST turn [error:"%o"]', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -525,7 +526,7 @@ class Room extends EventEmitter
|
||||||
{
|
{
|
||||||
turnServers = config.backupTurnServers;
|
turnServers = config.backupTurnServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._notification(peer.socket, 'roomReady', { turnServers });
|
this._notification(peer.socket, 'roomReady', { turnServers });
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -778,7 +779,7 @@ class Room extends EventEmitter
|
||||||
// initiate mediasoup Transports and be ready when he later joins.
|
// initiate mediasoup Transports and be ready when he later joins.
|
||||||
|
|
||||||
const { forceTcp, producing, consuming } = request.data;
|
const { forceTcp, producing, consuming } = request.data;
|
||||||
|
|
||||||
const webRtcTransportOptions =
|
const webRtcTransportOptions =
|
||||||
{
|
{
|
||||||
...config.mediasoup.webRtcTransport,
|
...config.mediasoup.webRtcTransport,
|
||||||
|
|
@ -1186,7 +1187,7 @@ class Room extends EventEmitter
|
||||||
throw new Error('peer not authorized');
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
const { chatMessage } = request.data;
|
const { chatMessage } = request.data;
|
||||||
|
|
||||||
this._chatHistory.push(chatMessage);
|
this._chatHistory.push(chatMessage);
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1205,7 +1206,7 @@ class Room extends EventEmitter
|
||||||
{
|
{
|
||||||
if (!this._hasPermission(peer, MODERATE_CHAT))
|
if (!this._hasPermission(peer, MODERATE_CHAT))
|
||||||
throw new Error('peer not authorized');
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
this._chatHistory = [];
|
this._chatHistory = [];
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1258,7 +1259,7 @@ class Room extends EventEmitter
|
||||||
case 'setAccessCode':
|
case 'setAccessCode':
|
||||||
{
|
{
|
||||||
const { accessCode } = request.data;
|
const { accessCode } = request.data;
|
||||||
|
|
||||||
this._accessCode = accessCode;
|
this._accessCode = accessCode;
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1278,7 +1279,7 @@ class Room extends EventEmitter
|
||||||
case 'setJoinByAccessCode':
|
case 'setJoinByAccessCode':
|
||||||
{
|
{
|
||||||
const { joinByAccessCode } = request.data;
|
const { joinByAccessCode } = request.data;
|
||||||
|
|
||||||
this._joinByAccessCode = joinByAccessCode;
|
this._joinByAccessCode = joinByAccessCode;
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1327,7 +1328,7 @@ class Room extends EventEmitter
|
||||||
throw new Error('peer not authorized');
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
const { magnetUri } = request.data;
|
const { magnetUri } = request.data;
|
||||||
|
|
||||||
this._fileHistory.push({ peerId: peer.id, magnetUri: magnetUri });
|
this._fileHistory.push({ peerId: peer.id, magnetUri: magnetUri });
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1346,7 +1347,7 @@ class Room extends EventEmitter
|
||||||
{
|
{
|
||||||
if (!this._hasPermission(peer, MODERATE_FILES))
|
if (!this._hasPermission(peer, MODERATE_FILES))
|
||||||
throw new Error('peer not authorized');
|
throw new Error('peer not authorized');
|
||||||
|
|
||||||
this._fileHistory = [];
|
this._fileHistory = [];
|
||||||
|
|
||||||
// Spread to others
|
// Spread to others
|
||||||
|
|
@ -1759,9 +1760,9 @@ class Room extends EventEmitter
|
||||||
if (called)
|
if (called)
|
||||||
return;
|
return;
|
||||||
called = true;
|
called = true;
|
||||||
callback(new Error('Request timeout.'));
|
callback(new SocketTimeoutError('Request timed out'));
|
||||||
},
|
},
|
||||||
10000
|
config.requestTimeout || 20000
|
||||||
);
|
);
|
||||||
|
|
||||||
return (...args) =>
|
return (...args) =>
|
||||||
|
|
@ -1775,7 +1776,7 @@ class Room extends EventEmitter
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_request(socket, method, data = {})
|
_sendRequest(socket, method, data = {})
|
||||||
{
|
{
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
{
|
{
|
||||||
|
|
@ -1797,6 +1798,33 @@ class Room extends EventEmitter
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _request(socket, method, data)
|
||||||
|
{
|
||||||
|
logger.debug('_request() [method:"%s", data:"%o"]', method, data);
|
||||||
|
|
||||||
|
const {
|
||||||
|
requestRetries = 3
|
||||||
|
} = config;
|
||||||
|
|
||||||
|
for (let tries = 0; tries < requestRetries; tries++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await this._sendRequest(socket, method, data);
|
||||||
|
}
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
error instanceof SocketTimeoutError &&
|
||||||
|
tries < requestRetries
|
||||||
|
)
|
||||||
|
logger.warn('_request() | timeout, retrying [attempt:"%s"]', tries);
|
||||||
|
else
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
_notification(socket, method, data = {}, broadcast = false, includeSender = false)
|
||||||
{
|
{
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
|
|
@ -1879,7 +1907,7 @@ class Room extends EventEmitter
|
||||||
|
|
||||||
for (const routerId of this._mediasoupRouters.keys())
|
for (const routerId of this._mediasoupRouters.keys())
|
||||||
{
|
{
|
||||||
const routerLoad =
|
const routerLoad =
|
||||||
Object.values(this._peers).filter((peer) => peer.routerId === routerId).length;
|
Object.values(this._peers).filter((peer) => peer.routerId === routerId).length;
|
||||||
|
|
||||||
if (routerLoad < load)
|
if (routerLoad < load)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* Error produced when a socket request has a timeout.
|
||||||
|
*/
|
||||||
|
class SocketTimeoutError extends Error
|
||||||
|
{
|
||||||
|
constructor(message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.name = 'SocketTimeoutError';
|
||||||
|
|
||||||
|
if (Error.hasOwnProperty('captureStackTrace')) // Just in V8.
|
||||||
|
Error.captureStackTrace(this, SocketTimeoutError);
|
||||||
|
else
|
||||||
|
this.stack = (new Error(message)).stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
{
|
||||||
|
SocketTimeoutError
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue