diff --git a/app/public/config/config.example.js b/app/public/config/config.example.js
index 7909284..e07d994 100644
--- a/app/public/config/config.example.js
+++ b/app/public/config/config.example.js
@@ -44,34 +44,47 @@ var config =
},
defaultAudio :
{
- sampleRate : 48000,
- channelCount : 1,
- volume : 1.0,
- autoGainControl : true,
- echoCancellation : true,
- noiseSuppression : true,
- sampleSize : 16
+ sampleRate : 48000,
+ channelCount : 1,
+ volume : 1.0,
+ autoGainControl : true,
+ echoCancellation : true,
+ noiseSuppression : true,
+ voiceActivityMute : false,
+ sampleSize : 16
},
- background : 'images/background.jpg',
- defaultLayout : 'democratic', // democratic, filmstrip
+
+ /**
+ * Set the auto mute / Push To Talk threshold
+ * default value is 4
+ *
+ * Set it to 0 to disable auto mute functionality,
+ * but use it with caution
+ * full mesh audio strongly decrease room capacity!
+ */
+ autoMuteThreshold : 4,
+ background : 'images/background.jpg',
+ defaultLayout : 'democratic', // democratic, filmstrip
// If true, will show media control buttons in separate
// control bar, not in the ME container.
- buttonControlBar : false,
+ buttonControlBar : false,
// If false, will push videos away to make room for side
// drawer. If true, will overlay side drawer over videos
- drawerOverlayed : true,
+ drawerOverlayed : true,
+ // Position of notifications
+ notificationPosition : 'right',
// Timeout for autohiding topbar and button control bar
- hideTimeout : 3000,
- lastN : 4,
- mobileLastN : 1,
+ hideTimeout : 3000,
+ lastN : 4,
+ mobileLastN : 1,
// Highest number of speakers user can select
- maxLastN : 5,
+ maxLastN : 5,
// If truthy, users can NOT change number of speakers visible
- lockLastN : false,
+ lockLastN : false,
// Add file and uncomment for adding logo to appbar
// logo : 'images/logo.svg',
- title : 'Multiparty meeting',
- theme :
+ title : 'Multiparty meeting',
+ theme :
{
palette :
{
diff --git a/app/src/RoomClient.js b/app/src/RoomClient.js
index 3710793..9e5b6ff 100644
--- a/app/src/RoomClient.js
+++ b/app/src/RoomClient.js
@@ -306,6 +306,22 @@ export default class RoomClient
switch (key)
{
+ case String.fromCharCode(37):
+ {
+ const newPeerId = this._spotlights.getPrevAsSelected(
+ store.getState().room.selectedPeerId);
+
+ if (newPeerId) this.setSelectedPeer(newPeerId);
+ break;
+ }
+ case String.fromCharCode(39):
+ {
+ const newPeerId = this._spotlights.getNextAsSelected(
+ store.getState().room.selectedPeerId);
+
+ if (newPeerId) this.setSelectedPeer(newPeerId);
+ break;
+ }
case 'A': // Activate advanced mode
{
store.dispatch(settingsActions.toggleAdvancedMode());
@@ -1025,37 +1041,50 @@ export default class RoomClient
if (!this._harkStream.getAudioTracks()[0])
throw new Error('getMicStream():something went wrong with hark');
- this._hark = hark(this._harkStream, { play: false });
+ this._hark = hark(this._harkStream,
+ {
+ play : false,
+ interval : 5,
+ threshold : store.getState().settings.noiseThreshold,
+ history : 30
+ });
+ this._hark.lastVolume = -100;
- // eslint-disable-next-line no-unused-vars
- this._hark.on('volume_change', (dBs, threshold) =>
+ this._hark.on('volume_change', (volume) =>
{
- // The exact formula to convert from dBs (-100..0) to linear (0..1) is:
- // Math.pow(10, dBs / 20)
- // However it does not produce a visually useful output, so let exagerate
- // it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
- // minimize component renderings.
- let volume = Math.round(Math.pow(10, dBs / 85) * 10);
-
- if (volume === 1)
- volume = 0;
-
volume = Math.round(volume);
-
- if (this._micProducer && volume !== this._micProducer.volume)
+ if (this._micProducer && volume !== Math.round(this._hark.lastVolume))
{
- this._micProducer.volume = volume;
-
+ if (volume < this._hark.lastVolume * 1.02)
+ {
+ volume = this._hark.lastVolume * 1.02;
+ }
+ this._hark.lastVolume = volume;
store.dispatch(peerVolumeActions.setPeerVolume(this._peerId, volume));
}
});
- this._hark.on('speaking', function()
+ this._hark.on('speaking', () =>
{
store.dispatch(meActions.setIsSpeaking(true));
+ if ((store.getState().settings.voiceActivatedUnmute ||
+ store.getState().me.isAutoMuted) &&
+ this._micProducer &&
+ this._micProducer.paused)
+ {
+ this._micProducer.resume();
+ }
+ store.dispatch(meActions.setAutoMuted(false)); // sanity action
});
- this._hark.on('stopped_speaking', function()
+ this._hark.on('stopped_speaking', () =>
{
store.dispatch(meActions.setIsSpeaking(false));
+ if (store.getState().settings.voiceActivatedUnmute &&
+ this._micProducer &&
+ !this._micProducer.paused)
+ {
+ this._micProducer.pause();
+ store.dispatch(meActions.setAutoMuted(true));
+ }
});
}
@@ -1470,6 +1499,26 @@ export default class RoomClient
peerActions.setStopPeerVideoInProgress(peerId, false));
}
+ async stopPeerScreenSharing(peerId)
+ {
+ logger.debug('stopPeerScreenSharing() [peerId:"%s"]', peerId);
+
+ store.dispatch(
+ peerActions.setStopPeerScreenSharingInProgress(peerId, true));
+
+ try
+ {
+ await this.sendRequest('moderator:stopScreenSharing', { peerId });
+ }
+ catch (error)
+ {
+ logger.error('stopPeerScreenSharing() failed: %o', error);
+ }
+
+ store.dispatch(
+ peerActions.setStopPeerScreenSharingInProgress(peerId, false));
+ }
+
async muteAllPeers()
{
logger.debug('muteAllPeers()');
@@ -1510,6 +1559,26 @@ export default class RoomClient
roomActions.setStopAllVideoInProgress(false));
}
+ async stopAllPeerScreenSharing()
+ {
+ logger.debug('stopAllPeerScreenSharing()');
+
+ store.dispatch(
+ roomActions.setStopAllScreenSharingInProgress(true));
+
+ try
+ {
+ await this.sendRequest('moderator:stopAllScreenSharing');
+ }
+ catch (error)
+ {
+ logger.error('stopAllPeerScreenSharing() failed: %o', error);
+ }
+
+ store.dispatch(
+ roomActions.setStopAllScreenSharingInProgress(false));
+ }
+
async closeMeeting()
{
logger.debug('closeMeeting()');
@@ -1944,23 +2013,12 @@ export default class RoomClient
producerPaused
} = request.data;
- let codecOptions;
-
- if (kind === 'audio')
- {
- codecOptions =
- {
- opusStereo : 1
- };
- }
-
const consumer = await this._recvTransport.consume(
{
id,
producerId,
kind,
rtpParameters,
- codecOptions,
appData : { ...appData, peerId } // Trick.
});
@@ -2013,19 +2071,8 @@ export default class RoomClient
consumer.hark = hark(stream, { play: false });
- // eslint-disable-next-line no-unused-vars
- consumer.hark.on('volume_change', (dBs, threshold) =>
+ consumer.hark.on('volume_change', (volume) =>
{
- // The exact formula to convert from dBs (-100..0) to linear (0..1) is:
- // Math.pow(10, dBs / 20)
- // However it does not produce a visually useful output, so let exaggerate
- // it a bit. Also, let convert it from 0..1 to 0..10 and avoid value 1 to
- // minimize component renderings.
- let volume = Math.round(Math.pow(10, dBs / 85) * 10);
-
- if (volume === 1)
- volume = 0;
-
volume = Math.round(volume);
if (consumer && volume !== consumer.volume)
@@ -2631,7 +2678,6 @@ export default class RoomClient
case 'moderator:stopVideo':
{
this.disableWebcam();
- this.disableScreenSharing();
store.dispatch(requestActions.notify(
{
@@ -2644,6 +2690,21 @@ export default class RoomClient
break;
}
+ case 'moderator:stopScreenSharing':
+ {
+ this.disableScreenSharing();
+
+ store.dispatch(requestActions.notify(
+ {
+ text : intl.formatMessage({
+ id : 'moderator.muteScreenSharingModerator',
+ defaultMessage : 'Moderator stopped your screen sharing'
+ })
+ }));
+
+ break;
+ }
+
case 'moderator:kick':
{
// Need some feedback
@@ -2999,7 +3060,9 @@ export default class RoomClient
if (!this._muted)
{
await this.enableMic();
- if (peers.length > 4)
+ const { autoMuteThreshold } = store.getState().settings;
+
+ if (autoMuteThreshold && peers.length > autoMuteThreshold)
this.muteMic();
}
@@ -3645,6 +3708,8 @@ export default class RoomClient
this._screenSharingProducer = null;
+ this._screenSharing.stop();
+
store.dispatch(meActions.setScreenShareInProgress(false));
}
@@ -3853,6 +3918,14 @@ export default class RoomClient
store.dispatch(meActions.setWebcamInProgress(false));
}
+ async _setNoiseThreshold(threshold)
+ {
+ logger.debug('_setNoiseThreshold:%s', threshold);
+ this._hark.setThreshold(threshold);
+ store.dispatch(
+ settingsActions.setNoiseThreshold(threshold));
+ }
+
async _updateAudioDevices()
{
logger.debug('_updateAudioDevices()');
diff --git a/app/src/Spotlights.js b/app/src/Spotlights.js
index 3d0673f..10d6638 100644
--- a/app/src/Spotlights.js
+++ b/app/src/Spotlights.js
@@ -12,6 +12,7 @@ export default class Spotlights extends EventEmitter
this._signalingSocket = signalingSocket;
this._maxSpotlights = maxSpotlights;
this._peerList = [];
+ this._unmutablePeerList = [];
this._selectedSpotlights = [];
this._currentSpotlights = [];
this._started = false;
@@ -45,6 +46,74 @@ export default class Spotlights extends EventEmitter
}
}
+ getNextAsSelected(peerId)
+ {
+ let newSelectedPeer = null;
+
+ if (peerId == null && this._unmutablePeerList.length > 0)
+ {
+ peerId = this._unmutablePeerList[0];
+ }
+
+ if (peerId != null && this._currentSpotlights.length < this._unmutablePeerList.length)
+ {
+ const oldIndex = this._unmutablePeerList.indexOf(peerId);
+
+ let index = oldIndex;
+
+ index++;
+ for (let i = 0; i < this._unmutablePeerList.length; i++)
+ {
+ if (index >= this._unmutablePeerList.length)
+ {
+ index = 0;
+ }
+ newSelectedPeer = this._unmutablePeerList[index];
+ if (!this._currentSpotlights.includes(newSelectedPeer))
+ {
+ break;
+ }
+ index++;
+ }
+ }
+
+ return newSelectedPeer;
+ }
+
+ getPrevAsSelected(peerId)
+ {
+ let newSelectedPeer = null;
+
+ if (peerId == null && this._unmutablePeerList.length > 0)
+ {
+ peerId = this._unmutablePeerList[0];
+ }
+
+ if (peerId != null && this._currentSpotlights.length < this._unmutablePeerList.length)
+ {
+ const oldIndex = this._unmutablePeerList.indexOf(peerId);
+
+ let index = oldIndex;
+
+ index--;
+ for (let i = 0; i < this._unmutablePeerList.length; i++)
+ {
+ if (index < 0)
+ {
+ index = this._unmutablePeerList.length - 1;
+ }
+ newSelectedPeer = this._unmutablePeerList[index];
+ if (!this._currentSpotlights.includes(newSelectedPeer))
+ {
+ break;
+ }
+ index--;
+ }
+ }
+
+ return newSelectedPeer;
+ }
+
setPeerSpotlight(peerId)
{
logger.debug('setPeerSpotlight() [peerId:"%s"]', peerId);
@@ -114,6 +183,7 @@ export default class Spotlights extends EventEmitter
logger.debug('_handlePeer() | adding peer [peerId: "%s"]', id);
this._peerList.push(id);
+ this._unmutablePeerList.push(id);
if (this._started)
this._spotlightsUpdated();
@@ -126,6 +196,7 @@ export default class Spotlights extends EventEmitter
'room "peerClosed" event [peerId:%o]', id);
this._peerList = this._peerList.filter((peer) => peer !== id);
+ this._unmutablePeerList = this._unmutablePeerList.filter((peer) => peer !== id);
this._selectedSpotlights = this._selectedSpotlights.filter((peer) => peer !== id);
diff --git a/app/src/actions/meActions.js b/app/src/actions/meActions.js
index 7fb34ea..be7c1ee 100644
--- a/app/src/actions/meActions.js
+++ b/app/src/actions/meActions.js
@@ -110,3 +110,9 @@ export const setIsSpeaking = (flag) =>
type : 'SET_IS_SPEAKING',
payload : { flag }
});
+
+export const setAutoMuted = (flag) =>
+ ({
+ type : 'SET_AUTO_MUTED',
+ payload : { flag }
+ });
diff --git a/app/src/actions/peerActions.js b/app/src/actions/peerActions.js
index 5672b47..1a1e2d3 100644
--- a/app/src/actions/peerActions.js
+++ b/app/src/actions/peerActions.js
@@ -86,3 +86,9 @@ export const setStopPeerVideoInProgress = (peerId, flag) =>
type : 'STOP_PEER_VIDEO_IN_PROGRESS',
payload : { peerId, flag }
});
+
+export const setStopPeerScreenSharingInProgress = (peerId, flag) =>
+ ({
+ type : 'STOP_PEER_SCREEN_SHARING_IN_PROGRESS',
+ payload : { peerId, flag }
+ });
diff --git a/app/src/actions/roomActions.js b/app/src/actions/roomActions.js
index 5ae45e3..a73e18a 100644
--- a/app/src/actions/roomActions.js
+++ b/app/src/actions/roomActions.js
@@ -164,6 +164,12 @@ export const setStopAllVideoInProgress = (flag) =>
payload : { flag }
});
+export const setStopAllScreenSharingInProgress = (flag) =>
+ ({
+ type : 'STOP_ALL_SCREEN_SHARING_IN_PROGRESS',
+ payload : { flag }
+ });
+
export const setCloseMeetingInProgress = (flag) =>
({
type : 'CLOSE_MEETING_IN_PROGRESS',
diff --git a/app/src/actions/settingsActions.js b/app/src/actions/settingsActions.js
index 21ff2fd..90b019a 100644
--- a/app/src/actions/settingsActions.js
+++ b/app/src/actions/settingsActions.js
@@ -71,6 +71,18 @@ export const setNoiseSuppression = (noiseSuppression) =>
payload : { noiseSuppression }
});
+export const setVoiceActivatedUnmute = (voiceActivatedUnmute) =>
+ ({
+ type: 'SET_VOICE_ACTIVATED_UNMUTE',
+ payload: { voiceActivatedUnmute }
+ });
+
+export const setNoiseThreshold = (noiseThreshold) =>
+ ({
+ type: 'SET_NOISE_THRESHOLD',
+ payload: { noiseThreshold }
+ });
+
export const setDefaultAudio = (audio) =>
({
type : 'SET_DEFAULT_AUDIO',
diff --git a/app/src/components/Containers/Me.js b/app/src/components/Containers/Me.js
index 3438631..5c7bb7a 100644
--- a/app/src/components/Containers/Me.js
+++ b/app/src/components/Containers/Me.js
@@ -137,14 +137,15 @@ const styles = (theme) =>
transform : 'translate(-50%, 0%)',
color : 'rgba(255, 255, 255, 0.7)',
fontSize : '1.3em',
- backgroundColor : 'rgba(255, 0, 0, 0.9)',
+ backgroundColor : 'rgba(245, 0, 87, 0.70)',
margin : '4px',
padding : theme.spacing(2),
- zIndex : 31,
+ zIndex : 1200,
borderRadius : '20px',
textAlign : 'center',
opacity : 0,
transition : 'opacity 1s ease',
+ pointerEvents : 'none',
'&.enabled' :
{
transition : 'opacity 0.1s',
@@ -176,7 +177,9 @@ const Me = (props) =>
extraVideoProducers,
canShareScreen,
classes,
- transports
+ transports,
+ noiseVolume,
+ classes
} = props;
const videoVisible = (
@@ -285,6 +288,25 @@ const Me = (props) =>
defaultMessage : 'Start screen sharing'
});
}
+ const [
+ screenShareTooltipOpen,
+ screenShareTooltipSetOpen
+ ] = React.useState(false);
+
+ const screenShareTooltipHandleClose = () =>
+ {
+ screenShareTooltipSetOpen(false);
+ };
+
+ const screenShareTooltipHandleOpen = () =>
+ {
+ screenShareTooltipSetOpen(true);
+ };
+
+ if (screenState === 'off' && me.screenShareInProgress && screenShareTooltipOpen)
+ {
+ screenShareTooltipHandleClose();
+ }
const spacingStyle =
{
@@ -346,7 +368,7 @@ const Me = (props) =>
style={spacingStyle}
>
- { me.browser.platform !== 'mobile' &&
+ { me.browser.platform !== 'mobile' && smallContainer &&
+ />
}
+ { me.browser.platform !== 'mobile' && !smallContainer &&
+
+
+
+ }
})}
className={classes.smallContainer}
disabled={!me.canSendMic || me.audioInProgress}
- color={micState === 'on' ? 'primary' : 'secondary'}
+ color={
+ micState === 'on' ?
+ settings.voiceActivatedUnmute && !me.isAutoMuted ?
+ 'primary'
+ : 'default'
+ : 'secondary'}
size='small'
onClick={() =>
{
@@ -422,7 +461,10 @@ const Me = (props) =>
}}
>
{ micState === 'on' ?
-
+
:
}
@@ -437,7 +479,10 @@ const Me = (props) =>
})}
className={classes.fab}
disabled={!me.canSendMic || me.audioInProgress}
- color={micState === 'on' ? 'default' : 'secondary'}
+ color={micState === 'on' ?
+ settings.voiceActivatedUnmute && !me.isAutoMuted? 'primary'
+ : 'default'
+ : 'secondary'}
size='large'
onClick={() =>
{
@@ -450,7 +495,11 @@ const Me = (props) =>
}}
>
{ micState === 'on' ?
-
+
:
}
@@ -512,7 +561,11 @@ const Me = (props) =>
}
{ me.browser.platform !== 'mobile' &&
-
+
{ smallContainer ?
const mapStateToProps = (state) =>
{
+ let volume;
+
+ // noiseVolume under threshold
+ if (state.peerVolumes[state.me.id] < state.settings.noiseThreshold)
+ {
+ // noiseVolume mapped to range 0.5 ... 1 (threshold switch)
+ volume = 1 + ((Math.abs(state.peerVolumes[state.me.id] -
+ state.settings.noiseThreshold) / (-120 -
+ state.settings.noiseThreshold)));
+ }
+ // noiseVolume over threshold: no noise but voice
+ else { volume = 0; }
+
return {
me : state.me,
...meProducersSelector(state),
settings : state.settings,
activeSpeaker : state.me.id === state.room.activeSpeakerId,
canShareScreen : hasPermission(state),
- transports : state.transports
+ transports : state.transports,
+ noiseVolume : volume
};
};
@@ -868,6 +936,8 @@ export default withRoomContext(connect(
return (
prev.room === next.room &&
prev.me === next.me &&
+ Math.round(prev.peerVolumes[prev.me.id]) ===
+ Math.round(next.peerVolumes[next.me.id]) &&
prev.peers === next.peers &&
prev.producers === next.producers &&
prev.settings === next.settings,
diff --git a/app/src/components/Containers/Volume.js b/app/src/components/Containers/Volume.js
index 3c13a39..81a050b 100644
--- a/app/src/components/Containers/Volume.js
+++ b/app/src/components/Containers/Volume.js
@@ -94,17 +94,17 @@ const styles = () =>
smallBar :
{
flex : '0 0 auto',
- margin : '0.3rem',
backgroundSize : '75%',
backgroundRepeat : 'no-repeat',
backgroundColor : 'rgba(0, 0, 0, 1)',
cursor : 'pointer',
transitionProperty : 'opacity, background-color',
width : 3,
- borderRadius : 6,
+ borderRadius : 2,
transitionDuration : '0.25s',
position : 'absolute',
- bottom : 0,
+ top : '50%',
+ transform : 'translateY(-50%)',
'&.level0' : { height: 0 },
'&.level1' : { height: '0.2vh' },
'&.level2' : { height: '0.4vh' },
@@ -149,9 +149,16 @@ const makeMapStateToProps = (initialState, props) =>
{
const mapStateToProps = (state) =>
{
- return {
- volume : state.peerVolumes[props.id]
- };
+ if (state.peerVolumes[props.id]>state.settings.noiseThreshold)
+ {
+ return {
+ volume : Math.round((state.peerVolumes[props.id]+100) / 10)
+ };
+ }
+ else
+ {
+ return { volume: 0 };
+ }
};
return mapStateToProps;
diff --git a/app/src/components/Controls/Help.js b/app/src/components/Controls/Help.js
index 98415b5..ab188b8 100644
--- a/app/src/components/Controls/Help.js
+++ b/app/src/components/Controls/Help.js
@@ -23,7 +23,8 @@ const shortcuts=[
{ key: '1', label: 'label.democratic', defaultMessage: 'Democratic View' },
{ key: '2', label: 'label.filmstrip', defaultMessage: 'Filmstrip View' },
{ key: 'space', label: 'me.mutedPTT', defaultMessage: 'Push SPACE to talk' },
- { key: 'a', label: 'label.advanced', defaultMessage: 'Show advanced information' }
+ { key: 'a', label: 'label.advanced', defaultMessage: 'Show advanced information' },
+ { key: `${String.fromCharCode(8592)} ${String.fromCharCode(8594)}`, label: 'room.browsePeersSpotlight', defaultMessage: 'Browse participants into Spotlight' }
];
const styles = (theme) =>
({
diff --git a/app/src/components/Controls/TopBar.js b/app/src/components/Controls/TopBar.js
index bbf408d..148f4a7 100644
--- a/app/src/components/Controls/TopBar.js
+++ b/app/src/components/Controls/TopBar.js
@@ -480,6 +480,34 @@ const TopBar = (props) =>
+ { lobbyPeers.length > 0 &&
+
+
+ setLockDialogOpen(!room.lockDialogOpen)}
+ >
+
+
+
+
+
+
+ }
+
+
);
diff --git a/app/src/components/Notifications/Notifications.js b/app/src/components/Notifications/Notifications.js
index ce2fcee..d5a21c7 100644
--- a/app/src/components/Notifications/Notifications.js
+++ b/app/src/components/Notifications/Notifications.js
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
import { withSnackbar } from 'notistack';
import * as notificationActions from '../../actions/notificationActions';
+const notificationPosition = window.config.notificationPosition || 'right';
+
class Notifications extends Component
{
displayed = [];
@@ -45,7 +47,7 @@ class Notifications extends Component
autoHideDuration : notification.timeout,
anchorOrigin : {
vertical : 'bottom',
- horizontal : 'left'
+ horizontal : notificationPosition
}
}
);
diff --git a/app/src/components/Settings/MediaSettings.js b/app/src/components/Settings/MediaSettings.js
index 28a69a2..d326b91 100644
--- a/app/src/components/Settings/MediaSettings.js
+++ b/app/src/components/Settings/MediaSettings.js
@@ -6,31 +6,66 @@ import { withRoomContext } from '../../RoomContext';
import * as settingsActions from '../../actions/settingsActions';
import PropTypes from 'prop-types';
import { useIntl, FormattedMessage } from 'react-intl';
+import classnames from 'classnames';
import MenuItem from '@material-ui/core/MenuItem';
import FormHelperText from '@material-ui/core/FormHelperText';
import FormControl from '@material-ui/core/FormControl';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import Select from '@material-ui/core/Select';
import Checkbox from '@material-ui/core/Checkbox';
+import Slider from '@material-ui/core/Slider';
+import Typography from '@material-ui/core/Typography';
-const styles = (theme) =>
- ({
- setting :
+const NoiseSlider = withStyles(
+ {
+ root :
{
- padding : theme.spacing(2)
+ color : '#3880ff',
+ height : 2,
+ padding : '15px 0'
},
- formControl :
- {
- display : 'flex'
+ track : {
+ height : 2
+ },
+ rail : {
+ height : 2,
+ opacity : 0.2
+ },
+ mark : {
+ backgroundColor : '#bfbfbf',
+ height : 10,
+ width : 3,
+ marginTop : -3
+ },
+ markActive : {
+ opacity : 1,
+ backgroundColor : 'currentColor'
}
- });
+ })(Slider);
+
+const styles = (theme) => ({
+ setting :
+ {
+ padding : theme.spacing(2)
+ },
+ margin :
+ {
+ height : theme.spacing(3)
+ },
+ formControl :
+ {
+ display : 'flex'
+ }
+});
const MediaSettings = ({
setEchoCancellation,
setAutoGainControl,
setNoiseSuppression,
+ setVoiceActivatedUnmute,
roomClient,
me,
+ volume,
settings,
classes
}) =>
@@ -135,6 +170,34 @@ const MediaSettings = ({
}
+
+
+
+
+
+
}
);
@@ -305,27 +377,31 @@ const MediaSettings = ({
MediaSettings.propTypes =
{
- roomClient : PropTypes.any.isRequired,
- setEchoCancellation : PropTypes.func.isRequired,
- setAutoGainControl : PropTypes.func.isRequired,
- setNoiseSuppression : PropTypes.func.isRequired,
- me : appPropTypes.Me.isRequired,
- settings : PropTypes.object.isRequired,
- classes : PropTypes.object.isRequired
+ roomClient : PropTypes.any.isRequired,
+ setEchoCancellation : PropTypes.func.isRequired,
+ setAutoGainControl : PropTypes.func.isRequired,
+ setNoiseSuppression : PropTypes.func.isRequired,
+ setVoiceActivatedUnmute : PropTypes.func.isRequired,
+ me : appPropTypes.Me.isRequired,
+ volume : PropTypes.number,
+ settings : PropTypes.object.isRequired,
+ classes : PropTypes.object.isRequired
};
const mapStateToProps = (state) =>
{
return {
me : state.me,
+ volume : state.peerVolumes[state.me.id],
settings : state.settings
};
};
const mapDispatchToProps = {
- setEchoCancellation : settingsActions.setEchoCancellation,
- setAutoGainControl : settingsActions.toggleAutoGainControl,
- setNoiseSuppression : settingsActions.toggleNoiseSuppression
+ setEchoCancellation : settingsActions.setEchoCancellation,
+ setAutoGainControl : settingsActions.toggleAutoGainControl,
+ setNoiseSuppression : settingsActions.toggleNoiseSuppression,
+ setVoiceActivatedUnmute : settingsActions.setVoiceActivatedUnmute
};
export default withRoomContext(connect(
@@ -337,7 +413,8 @@ export default withRoomContext(connect(
{
return (
prev.me === next.me &&
- prev.settings === next.settings
+ prev.settings === next.settings &&
+ prev.peerVolumes[prev.me.id] === next[next.me.id]
);
}
}
diff --git a/app/src/components/Settings/Settings.js b/app/src/components/Settings/Settings.js
index 6633829..cbfb8b1 100644
--- a/app/src/components/Settings/Settings.js
+++ b/app/src/components/Settings/Settings.js
@@ -95,7 +95,7 @@ const Settings = ({
/>
diff --git a/app/src/index.js b/app/src/index.js
index e89d06d..c5f333d 100644
--- a/app/src/index.js
+++ b/app/src/index.js
@@ -31,7 +31,8 @@ import messagesFrench from './translations/fr';
import messagesGreek from './translations/el';
import messagesRomanian from './translations/ro';
import messagesPortuguese from './translations/pt';
-import messagesChinese from './translations/cn';
+import messagesChineseSimplified from './translations/cn';
+import messagesChineseTraditional from './translations/tw';
import messagesSpanish from './translations/es';
import messagesCroatian from './translations/hr';
import messagesCzech from './translations/cs';
@@ -49,26 +50,37 @@ const cache = createIntlCache();
const messages =
{
// 'en' : messagesEnglish,
- 'nb' : messagesNorwegian,
- 'de' : messagesGerman,
- 'hu' : messagesHungarian,
- 'pl' : messagesPolish,
- 'dk' : messagesDanish,
- 'fr' : messagesFrench,
- 'el' : messagesGreek,
- 'ro' : messagesRomanian,
- 'pt' : messagesPortuguese,
- 'zh' : messagesChinese,
- 'es' : messagesSpanish,
- 'hr' : messagesCroatian,
- 'cs' : messagesCzech,
- 'it' : messagesItalian,
- 'uk' : messagesUkrainian,
- 'tr' : messagesTurkish,
- 'lv' : messagesLatvian
+ 'nb' : messagesNorwegian,
+ 'de' : messagesGerman,
+ 'hu' : messagesHungarian,
+ 'pl' : messagesPolish,
+ 'dk' : messagesDanish,
+ 'fr' : messagesFrench,
+ 'el' : messagesGreek,
+ 'ro' : messagesRomanian,
+ 'pt' : messagesPortuguese,
+ 'zh-hans' : messagesChineseSimplified,
+ 'zh-hant' : messagesChineseTraditional,
+ 'es' : messagesSpanish,
+ 'hr' : messagesCroatian,
+ 'cs' : messagesCzech,
+ 'it' : messagesItalian,
+ 'uk' : messagesUkrainian,
+ 'tr' : messagesTurkish,
+ 'lv' : messagesLatvian
};
-const locale = navigator.language.split(/[-_]/)[0]; // language without region code
+const browserLanguage = (navigator.language || navigator.browserLanguage).toLowerCase();
+
+let locale = browserLanguage.split(/[-_]/)[0]; // language without region code
+
+if (locale === 'zh')
+{
+ if (browserLanguage === 'zh-cn')
+ locale = 'zh-hans';
+ else
+ locale = 'zh-hant';
+}
const intl = createIntl({
locale,
diff --git a/app/src/reducers/me.js b/app/src/reducers/me.js
index f3fff66..35336a6 100644
--- a/app/src/reducers/me.js
+++ b/app/src/reducers/me.js
@@ -18,7 +18,8 @@ const initialState =
raisedHand : false,
raisedHandInProgress : false,
loggedIn : false,
- isSpeaking : false
+ isSpeaking : false,
+ isAutoMuted : true
};
const me = (state = initialState, action) =>
@@ -162,6 +163,13 @@ const me = (state = initialState, action) =>
return { ...state, isSpeaking: flag };
}
+ case 'SET_AUTO_MUTED':
+ {
+ const { flag } = action.payload;
+
+ return { ...state, isAutoMuted: flag };
+ }
+
default:
return state;
}
diff --git a/app/src/reducers/peerVolumes.js b/app/src/reducers/peerVolumes.js
index fafe739..826a038 100644
--- a/app/src/reducers/peerVolumes.js
+++ b/app/src/reducers/peerVolumes.js
@@ -31,9 +31,10 @@ const peerVolumes = (state = initialState, action) =>
case 'SET_PEER_VOLUME':
{
- const { peerId, volume } = action.payload;
+ const { peerId } = action.payload;
+ const dBs = action.payload.volume < -100 ? -100 : action.payload.volume;
- return { ...state, [peerId]: volume };
+ return { ...state, [peerId]: Math.round(dBs) };
}
default:
diff --git a/app/src/reducers/peers.js b/app/src/reducers/peers.js
index 32d6fef..8e6a7f7 100644
--- a/app/src/reducers/peers.js
+++ b/app/src/reducers/peers.js
@@ -82,6 +82,11 @@ const peer = (state = initialState, action) =>
stopPeerVideoInProgress : action.payload.flag
};
+ case 'STOP_PEER_SCREEN_SHARING_IN_PROGRESS':
+ return {
+ ...state,
+ stopPeerScreenSharingInProgress : action.payload.flag
+ };
default:
return state;
}
@@ -118,6 +123,7 @@ const peers = (state = initialState, action) =>
case 'REMOVE_PEER_ROLE':
case 'STOP_PEER_AUDIO_IN_PROGRESS':
case 'STOP_PEER_VIDEO_IN_PROGRESS':
+ case 'STOP_PEER_SCREEN_SHARING_IN_PROGRESS':
{
const oldPeer = state[action.payload.peerId];
diff --git a/app/src/reducers/room.js b/app/src/reducers/room.js
index d784219..193e8e0 100644
--- a/app/src/reducers/room.js
+++ b/app/src/reducers/room.js
@@ -226,6 +226,9 @@ const room = (state = initialState, action) =>
case 'STOP_ALL_VIDEO_IN_PROGRESS':
return { ...state, stopAllVideoInProgress: action.payload.flag };
+ case 'STOP_ALL_SCREEN_SHARING_IN_PROGRESS':
+ return { ...state, stopAllScreenSharingInProgress: action.payload.flag };
+
case 'CLOSE_MEETING_IN_PROGRESS':
return { ...state, closeMeetingInProgress: action.payload.flag };
diff --git a/app/src/reducers/settings.js b/app/src/reducers/settings.js
index 1c375bf..750df24 100644
--- a/app/src/reducers/settings.js
+++ b/app/src/reducers/settings.js
@@ -1,25 +1,28 @@
const initialState =
{
- displayName : 'Guest',
- selectedWebcam : null,
- selectedAudioDevice : null,
- advancedMode : false,
- sampleRate : 48000,
- channelCount : 1,
- volume : 1.0,
- autoGainControl : true,
- echoCancellation : true,
- noiseSuppression : true,
- sampleSize : 16,
+ displayName : 'Guest',
+ selectedWebcam : null,
+ selectedAudioDevice : null,
+ advancedMode : false,
+ sampleRate : 48000,
+ channelCount : 1,
+ volume : 1.0,
+ autoGainControl : false,
+ echoCancellation : true,
+ noiseSuppression : true,
+ voiceActivatedUnmute : false,
+ noiseThreshold : -50,
+ sampleSize : 16,
// low, medium, high, veryhigh, ultra
- resolution : window.config.defaultResolution || 'medium',
- lastN : 4,
- permanentTopBar : true,
- hiddenControls : false,
- showNotifications : true,
- notificationSounds : true,
- buttonControlBar : window.config.buttonControlBar || false,
- drawerOverlayed : window.config.drawerOverlayed || true,
+ resolution : window.config.defaultResolution || 'medium',
+ lastN : 4,
+ permanentTopBar : true,
+ hiddenControls : false,
+ showNotifications : true,
+ notificationSounds : true,
+ buttonControlBar : window.config.buttonControlBar || false,
+ drawerOverlayed : window.config.drawerOverlayed || true,
+ autoMuteThreshold : window.config.autoMuteThreshold || 4,
...window.config.defaultAudio
};
@@ -98,6 +101,20 @@ const settings = (state = initialState, action) =>
return { ...state, noiseSuppression };
}
+ case 'SET_VOICE_ACTIVATED_UNMUTE':
+ {
+ const { voiceActivatedUnmute } = action.payload;
+
+ return { ...state, voiceActivatedUnmute };
+ }
+
+ case 'SET_NOISE_THRESHOLD':
+ {
+ const { noiseThreshold } = action.payload;
+
+ return { ...state, noiseThreshold };
+ }
+
case 'SET_DEFAULT_AUDIO':
{
const { audio } = action.payload;
diff --git a/app/src/translations/cn.json b/app/src/translations/cn.json
index 0ce5f5b..c5f79e4 100644
--- a/app/src/translations/cn.json
+++ b/app/src/translations/cn.json
@@ -63,6 +63,7 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
"me.mutedPTT": null,
@@ -84,6 +85,10 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
+ "room.stopAllScreenSharing": null,
"label.roomName": "房间名称",
"label.chooseRoomButton": "继续",
@@ -109,7 +114,7 @@
"label.ultra": "超高 (UHD)",
"label.close": "关闭",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
\ No newline at end of file
diff --git a/app/src/translations/cs.json b/app/src/translations/cs.json
index 3eac16c..c1ea569 100644
--- a/app/src/translations/cs.json
+++ b/app/src/translations/cs.json
@@ -62,6 +62,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -83,6 +85,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Jméno místnosti",
"label.chooseRoomButton": "Pokračovat",
@@ -108,7 +113,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Zavřít",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -182,5 +187,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
-}
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
+}
\ No newline at end of file
diff --git a/app/src/translations/de.json b/app/src/translations/de.json
index c4b67fe..9339d4f 100644
--- a/app/src/translations/de.json
+++ b/app/src/translations/de.json
@@ -51,7 +51,7 @@
"room.videoPaused": "Video gestoppt",
"room.muteAll": "Alle stummschalten",
"room.stopAllVideo": "Alle Videos stoppen",
- "room.closeMeeting": "Meeting schließen",
+ "room.closeMeeting": "Meeting beenden",
"room.clearChat": "Liste löschen",
"room.clearFileSharing": "Liste löschen",
"room.speechUnsupported": "Dein Browser unterstützt keine Spracherkennung",
@@ -61,10 +61,12 @@
"room.extraVideo": "Video hinzufügen",
"room.overRoomLimit": "Der Raum ist voll, probiere es später nochmal",
"room.help": "Hilfe",
- "room.about": "Impressum",
+ "room.about": "Über",
"room.shortcutKeys": "Tastaturkürzel",
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
- "me.mutedPTT": "Du bist stummgeschalted, Halte die SPACE-Taste um zu sprechen",
+ "me.mutedPTT": "Du bist stummgeschaltet. Halte die SPACE-Taste um zu sprechen",
"roles.gotRole": "Rolle erhalten: {role}",
"roles.lostRole": "Rolle entzogen: {role}",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Video stoppen",
"tooltip.raisedHand": "Hand heben",
"tooltip.muteScreenSharing": "Stoppe Bildschirmfreigabe",
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Name des Raums",
"label.chooseRoomButton": "Weiter",
@@ -103,16 +108,16 @@
"label.democratic": "Demokratisch",
"label.filmstrip": "Filmstreifen",
"label.low": "Niedrig",
- "label.medium": "Medium",
+ "label.medium": "Mittel",
"label.high": "Hoch (HD)",
"label.veryHigh": "Sehr hoch (FHD)",
"label.ultra": "Ultra (UHD)",
"label.close": "Schließen",
"label.media": "Audio / Video",
- "label.appearence": "Erscheinung",
- "label.advanced": "Erweiter",
+ "label.appearance": "Ansicht",
+ "label.advanced": "Erweitert",
"label.addVideo": "Video hinzufügen",
- "label.promoteAllPeers": "Alle Teinehmer einlassen",
+ "label.promoteAllPeers": "Alle Teilnehmer reinlassen",
"label.moreActions": "Weitere Aktionen",
"settings.settings": "Einstellungen",
@@ -134,7 +139,7 @@
"settings.hiddenControls": "Medienwerkzeugleiste automatisch ausblenden",
"settings.notificationSounds": "Audiosignal bei Benachrichtigungen",
"settings.showNotifications": "Zeige Benachrichtigungen",
- "settings.buttonControlBar": "Seperate seitliche Medienwerkzeugleiste",
+ "settings.buttonControlBar": "Separate seitliche Medienwerkzeugleiste",
"settings.echoCancellation": "Echounterdrückung",
"settings.autoGainControl": "Automatische Pegelregelung (Audioeingang)",
"settings.noiseSuppression": "Rauschunterdrückung",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Moderator hat Chat gelöscht",
"moderator.clearFiles": "Moderator hat geteilte Dateiliste gelöscht",
"moderator.muteAudio": "Moderator hat dich stummgeschaltet",
- "moderator.muteVideo": "Moderator hat dein Video gestoppt"
+ "moderator.muteVideo": "Moderator hat dein Video gestoppt",
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/dk.json b/app/src/translations/dk.json
index c5c3a2d..edeb619 100644
--- a/app/src/translations/dk.json
+++ b/app/src/translations/dk.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Værelsesnavn",
"label.chooseRoomButton": "Fortsæt",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Luk",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/el.json b/app/src/translations/el.json
index d71764f..6807831 100644
--- a/app/src/translations/el.json
+++ b/app/src/translations/el.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Όνομα δωματίου",
"label.chooseRoomButton": "Συνέχεια",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Κλείσιμο",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
\ No newline at end of file
diff --git a/app/src/translations/en.json b/app/src/translations/en.json
index 344d660..30c21d7 100644
--- a/app/src/translations/en.json
+++ b/app/src/translations/en.json
@@ -63,6 +63,8 @@
"room.help": "Help",
"room.about": "About",
"room.shortcutKeys": "Shortcut Keys",
+ "room.browsePeersSpotlight": "Browse participants into Spotlight",
+ "room.stopAllScreenSharing": "Stop all screen sharing",
"me.mutedPTT": "You are muted, hold down SPACE-BAR to talk",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Mute participant video",
"tooltip.raisedHand": "Raise hand",
"tooltip.muteScreenSharing": "Mute participant share",
+ "tooltip.muteParticipantAudioModerator": "Mute participant audio globally",
+ "tooltip.muteParticipantVideoModerator": "Mute participant video globally",
+ "tooltip.muteScreenSharingModerator": "Mute participant screen share globally",
"label.roomName": "Room name",
"label.chooseRoomButton": "Continue",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Close",
"label.media": "Media",
- "label.appearence": "Appearence",
+ "label.appearance": "Appearence",
"label.advanced": "Advanced",
"label.addVideo": "Add video",
"label.promoteAllPeers": "Promote all",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Moderator cleared the chat",
"moderator.clearFiles": "Moderator cleared the files",
"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"
}
\ No newline at end of file
diff --git a/app/src/translations/es.json b/app/src/translations/es.json
index 758b0c8..4e0c12a 100644
--- a/app/src/translations/es.json
+++ b/app/src/translations/es.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Nombre de la sala",
"label.chooseRoomButton": "Continuar",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Cerrar",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/fr.json b/app/src/translations/fr.json
index 2eb7edf..0f2ac0b 100644
--- a/app/src/translations/fr.json
+++ b/app/src/translations/fr.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Nom de la salle",
"label.chooseRoomButton": "Continuer",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra Haute Définition",
"label.close": "Fermer",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -182,5 +187,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/hr.json b/app/src/translations/hr.json
index c0f8879..59873d4 100644
--- a/app/src/translations/hr.json
+++ b/app/src/translations/hr.json
@@ -46,7 +46,7 @@
"room.lobbyEmpty": "Trenutno nema nikoga u predvorju",
"room.hiddenPeers": "{hiddenPeersCount, plural, one {participant} other {participants}}",
"room.me": "Ja",
- "room.spotlights": "Sudionici u fokusu",
+ "room.spotlights": "Sudionici u središtu pažnje",
"room.passive": "Pasivni sudionici",
"room.videoPaused": "Video pauziran",
"room.muteAll": "Utišaj sve",
@@ -60,9 +60,11 @@
"room.loweredHand": "{displayName} je spustio ruku",
"room.extraVideo": "Dodatni video",
"room.overRoomLimit": "Soba je popunjena, pokušajte ponovno kasnije.",
- "room.help": null,
- "room.about": null,
- "room.shortcutKeys": null,
+ "room.help": "Pomoć",
+ "room.about": "O programu",
+ "room.shortcutKeys": "Prečaci",
+ "room.browsePeersSpotlight": "Pretražite sudionike u središtu pažnje",
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": "Utišani ste, pritisnite i držite SPACE tipku za razgovor",
@@ -81,9 +83,12 @@
"tooltip.participants": "Prikaži sudionike",
"tooltip.kickParticipant": "Izbaci sudionika",
"tooltip.muteParticipant": "Utišaj sudionika",
- "tooltip.muteParticipantVideo": "Ne primaj video sudionika",
+ "tooltip.muteParticipantVideo": "Ne prikazuj video sudionika",
"tooltip.raisedHand": "Podigni ruku",
- "tooltip.muteScreenSharing": null,
+ "tooltip.muteScreenSharing": "Ne prikazuj dijeljenje ekrana sudionika",
+ "tooltip.muteParticipantAudioModerator": "Utišaj sve sudionike",
+ "tooltip.muteParticipantVideoModerator": "Ne prikazuj video svih sudionika",
+ "tooltip.muteScreenSharingModerator": "Ne prikazuj dijeljenje ekrana svih sudionika",
"label.roomName": "Naziv sobe",
"label.chooseRoomButton": "Nastavi",
@@ -109,11 +114,11 @@
"label.ultra": "Ultra visoka (UHD)",
"label.close": "Zatvori",
"label.media": "Medij",
- "label.appearence": "Prikaz",
+ "label.appearance": "Prikaz",
"label.advanced": "Napredno",
"label.addVideo": "Dodaj video",
"label.promoteAllPeers": "Promoviraj sve",
- "label.moreActions": null,
+ "label.moreActions": "Više akcija",
"settings.settings": "Postavke",
"settings.camera": "Kamera",
@@ -133,12 +138,12 @@
"settings.lastn": "Broj vidljivih videozapisa",
"settings.hiddenControls": "Skrivene kontrole medija",
"settings.notificationSounds": "Zvuk obavijesti",
- "settings.showNotifications": null,
- "settings.buttonControlBar": null,
- "settings.echoCancellation": null,
- "settings.autoGainControl": null,
- "settings.noiseSuppression": null,
- "settings.drawerOverlayed": null,
+ "settings.showNotifications": "Prikaži obavijesti",
+ "settings.buttonControlBar": "Razdvoji upravljanje medijima",
+ "settings.echoCancellation": "Poništavanje jeke",
+ "settings.autoGainControl": "Automatsko upravljanje jačinom zvuka",
+ "settings.noiseSuppression": "Poništavanje šuma",
+ "settings.drawerOverlayed": "Bočni izbornik iznad sadržaja",
"filesharing.saveFileError": "Nije moguće spremiti datoteku",
"filesharing.startingFileShare": "Pokušaj dijeljenja datoteke",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Moderator je izbrisao razgovor",
"moderator.clearFiles": "Moderator je izbrisao datoteke",
"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
}
diff --git a/app/src/translations/hu.json b/app/src/translations/hu.json
index cf65f1d..1a2832b 100644
--- a/app/src/translations/hu.json
+++ b/app/src/translations/hu.json
@@ -49,8 +49,8 @@
"room.spotlights": "Látható résztvevők",
"room.passive": "Passzív résztvevők",
"room.videoPaused": "Ez a videóstream szünetel",
- "room.muteAll": "Mindenki némítása",
- "room.stopAllVideo": "Mindenki video némítása",
+ "room.muteAll": "Összes némítása",
+ "room.stopAllVideo": "Összes video némítása",
"room.closeMeeting": "Konferencia lebontása",
"room.clearChat": "Chat történelem kiürítése",
"room.clearFileSharing": "File megosztás kiürítése",
@@ -63,6 +63,8 @@
"room.help": "Segítség",
"room.about": "Névjegy",
"room.shortcutKeys": "Billentyűparancsok",
+ "room.browsePeersSpotlight": "Résztvevők böngészése",
+ "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",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Résztvevő videóstreamének némítása",
"tooltip.raisedHand": "Jelentkezés",
"tooltip.muteScreenSharing": "Képernyőmegosztás szüneteltetése",
+ "tooltip.muteParticipantAudioModerator": "Résztvevő hangjának általános némítása",
+ "tooltip.muteParticipantVideoModerator": "Résztvevő videójának általános némítása",
+ "tooltip.muteScreenSharingModerator": "Résztvevő képernyőmegosztásának általános némítása",
"label.roomName": "Konferencia",
"label.chooseRoomButton": "Tovább",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra magas (UHD)",
"label.close": "Bezár",
"label.media": "Média",
- "label.appearence": "Megjelenés",
+ "label.appearance": "Megjelenés",
"label.advanced": "Részletek",
"label.addVideo": "Videó hozzáadása",
"label.promoteAllPeers": "Mindenkit beengedek",
@@ -138,7 +143,7 @@
"settings.echoCancellation": "Visszhangelnyomás",
"settings.autoGainControl": "Automatikus hangerő",
"settings.noiseSuppression": "Zajelnyomás",
- "settings.drawerOverlayed": null,
+ "settings.drawerOverlayed": "Oldalsáv a tartalom felett",
"filesharing.saveFileError": "A file-t nem sikerült elmenteni",
"filesharing.startingFileShare": "Fájl megosztása",
@@ -183,5 +188,6 @@
"moderator.clearChat": "A moderátor kiürítette a chat 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.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"
}
diff --git a/app/src/translations/it.json b/app/src/translations/it.json
index 312a2ff..02b53e7 100644
--- a/app/src/translations/it.json
+++ b/app/src/translations/it.json
@@ -63,7 +63,9 @@
"room.help": "Aiuto",
"room.about": "Informazioni su",
"room.shortcutKeys": "Scorciatoie da tastiera",
-
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
+
"me.mutedPTT": "Sei mutato, tieni premuto SPAZIO per parlare",
"roles.gotRole": "Hai ottenuto il ruolo: {role}",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Ferma video partecipante",
"tooltip.raisedHand": "Mano alzata",
"tooltip.muteScreenSharing": "Ferma condivisione schermo partecipante",
+ "tooltip.muteParticipantAudioModerator": "Sospendi audio globale",
+ "tooltip.muteParticipantVideoModerator": "Sospendi video globale",
+ "tooltip.muteScreenSharingModerator": "Sospendi condivisione schermo globale",
"label.roomName": "Nome della stanza",
"label.chooseRoomButton": "Continua",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Chiudi",
"label.media": "Media",
- "label.appearence": "Aspetto",
+ "label.appearance": "Aspetto",
"label.advanced": "Avanzate",
"label.addVideo": "Aggiungi video",
"label.promoteAllPeers": "Promuovi tutti",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Il moderatore ha pulito la chat",
"moderator.clearFiles": "Il moderatore ha pulito i file",
"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
}
\ No newline at end of file
diff --git a/app/src/translations/lv.json b/app/src/translations/lv.json
index 7bf0b24..62ee61e 100644
--- a/app/src/translations/lv.json
+++ b/app/src/translations/lv.json
@@ -62,6 +62,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": "Jūs esat noklusināts. Turiet taustiņu SPACE-BAR, lai runātu",
@@ -83,6 +85,9 @@
"tooltip.muteParticipantVideo": "Atslēgt dalībnieka video",
"tooltip.raisedHand": "Pacelt roku",
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Sapulces telpas nosaukums (ID)",
"label.chooseRoomButton": "Turpināt",
@@ -107,7 +112,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Aizvērt",
"label.media": "Mediji",
- "label.appearence": "Izskats",
+ "label.appearance": "Izskats",
"label.advanced": "Advancēts",
"label.addVideo": "Pievienot video",
"label.moreActions": null,
@@ -177,5 +182,6 @@
"moderator.clearChat": "Moderators nodzēsa tērziņus",
"moderator.clearFiles": "Moderators notīrīja failus",
"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
}
diff --git a/app/src/translations/nb.json b/app/src/translations/nb.json
index 251858b..5bafeb6 100644
--- a/app/src/translations/nb.json
+++ b/app/src/translations/nb.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": "Du er dempet, hold nede SPACE for å snakke",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Demp deltakervideo",
"tooltip.raisedHand": "Rekk opp hånden",
"tooltip.muteScreenSharing": "Demp deltaker skjermdeling",
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Møtenavn",
"label.chooseRoomButton": "Fortsett",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Lukk",
"label.media": "Media",
- "label.appearence": "Utseende",
+ "label.appearance": "Utseende",
"label.advanced": "Avansert",
"label.addVideo": "Legg til video",
"label.promoteAllPeers": "Slipp inn alle",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Moderator tømte chatten",
"moderator.clearFiles": "Moderator fjernet filer",
"moderator.muteAudio": "Moderator mutet lyden din",
- "moderator.muteVideo": "Moderator mutet videoen din"
+ "moderator.muteVideo": "Moderator mutet videoen din",
+ "moderator.muteScreenSharing": null
}
\ No newline at end of file
diff --git a/app/src/translations/pl.json b/app/src/translations/pl.json
index 174684c..7612f99 100644
--- a/app/src/translations/pl.json
+++ b/app/src/translations/pl.json
@@ -63,6 +63,8 @@
"room.help": "Pomoc",
"room.about": "O pogramie",
"room.shortcutKeys": "Skróty klawiaturowe",
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": "Masz wyciszony mikrofon, przytrzymaj spację aby mówić",
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": "Wyłącz wideo użytkownika",
"tooltip.raisedHand": "Podnieś rękę",
"tooltip.muteScreenSharing": "Anuluj udostępniania pulpitu przez użytkownika",
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Nazwa konferencji",
"label.chooseRoomButton": "Kontynuuj",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Zamknij",
"label.media": "Media",
- "label.appearence": "Wygląd",
+ "label.appearance": "Wygląd",
"label.advanced": "Zaawansowane",
"label.addVideo": "Dodaj wideo",
"label.promoteAllPeers": "Wpuść wszystkich",
@@ -183,5 +188,6 @@
"moderator.clearChat": "Moderator wyczyścił chat",
"moderator.clearFiles": "Moderator wyczyścił pliki",
"moderator.muteAudio": "Moderator wyciszył audio",
- "moderator.muteVideo": "Moderator wyciszył twoje video"
+ "moderator.muteVideo": "Moderator wyciszył twoje video",
+ "moderator.muteScreenSharing": null
}
\ No newline at end of file
diff --git a/app/src/translations/pt.json b/app/src/translations/pt.json
index 8250231..a2a3310 100644
--- a/app/src/translations/pt.json
+++ b/app/src/translations/pt.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Nome da sala",
"label.chooseRoomButton": "Continuar",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Fechar",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/ro.json b/app/src/translations/ro.json
index 1ba455c..7161bd4 100644
--- a/app/src/translations/ro.json
+++ b/app/src/translations/ro.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Numele camerei",
"label.chooseRoomButton": "Continuare",
@@ -109,7 +114,7 @@
"label.ultra": "Rezoluție ultra înaltă (UHD)",
"label.close": "Închide",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
}
diff --git a/app/src/translations/tr.json b/app/src/translations/tr.json
index 524c557..1876bab 100644
--- a/app/src/translations/tr.json
+++ b/app/src/translations/tr.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Oda adı",
"label.chooseRoomButton": "Devam",
@@ -109,7 +114,7 @@
"label.ultra": "Ultra (UHD)",
"label.close": "Kapat",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -175,5 +180,6 @@
"devices.screenSharingError": "Ekranınıza erişilirken bir hata oluştu",
"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
}
diff --git a/app/src/translations/tw.json b/app/src/translations/tw.json
new file mode 100644
index 0000000..99c32d7
--- /dev/null
+++ b/app/src/translations/tw.json
@@ -0,0 +1,192 @@
+{
+ "socket.disconnected": "您已斷開連接",
+ "socket.reconnecting": "嘗試重新連接",
+ "socket.reconnected": "您已重新連接",
+ "socket.requestError": "服務器請求錯誤",
+
+ "room.chooseRoom": "選擇您要加入的房間的名稱",
+ "room.cookieConsent": "這個網站使用Cookies來提升您的使用者體驗",
+ "room.consentUnderstand": "了解",
+ "room.joined": "您已加入房間",
+ "room.cantJoin": "無法加入房間",
+ "room.youLocked": "您已鎖定房間",
+ "room.cantLock": "無法鎖定房間",
+ "room.youUnLocked": "您解鎖了房間",
+ "room.cantUnLock": "無法解鎖房間",
+ "room.locked": "房間已鎖定",
+ "room.unlocked": "房間現已解鎖",
+ "room.newLobbyPeer": "新參與者進入大廳",
+ "room.lobbyPeerLeft": "參與者離開大廳",
+ "room.lobbyPeerChangedDisplayName": "大廳的參與者將名稱變更為 {displayName}",
+ "room.lobbyPeerChangedPicture": "大廳的參與者變更了圖片",
+ "room.setAccessCode": "設置房間的進入密碼",
+ "room.accessCodeOn": "房間的進入密碼現已啟用",
+ "room.accessCodeOff": "房間的進入密碼已停用",
+ "room.peerChangedDisplayName": "{oldDisplayName} 已變更名稱為 {displayName}",
+ "room.newPeer": "{displayName} 加入了會議室",
+ "room.newFile": "有新文件",
+ "room.toggleAdvancedMode": "切換進階模式",
+ "room.setDemocraticView": "已更改為使用者佈局",
+ "room.setFilmStripView": "已更改為投影片佈局",
+ "room.loggedIn": "您已登入",
+ "room.loggedOut": "您已登出",
+ "room.changedDisplayName": "您的顯示名稱已變更為 {displayName}",
+ "room.changeDisplayNameError": "更改顯示名稱時發生錯誤",
+ "room.chatError": "無法發送聊天消息",
+ "room.aboutToJoin": "您即將參加會議",
+ "room.roomId": "房間ID: {roomName}",
+ "room.setYourName": "設置您的顯示名稱,並選擇您想加入的方式:",
+ "room.audioOnly": "僅通話",
+ "room.audioVideo": "通話和視訊",
+ "room.youAreReady": "準備完畢!",
+ "room.emptyRequireLogin": "房間是空的! 您可以登錄以開始會議或等待主持人加入",
+ "room.locketWait": "房間已鎖定! 請等待其他人允許您進入...",
+ "room.lobbyAdministration": "大廳管理",
+ "room.peersInLobby": "大廳的參與者",
+ "room.lobbyEmpty": "大廳目前沒有人",
+ "room.hiddenPeers": "{hiddenPeersCount, plural, one {participant} other {participants}}",
+ "room.me": "我",
+ "room.spotlights": "Spotlight中的參與者",
+ "room.passive": "被動參與者",
+ "room.videoPaused": "視訊已關閉",
+ "room.muteAll": "全部靜音",
+ "room.stopAllVideo": "關閉全部視訊",
+ "room.closeMeeting": "關閉會議",
+ "room.clearChat": "清除聊天",
+ "room.clearFileSharing": "清除檔案",
+ "room.speechUnsupported": "您的瀏覽器不支援語音辨識",
+ "room.moderatoractions": "管理員動作",
+ "room.raisedHand": "{displayName} 舉手了",
+ "room.loweredHand": "{displayName} 放下了他的手",
+ "room.extraVideo": "其他視訊",
+ "room.overRoomLimit": "房間已滿,請稍後重試",
+ "room.help": "幫助",
+ "room.about": "關於",
+ "room.shortcutKeys": "鍵盤快速鍵",
+ "room.stopAllScreenSharing": null,
+
+ "me.mutedPTT": "您已靜音,請按下 空白鍵 來說話",
+
+ "roles.gotRole": "您已取得身份: {role}",
+ "roles.lostRole": "您的 {role} 身份已被撤銷",
+
+ "tooltip.login": "登入",
+ "tooltip.logout": "登出",
+ "tooltip.admitFromLobby": "從大廳允許",
+ "tooltip.lockRoom": "鎖定房間",
+ "tooltip.unLockRoom": "解鎖房間",
+ "tooltip.enterFullscreen": "進入全螢幕",
+ "tooltip.leaveFullscreen": "退出全螢幕",
+ "tooltip.lobby": "顯示大廳",
+ "tooltip.settings": "顯示設置",
+ "tooltip.participants": "顯示參加者",
+ "tooltip.kickParticipant": "踢出",
+ "tooltip.muteParticipant": "靜音",
+ "tooltip.muteParticipantVideo": "隱藏視訊",
+ "tooltip.raisedHand": "舉手",
+ "tooltip.muteScreenSharing": "隱藏螢幕分享",
+ "tooltip.muteParticipantAudioModerator": "關閉聲音",
+ "tooltip.muteParticipantVideoModerator": "關閉視訊",
+ "tooltip.muteScreenSharingModerator": "關閉螢幕分享",
+
+ "label.roomName": "房間名稱",
+ "label.chooseRoomButton": "繼續",
+ "label.yourName": "您的名字",
+ "label.newWindow": "新視窗",
+ "label.fullscreen": "全螢幕",
+ "label.openDrawer": "打開側邊欄",
+ "label.leave": "離開",
+ "label.chatInput": "輸入聊天訊息",
+ "label.chat": "聊天",
+ "label.filesharing": "文件分享",
+ "label.participants": "參與者",
+ "label.shareFile": "分享文件",
+ "label.shareGalleryFile": "分享圖片",
+ "label.fileSharingUnsupported": "不支援文件分享",
+ "label.unknown": "未知",
+ "label.democratic": "使用者佈局",
+ "label.filmstrip": "投影片佈局",
+ "label.low": "低",
+ "label.medium": "中",
+ "label.high": "高 (HD)",
+ "label.veryHigh": "非常高 (FHD)",
+ "label.ultra": "超高 (UHD)",
+ "label.close": "關閉",
+ "label.media": "媒體",
+ "label.appearance": "外觀",
+ "label.advanced": "進階",
+ "label.addVideo": "新增視訊",
+ "label.promoteAllPeers": "提升全部",
+ "label.moreActions": "更多",
+
+ "settings.settings": "設置",
+ "settings.camera": "視訊來源",
+ "settings.selectCamera": "選擇視訊來源",
+ "settings.cantSelectCamera": "無法選擇此視訊來源",
+ "settings.audio": "音訊來源",
+ "settings.selectAudio": "選擇音訊來源",
+ "settings.cantSelectAudio": "無法選擇音訊來源",
+ "settings.audioOutput": "音訊輸出",
+ "settings.selectAudioOutput": "選擇音訊輸出設備",
+ "settings.cantSelectAudioOutput": "無法選擇音訊輸出設備",
+ "settings.resolution": "選擇視訊解析度",
+ "settings.layout": "房間佈局",
+ "settings.selectRoomLayout": "選擇房間佈局",
+ "settings.advancedMode": "進階模式",
+ "settings.permanentTopBar": "固定頂端列",
+ "settings.lastn": "視訊數量上限",
+ "settings.hiddenControls": "隱藏控制按鈕",
+ "settings.notificationSounds": "通知音效",
+ "settings.showNotifications": "顯示通知",
+ "settings.buttonControlBar": "獨立控制按鈕",
+ "settings.echoCancellation": "回音消除",
+ "settings.autoGainControl": "自動增益控制",
+ "settings.noiseSuppression": "噪音消除",
+ "settings.drawerOverlayed": "側邊欄覆蓋畫面",
+
+ "filesharing.saveFileError": "無法保存文件",
+ "filesharing.startingFileShare": "開始分享文件",
+ "filesharing.successfulFileShare": "文件已成功分享",
+ "filesharing.unableToShare": "無法分享文件",
+ "filesharing.error": "文件分享發生錯誤",
+ "filesharing.finished": "文件分享成功",
+ "filesharing.save": "保存文件",
+ "filesharing.sharedFile": "{displayName} 分享了一個文件",
+ "filesharing.download": "下載文件",
+ "filesharing.missingSeeds": "如果過了很久還是無法下載,則可能沒有人播種了。請讓上傳者重新上傳您想要的文件。",
+
+ "devices.devicesChanged": "您的設備已更改,請在設置中設定您的設備",
+
+ "device.audioUnsupported": "不支援您的音訊格式",
+ "device.activateAudio": "開啟音訊",
+ "device.muteAudio": "靜音",
+ "device.unMuteAudio": "取消靜音",
+
+ "device.videoUnsupported": "不支援您的視訊格式",
+ "device.startVideo": "開啟視訊",
+ "device.stopVideo": "關閉視訊",
+
+ "device.screenSharingUnsupported": "不支援您的螢幕分享格式",
+ "device.startScreenSharing": "開始螢幕分享",
+ "device.stopScreenSharing": "停止螢幕分享",
+
+ "devices.microphoneDisconnected": "麥克風已斷開",
+ "devices.microphoneError": "麥克風發生錯誤",
+ "devices.microphoneMute": "麥克風靜音",
+ "devices.microphoneUnMute": "取消麥克風靜音",
+ "devices.microphoneEnable": "麥克風已啟用",
+ "devices.microphoneMuteError": "無法使麥克風靜音",
+ "devices.microphoneUnMuteError": "無法取消麥克風靜音",
+
+ "devices.screenSharingDisconnected" : "螢幕分享已斷開",
+ "devices.screenSharingError": "螢幕分享時發生錯誤",
+
+ "devices.cameraDisconnected": "相機已斷開連接",
+ "devices.cameraError": "存取相機時發生錯誤",
+
+ "moderator.clearChat": "管理員清除了聊天",
+ "moderator.clearFiles": "管理員清除了所有檔案",
+ "moderator.muteAudio": "您已被管理員靜音",
+ "moderator.muteVideo": "您的視訊已被管理員關閉",
+ "moderator.muteScreenSharing": null
+}
\ No newline at end of file
diff --git a/app/src/translations/uk.json b/app/src/translations/uk.json
index a8cc077..2ee6774 100644
--- a/app/src/translations/uk.json
+++ b/app/src/translations/uk.json
@@ -63,6 +63,8 @@
"room.help": null,
"room.about": null,
"room.shortcutKeys": null,
+ "room.browsePeersSpotlight": null,
+ "room.stopAllScreenSharing": null,
"me.mutedPTT": null,
@@ -84,6 +86,9 @@
"tooltip.muteParticipantVideo": null,
"tooltip.raisedHand": null,
"tooltip.muteScreenSharing": null,
+ "tooltip.muteParticipantAudioModerator": null,
+ "tooltip.muteParticipantVideoModerator": null,
+ "tooltip.muteScreenSharingModerator": null,
"label.roomName": "Назва кімнати",
"label.chooseRoomButton": "Продовжити",
@@ -109,7 +114,7 @@
"label.ultra": "Ультра (UHD)",
"label.close": "Закрити",
"label.media": null,
- "label.appearence": null,
+ "label.appearance": null,
"label.advanced": null,
"label.addVideo": null,
"label.promoteAllPeers": null,
@@ -183,5 +188,6 @@
"moderator.clearChat": null,
"moderator.clearFiles": null,
"moderator.muteAudio": null,
- "moderator.muteVideo": null
-}
\ No newline at end of file
+ "moderator.muteVideo": null,
+ "moderator.muteScreenSharing": null
+}
\ No newline at end of file
diff --git a/server/lib/Room.js b/server/lib/Room.js
index 74accc4..f110327 100644
--- a/server/lib/Room.js
+++ b/server/lib/Room.js
@@ -1441,6 +1441,38 @@ class Room extends EventEmitter
break;
}
+ case 'moderator:stopAllScreenSharing':
+ {
+ if (!this._hasPermission(peer, MODERATE_ROOM))
+ throw new Error('peer not authorized');
+
+ // Spread to others
+ this._notification(peer.socket, 'moderator:stopScreenSharing', null, true);
+
+ cb();
+
+ break;
+ }
+
+ case 'moderator:stopScreenSharing':
+ {
+ if (!this._hasPermission(peer, MODERATE_ROOM))
+ throw new Error('peer not authorized');
+
+ const { peerId } = request.data;
+
+ const stopVideoPeer = this._peers[peerId];
+
+ if (!stopVideoPeer)
+ throw new Error(`peer with id "${peerId}" not found`);
+
+ this._notification(stopVideoPeer.socket, 'moderator:stopScreenSharing');
+
+ cb();
+
+ break;
+ }
+
case 'moderator:closeMeeting':
{
if (!this._hasPermission(peer, MODERATE_ROOM))