diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
index 3ec2232661..079e78d76f 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
@@ -14,6 +14,10 @@ const intlMessages = defineMessages({
id: 'app.audio.joinAudio',
description: 'Join audio button label',
},
+ leaveAudio: {
+ id: 'app.audio.leaveAudio',
+ description: 'Leave audio button label',
+ },
muteAudio: {
id: 'app.actionsBar.muteLabel',
description: 'Mute audio button label',
@@ -34,14 +38,19 @@ const propTypes = {
showMute: PropTypes.bool.isRequired,
inAudio: PropTypes.bool.isRequired,
listenOnly: PropTypes.bool.isRequired,
- intl: PropTypes.object.isRequired,
+ intl: PropTypes.shape({
+ formatMessage: PropTypes.func.isRequired,
+ }).isRequired,
talking: PropTypes.bool.isRequired,
};
class AudioControls extends PureComponent {
constructor(props) {
super(props);
- this.renderLeaveButton = this.renderLeaveButton.bind(this);
+ this.renderLeaveButtonWithoutLiveStreamSelector = this
+ .renderLeaveButtonWithoutLiveStreamSelector.bind(this);
+
+ this.renderJoinLeaveButton = this.renderJoinLeaveButton.bind(this);
}
componentDidMount() {
@@ -52,19 +61,106 @@ class AudioControls extends PureComponent {
}
}
- renderLeaveButton() {
+ renderJoinButton() {
+ const {
+ handleJoinAudio,
+ disable,
+ intl,
+ shortcuts,
+ } = this.props;
+
+ return (
+
+ );
+ }
+
+ static renderLeaveButtonWithLiveStreamSelector() {
return ();
}
+ renderLeaveButtonWithoutLiveStreamSelector() {
+ const {
+ handleJoinAudio,
+ handleLeaveAudio,
+ disable,
+ inAudio,
+ listenOnly,
+ intl,
+ shortcuts,
+ } = this.props;
+
+ let joinIcon = 'audio_off';
+ if (inAudio) {
+ if (listenOnly) {
+ joinIcon = 'listen';
+ } else {
+ joinIcon = 'audio_on';
+ }
+ }
+
+ return (
+
+ );
+ }
+
+ renderJoinLeaveButton() {
+ const {
+ inAudio,
+ } = this.props;
+
+ let { enableDynamicAudioDeviceSelection } = Meteor.settings.public.app;
+
+ if (typeof enableDynamicAudioDeviceSelection === 'undefined') {
+ enableDynamicAudioDeviceSelection = true;
+ }
+
+ if (inAudio) {
+ if (enableDynamicAudioDeviceSelection) {
+ return AudioControls.renderLeaveButtonWithLiveStreamSelector();
+ }
+
+ return this.renderLeaveButtonWithoutLiveStreamSelector();
+ }
+
+ return this.renderJoinButton();
+ }
+
render() {
const {
handleToggleMuteMicrophone,
- handleJoinAudio,
showMute,
muted,
disable,
talking,
- inAudio,
intl,
shortcuts,
isVoiceUser,
@@ -106,24 +202,7 @@ class AudioControls extends PureComponent {
) : null}
{showMute && isVoiceUser ? toggleMuteBtn : null}
{
- (inAudio)
- ? this.renderLeaveButton()
- : (
-
- )
+ this.renderJoinLeaveButton()
}
);
@@ -132,4 +211,5 @@ class AudioControls extends PureComponent {
AudioControls.propTypes = propTypes;
-export default withShortcutHelper(injectIntl(AudioControls), ['joinAudio', 'toggleMute']);
+export default withShortcutHelper(injectIntl(AudioControls), ['joinAudio',
+ 'leaveAudio', 'toggleMute']);
diff --git a/bigbluebutton-html5/private/config/settings.yml b/bigbluebutton-html5/private/config/settings.yml
index 6ddbcff62b..1f43826385 100755
--- a/bigbluebutton-html5/private/config/settings.yml
+++ b/bigbluebutton-html5/private/config/settings.yml
@@ -8,6 +8,14 @@ public:
forceListenOnly: false
skipCheck: false
skipCheckOnJoin: false
+ #
+ # Allow users to change microphone/speaker dinamically
+ # The device is changed immediately, without the need to rejoin
+ # audio. Default value is true
+ # Firefox users: if no output devices is shown, you may set the flag
+ # "media.setsinkid.enabled" to make it work properly
+ # enableDynamicAudioDeviceSelection: true
+ #
clientTitle: BigBlueButton
appName: BigBlueButton HTML5 Client
bbbServerVersion: 2.3-dev