From ff35ad960257cf7804f03402c07b52d543236620 Mon Sep 17 00:00:00 2001
From: gcampes <gabrieldecampes@gmail.com>
Date: Mon, 23 Oct 2017 10:41:09 -0200
Subject: [PATCH] delete unused files, cleanup code

---
 .../imports/api/audio/client/bridge/sip.js    | 17 +++-
 .../audio/audio-controls/component.jsx        |  4 +-
 .../audio/audio-modal/component.jsx           | 10 +-
 .../audio/audio-notification/component.jsx    | 97 -------------------
 .../audio/audio-notification/container.jsx    | 16 ---
 .../audio/audio-notification/styles.scss      | 63 ------------
 .../audio/audio-settings/component.jsx        |  9 +-
 .../components/audio/audio-test/component.jsx | 16 ++-
 .../components/audio/audio-test/container.jsx | 14 ++-
 .../imports/ui/components/audio/component.jsx | 21 +++-
 .../imports/ui/components/audio/container.jsx | 10 +-
 .../audio/device-selector/component.jsx       | 45 +++++----
 .../audio/enter-audio/component.jsx           | 33 -------
 .../audio/enter-audio/container.jsx           | 29 ------
 .../components/audio/join-audio/component.jsx | 92 ------------------
 .../audio/mute-button/component.jsx           | 56 -----------
 .../audio/mute-button/container.jsx           | 26 -----
 .../components/audio/mute-button/styles.scss  |  3 -
 .../open-audio-modal-button/component.jsx     | 16 ---
 .../open-audio-modal-button/container.jsx     | 26 -----
 .../audio/open-audio-modal-button/styles.scss |  3 -
 .../ui/services/audio-manager/index.js        | 24 +++--
 22 files changed, 118 insertions(+), 512 deletions(-)
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/audio-notification/component.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/audio-notification/container.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/audio-notification/styles.scss
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/join-audio/component.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx
 delete mode 100644 bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss

diff --git a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
index 894457edf9..3d30439716 100644
--- a/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
+++ b/bigbluebutton-html5/imports/api/audio/client/bridge/sip.js
@@ -165,9 +165,9 @@ export default class SIPBridge extends BaseAudioBridge {
       let userAgent = new window.SIP.UA({
         uri: `sip:${encodeURIComponent(callerIdName)}@${hostname}`,
         wsServers: `${(protocol === 'https:' ? 'wss://' : 'ws://')}${hostname}/ws`,
-        log: {
-          builtinEnabled: false,
-        },
+        // log: {
+        //   builtinEnabled: false,
+        // },
         displayName: callerIdName,
         register: false,
         traceSip: true,
@@ -234,9 +234,13 @@ export default class SIPBridge extends BaseAudioBridge {
   }
 
   setupEventHandlers(currentSession) {
+    this.notifiedSuccess = false;
+
     return new Promise((resolve) => {
       const handleConnectionCompleted = () => {
+        if (this.notifiedSuccess) return;
         this.callback({ status: this.baseCallStates.started });
+        this.notifiedSuccess = true;
         resolve();
       };
 
@@ -260,7 +264,7 @@ export default class SIPBridge extends BaseAudioBridge {
 
       currentSession.on('terminated', handleSessionTerminated);
       currentSession.mediaHandler.on('iceConnectionCompleted', handleConnectionCompleted);
-      currentSession.mediaHandler.on('iceConnectsionConnected', handleConnectionCompleted);
+      currentSession.mediaHandler.on('iceConnectionConnected', handleConnectionCompleted);
 
       this.currentSession = currentSession;
     });
@@ -272,7 +276,10 @@ export default class SIPBridge extends BaseAudioBridge {
     } = this;
 
     const getMediaStream = constraints =>
-      navigator.mediaDevices.getUserMedia(constraints);
+      navigator.mediaDevices.getUserMedia(constraints).catch((err) => {
+        console.error(err);
+        throw new Error('There was a problem getting the media devices');
+      });
 
     if (!value) {
       const mediaStream = await getMediaStream({ audio: true });
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 c01483ec7a..3d6a95c327 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-controls/component.jsx
@@ -7,6 +7,7 @@ const propTypes = {
   handleToggleMuteMicrophone: PropTypes.func.isRequired,
   handleJoinAudio: PropTypes.func.isRequired,
   handleLeaveAudio: PropTypes.func.isRequired,
+  disable: PropTypes.bool.isRequired,
   unmute: PropTypes.bool.isRequired,
   mute: PropTypes.bool.isRequired,
   join: PropTypes.bool.isRequired,
@@ -26,6 +27,7 @@ const AudioControls = ({
       <Button
         className={styles.button}
         onClick={handleToggleMuteMicrophone}
+        disabled={disable}
         label={unmute ? 'Unmute' : 'Mute'}
         color={'primary'}
         icon={unmute ? 'mute' : 'unmute'}
@@ -35,7 +37,7 @@ const AudioControls = ({
     <Button
       className={styles.button}
       onClick={join ? handleLeaveAudio : handleJoinAudio}
-      disable={disable}
+      disabled={disable}
       label={join ? 'Leave Audio' : 'Join Audio'}
       color={join ? 'danger' : 'primary'}
       icon={join ? 'audio_off' : 'audio_on'}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
index 70193ff3ea..c063971081 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-modal/component.jsx
@@ -20,8 +20,13 @@ const propTypes = {
   isEchoTest: PropTypes.bool.isRequired,
   isConnecting: PropTypes.bool.isRequired,
   isConnected: PropTypes.bool.isRequired,
-  inputDeviceId: PropTypes.string.isRequired,
-  outputDeviceId: PropTypes.string.isRequired,
+  inputDeviceId: PropTypes.string,
+  outputDeviceId: PropTypes.string,
+};
+
+const defaultProps = {
+  inputDeviceId: null,
+  outputDeviceId: null,
 };
 
 const intlMessages = defineMessages({
@@ -277,5 +282,6 @@ class AudioModal extends Component {
 }
 
 AudioModal.propTypes = propTypes;
+AudioModal.defaultProps = defaultProps;
 
 export default injectIntl(AudioModal);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-notification/component.jsx
deleted file mode 100644
index 8a4348a3a7..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/component.jsx
+++ /dev/null
@@ -1,97 +0,0 @@
-import React, { Component } from 'react';
-import cx from 'classnames';
-import Button from '/imports/ui/components/button/component';
-import PropTypes from 'prop-types';
-import { defineMessages, intlShape, injectIntl } from 'react-intl';
-import styles from './styles.scss';
-
-const COLORS = [
-  'default', 'primary', 'danger', 'success',
-];
-
-const propTypes = {
-  color: PropTypes.oneOf(COLORS),
-  intl: intlShape.isRequired,
-  message: PropTypes.string,
-};
-
-const defaultProps = {
-  color: 'danger',
-  message: null,
-};
-
-const intlMessages = defineMessages({
-  closeLabel: {
-    id: 'app.audioNotification.closeLabel',
-    description: 'Audio notification dismiss label',
-  },
-});
-
-class AudioNotification extends Component {
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      message: null,
-    };
-
-    this.handleClose = this.handleClose.bind(this);
-  }
-
-  componentWillReceiveProps(nextProps) {
-    const {
-      message,
-    } = nextProps;
-
-    if (this.state.message) {
-      return;
-    }
-
-    this.setState({
-      message,
-    });
-  }
-
-  handleClose() {
-    this.setState({
-      message: null,
-    });
-  }
-
-  render() {
-    const {
-      intl,
-    } = this.props;
-
-    const {
-      message,
-    } = this.state;
-
-    if (!message) {
-      return null;
-    }
-
-    return (
-      <div
-        role="alert"
-        className={cx(styles.audioNotifications, styles[this.props.color])}
-      >
-        {message}
-        <Button
-          className={styles.closeBtn}
-          label={intl.formatMessage(intlMessages.closeLabel)}
-          icon={'close'}
-          size={'sm'}
-          circle
-          hideLabel
-          onClick={this.handleClose}
-        />
-      </div>
-    );
-  }
-}
-
-AudioNotification.propTypes = propTypes;
-AudioNotification.defaultProps = defaultProps;
-
-export default injectIntl(AudioNotification);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-notification/container.jsx
deleted file mode 100644
index e96d83b296..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/container.jsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { createContainer } from 'meteor/react-meteor-data';
-import Service from '/imports/ui/components/audio/service';
-import React from 'react';
-import AudioNotification from './component';
-
-const AudioNotificationContainer = props => (
-  <AudioNotification
-    {...props}
-  />
-);
-
-export default createContainer(() => (
-  {
-    message: Service.error(),
-  }
-), AudioNotificationContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/audio-notification/styles.scss
deleted file mode 100644
index 1033621bbd..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-notification/styles.scss
+++ /dev/null
@@ -1,63 +0,0 @@
-@import "/imports/ui/stylesheets/variables/_all";
-
-$nb-default-color: $color-gray;
-$nb-default-bg: $color-white;
-$nb-default-border: $color-white;
-
-$nb-primary-color: $color-white;
-$nb-primary-bg: $color-primary;
-$nb-primary-border: $color-primary;
-
-$nb-success-color: $color-white;
-$nb-success-bg: $color-success;
-$nb-success-border: $color-success;
-
-$nb-danger-color: $color-white;
-$nb-danger-bg: $color-danger;
-$nb-danger-border: $color-danger;
-
-.audioNotifications {
-  padding: $line-height-computed / 2;
-  display: flex;
-  flex-direction: row;
-  justify-content: center;
-  align-items: center;
-  font-weight: 600;
-}
-
-.closeBtn {
-  position: absolute;
-  right: 1.65em;
-  top: .5em;
-}
-
-// Modifies the close button style
-Button.closeBtn span:first-child {
-  color: $color-gray-light;
-  background: none;
-  border: none;
-  box-shadow: none;
-}
-
-
-@mixin nb-variant($color, $background, $border) {
-  color: $color;
-  background-color: $background;
-  border-color: $border;
-}
-
-.default {
-  @include nb-variant($nb-default-color, $nb-default-bg, $nb-default-border);
-}
-
-.primary {
-  @include nb-variant($nb-primary-color, $nb-primary-bg, $nb-primary-border);
-}
-
-.success {
-  @include nb-variant($nb-success-color, $nb-success-bg, $nb-success-border);
-}
-
-.danger {
-  @include nb-variant($nb-danger-color, $nb-danger-bg, $nb-danger-border);
-}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
index 13f82f54be..7b47f79bca 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-settings/component.jsx
@@ -4,7 +4,6 @@ import { defineMessages, injectIntl, intlShape } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
 import { withModalMounter } from '/imports/ui/components/modal/service';
 import DeviceSelector from '/imports/ui/components/audio/device-selector/component';
-import AudioStreamVolume from '/imports/ui/components/audio/audio-stream-volume/component';
 import AudioTestContainer from '/imports/ui/components/audio/audio-test/container';
 import cx from 'classnames';
 import styles from './styles';
@@ -74,18 +73,14 @@ class AudioSettings extends React.Component {
     };
   }
 
-  handleInputChange(deviceId, device) {
-    console.log(`INPUT DEVICE CHANGED: ${deviceId}`);
-    console.log(device);
+  handleInputChange(deviceId) {
     this.changeInputDevice(deviceId);
     this.setState({
       inputDeviceId: deviceId,
     });
   }
 
-  handleOutputChange(deviceId, device) {
-    console.log(`OUTPUT DEVICE CHANGED: ${deviceId}`);
-    console.log(device);
+  handleOutputChange(deviceId) {
     this.changeOutputDevice(deviceId);
     this.setState({
       outputDeviceId: deviceId,
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-test/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-test/component.jsx
index da775040f3..cb57d7fca0 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-test/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-test/component.jsx
@@ -1,8 +1,19 @@
 import React from 'react';
+import PropTypes from 'prop-types';
 import Button from '/imports/ui/components/button/component';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, intlShape, injectIntl } from 'react-intl';
 import styles from './styles.scss';
 
+const propTypes = {
+  intl: intlShape.isRequired,
+  handlePlayAudioSample: PropTypes.func.isRequired,
+  outputDeviceId: PropTypes.string,
+};
+
+const defaultProps = {
+  outputDeviceId: null,
+};
+
 const intlMessages = defineMessages({
   playSoundLabel: {
     id: 'app.audio.playSoundLabel',
@@ -36,4 +47,7 @@ class AudioTest extends React.Component {
   }
 }
 
+AudioTest.propTypes = propTypes;
+AudioTest.defaultProps = defaultProps;
+
 export default injectIntl(AudioTest);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
index 953d70fa2a..c4d235d01f 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/audio-test/container.jsx
@@ -1,8 +1,17 @@
 import React from 'react';
 import { createContainer } from 'meteor/react-meteor-data';
 import Service from '/imports/ui/components/audio/service';
+import PropTypes from 'prop-types';
 import AudioTest from './component';
 
+const propTypes = {
+  children: PropTypes.node,
+};
+
+const defaultProps = {
+  children: null,
+};
+
 const AudioTestContainer = props => (
   <AudioTest {...props}>
     {props.children}
@@ -13,7 +22,10 @@ export default createContainer(() => ({
   outputDeviceId: Service.outputDeviceId(),
   handlePlayAudioSample: (deviceId) => {
     const sound = new Audio('resources/sounds/audioSample.mp3');
-    if (deviceId) sound.setSinkId(deviceId);
+    if (deviceId && sound.setSinkId) sound.setSinkId(deviceId);
     sound.play();
   },
 }), AudioTestContainer);
+
+AudioTestContainer.propTypes = propTypes;
+AudioTestContainer.defaultProps = defaultProps;
diff --git a/bigbluebutton-html5/imports/ui/components/audio/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/component.jsx
index facfb00b5e..717836bd01 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/component.jsx
@@ -1,11 +1,28 @@
 import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+const propTypes = {
+  init: PropTypes.func.isRequired,
+};
 
 export default class Audio extends Component {
+  constructor(props) {
+    super(props);
+
+    this.init = props.init.bind(this);
+  }
+
   componentDidMount() {
-    this.props.init.call(this);
+    this.init();
   }
 
   render() {
-    return (<audio id="remote-media" autoPlay="autoplay" />);
+    return (
+      <audio id="remote-media" autoPlay="autoplay">
+        <track kind="captions" /> {/* These captions are brought to you by eslint */}
+      </audio>
+    );
   }
 }
+
+Audio.propTypes = propTypes;
diff --git a/bigbluebutton-html5/imports/ui/components/audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
index afb3a6e08b..e0e10d7d5f 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/container.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/container.jsx
@@ -20,7 +20,7 @@ const intlMessages = defineMessages({
     id: 'app.audioManager.joinedAudio',
     description: 'Joined audio toast message',
   },
-  joinedEcho : {
+  joinedEcho: {
     id: 'app.audioManager.joinedEcho',
     description: 'Joined echo test toast message',
   },
@@ -28,7 +28,6 @@ const intlMessages = defineMessages({
     id: 'app.audioManager.leftAudio',
     description: 'Left audio toast message',
   },
-
   genericError: {
     id: 'app.audioManager.genericError',
     description: 'Generic error messsage',
@@ -51,8 +50,7 @@ const intlMessages = defineMessages({
 const AudioContainer = props =>
   (<Audio {...props}>
     {props.children}
-  </Audio>
-  );
+  </Audio>);
 
 let didMountAutoJoin = false;
 
@@ -73,12 +71,12 @@ export default withModalMounter(injectIntl(createContainer(({ mountModal, intl }
       REQUEST_TIMEOUT: intl.formatMessage(intlMessages.requestTimeout),
       INVALID_TARGET: intl.formatMessage(intlMessages.invalidTarget),
     },
-  }
+  };
 
   return {
     init: () => {
       Service.init(messages);
-      Service.changeOutputDevice(document.querySelector('#remote-media').sinkId)
+      Service.changeOutputDevice(document.querySelector('#remote-media').sinkId);
       if (!autoJoinAudio || didMountAutoJoin) return;
       mountModal(<AudioModalContainer />);
       didMountAutoJoin = true;
diff --git a/bigbluebutton-html5/imports/ui/components/audio/device-selector/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/device-selector/component.jsx
index fb5b24c4f5..65ac4f4c4c 100644
--- a/bigbluebutton-html5/imports/ui/components/audio/device-selector/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/audio/device-selector/component.jsx
@@ -1,4 +1,5 @@
 import React, { Component } from 'react';
+import _ from 'lodash';
 import PropTypes from 'prop-types';
 import cx from 'classnames';
 import styles from '../audio-modal/styles';
@@ -7,19 +8,21 @@ const propTypes = {
   kind: PropTypes.oneOf(['audioinput', 'audiooutput', 'videoinput']),
   onChange: PropTypes.func.isRequired,
   value: PropTypes.string,
+  handleDeviceChange: PropTypes.func,
+  className: PropTypes.string,
 };
 
 const defaultProps = {
   kind: 'audioinput',
   value: undefined,
+  className: null,
+  handleDeviceChange: null,
 };
 
 class DeviceSelector extends Component {
   constructor(props) {
     super(props);
 
-    this.handleEnumerateDevicesSuccess = this.handleEnumerateDevicesSuccess.bind(this);
-    this.handleEnumerateDevicesError = this.handleEnumerateDevicesError.bind(this);
     this.handleSelectChange = this.handleSelectChange.bind(this);
 
     this.state = {
@@ -30,26 +33,26 @@ class DeviceSelector extends Component {
   }
 
   componentDidMount() {
-    navigator.mediaDevices
-      .enumerateDevices()
-      .then(this.handleEnumerateDevicesSuccess)
-      .catch(this.handleEnumerateDevicesError);
-  }
+    const handleEnumerateDevicesError = (error) => {
+      logClient('error', { error, method: 'handleEnumerateDevicesError' });
+    };
 
-  handleEnumerateDevicesSuccess(deviceInfos) {
-    const devices = deviceInfos.filter(d => d.kind === this.props.kind);
+    const handleEnumerateDevicesSuccess = (deviceInfos) => {
+      const devices = deviceInfos.filter(d => d.kind === this.props.kind);
 
-    this.setState({
-      devices,
-      options: devices.map((d, i) => ({
-        label: d.label || `${this.props.kind} - ${i}`,
-        value: d.deviceId,
-      })),
-    });
-  }
+      this.setState({
+        devices,
+        options: devices.map((d, i) => ({
+          label: d.label || `${this.props.kind} - ${i}`,
+          value: d.deviceId,
+        })),
+      });
+    };
 
-  handleEnumerateDevicesError(error) {
-    logClient('error', { error, method: 'handleEnumerateDevicesError' });
+    navigator.mediaDevices
+      .enumerateDevices()
+      .then(handleEnumerateDevicesSuccess)
+      .catch(handleEnumerateDevicesError);
   }
 
   handleSelectChange(event) {
@@ -75,9 +78,9 @@ class DeviceSelector extends Component {
       >
         {
           options.length ?
-            options.map((option, i) => (
+            options.map(option => (
               <option
-                key={i}
+                key={_.uniqueId('device-option-')}
                 value={option.value}
               >
                 {option.label}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
deleted file mode 100644
index fceea096a8..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/enter-audio/component.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React from 'react';
-import { defineMessages, injectIntl } from 'react-intl';
-import Button from '/imports/ui/components/button/component';
-
-class EnterAudio extends React.Component {
-  constructor(props) {
-    super(props);
-  }
-
-  render() {
-    const {
-      intl,
-    } = this.props;
-
-    return (
-      <Button
-        label={intl.formatMessage(intlMessages.enterSessionLabel)}
-        size={'md'}
-        color={'primary'}
-        onClick={this.props.handleJoin}
-      />
-    );
-  }
-}
-
-const intlMessages = defineMessages({
-  enterSessionLabel: {
-    id: 'app.audio.enterSessionLabel',
-    description: 'enter session button label',
-  },
-});
-
-export default injectIntl(EnterAudio);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
deleted file mode 100644
index 30a84bea88..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/enter-audio/container.jsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React, { Component } from 'react';
-import { createContainer } from 'meteor/react-meteor-data';
-import AudioService from '../service';
-import { withModalMounter } from '/imports/ui/components/modal/service';
-import EnterAudio from './component';
-
-class EnterAudioContainer extends Component {
-  constructor(props) {
-    super(props);
-  }
-
-  render() {
-    const {
-      isFullAudio,
-      mountModal,
-    } = this.props;
-
-    const handleJoin = () => {
-      mountModal(null);
-      return isFullAudio ? AudioService.joinMicrophone() : AudioService.joinListenOnly();
-    };
-
-    return (
-      <EnterAudio handleJoin={handleJoin} />
-    );
-  }
-}
-
-export default withModalMounter(EnterAudioContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/join-audio/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/join-audio/component.jsx
deleted file mode 100644
index 10fc993dbd..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/join-audio/component.jsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import React from 'react';
-import styles from '../audio-modal/styles.scss';
-import Button from '/imports/ui/components/button/component';
-import { withModalMounter } from '/imports/ui/components/modal/service';
-import { defineMessages, injectIntl } from 'react-intl';
-
-const intlMessages = defineMessages({
-  microphoneLabel: {
-    id: 'app.audioModal.microphoneLabel',
-    description: 'Join mic audio button label',
-  },
-  listenOnlyLabel: {
-    id: 'app.audioModal.listenOnlyLabel',
-    description: 'Join listen only audio button label',
-  },
-  closeLabel: {
-    id: 'app.audioModal.closeLabel',
-    description: 'close audio modal button label',
-  },
-  audioChoiceLabel: {
-    id: 'app.audioModal.audioChoiceLabel',
-    description: 'Join audio modal title',
-  },
-});
-
-class JoinAudio extends React.Component {
-  constructor(props) {
-    super(props);
-
-    this.handleClose = this.handleClose.bind(this);
-    this.openAudio = this.openAudio.bind(this);
-    this.openListen = this.openListen.bind(this);
-  }
-
-  handleClose() {
-    /* TODO: Refactor this to the outer component (audio-modal/container) */
-    this.props.mountModal(null);
-  }
-
-  openAudio() {
-    this.props.changeMenu(this.props.AUDIO_SETTINGS);
-  }
-
-  openListen() {
-    this.handleClose();
-    this.props.handleJoinListenOnly();
-  }
-
-  render() {
-    const { intl } = this.props;
-    return (
-      <div>
-        <div className={styles.closeBtnWrapper}>
-          <Button
-            className={styles.closeBtn}
-            label={intl.formatMessage(intlMessages.closeLabel)}
-            icon={'close'}
-            size={'lg'}
-            hideLabel
-            onClick={this.handleClose}
-          />
-        </div>
-
-        <div className={styles.title}>
-          {intl.formatMessage(intlMessages.audioChoiceLabel)}
-        </div>
-        <div className={styles.center}>
-          <Button
-            className={styles.audioBtn}
-            label={intl.formatMessage(intlMessages.microphoneLabel)}
-            icon={'unmute'}
-            circle
-            size={'jumbo'}
-            onClick={this.openAudio}
-          />
-
-          <span className={styles.verticalLine} />
-          <Button
-            className={styles.audioBtn}
-            label={intl.formatMessage(intlMessages.listenOnlyLabel)}
-            icon={'listen'}
-            circle
-            size={'jumbo'}
-            onClick={this.openListen}
-          />
-        </div>
-      </div>
-    );
-  }
-}
-
-export default withModalMounter(injectIntl(JoinAudio));
diff --git a/bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
deleted file mode 100644
index b20650d198..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/mute-button/component.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-import React from 'react';
-import Button from '/imports/ui/components/button/component';
-import styles from './styles.scss';
-//
-import { defineMessages, injectIntl } from 'react-intl';
-
-const intlMessages = defineMessages({
-  muteLabel: {
-    id: 'app.actionsBar.muteLabel',
-    description: 'Mute audio button label',
-  },
-  unmuteLabel: {
-    id: 'app.actionsBar.unmuteLabel',
-    description: 'Unmute audio button label',
-  },
-});
-
-class MuteAudio extends React.Component {
-
-  render() {
-    const {
-      isInAudio,
-      isMuted,
-      toggleMuteMicrophone,
-      isTalking,
-      intl,
-      isListenOnly,
-    } = this.props;
-
-    const icon = !isMuted ? 'unmute' : 'mute';
-    const label = intl.formatMessage(!isMuted ? intlMessages.muteLabel :
-                                                intlMessages.unmuteLabel);
-    // const tabIndex = !isInAudio ? -1 : 0;
-    let className;
-
-    if (isTalking) {
-      className = styles.circleGlow;
-    }
-
-    return (
-      <Button
-        onClick={toggleMuteMicrophone}
-        label={label}
-        color={'primary'}
-        icon={icon}
-        size={'lg'}
-        circle
-        className={className}
-      />
-
-        //tabIndex={tabIndex}
-    );
-  }
-}
-
-export default injectIntl(MuteAudio);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
deleted file mode 100644
index c74a7895b9..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/mute-button/container.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import { createContainer } from 'meteor/react-meteor-data';
-import VoiceUsers from '/imports/api/2.0/voice-users';
-import Auth from '/imports/ui/services/auth/index';
-import MuteAudio from './component';
-import AudioManager from '/imports/ui/services/audio-manager';
-
-const MuteAudioContainer = props => (<MuteAudio {...props} />);
-
-export default createContainer(() => {
-  const userId = Auth.userID;
-  const voiceUser = VoiceUsers.findOne({ intId: userId });
-
-  const { isConnected, isMuted, toggleMuteMicrophone } = AudioManager;
-  const { talking } = voiceUser;
-
-  // const callback = () => makeCall('toggleSelfVoice');
-
-  const data = {
-    isConnected: isConnected,
-    isMuted: isMuted,
-    toggleMuteMicrophone: toggleMuteMicrophone.bind(AudioManager),
-    isTalking: talking,
-  };
-  return data;
-}, MuteAudioContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss
deleted file mode 100644
index 1c4da32635..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/mute-button/styles.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.circleGlow > :first-child{
-    box-shadow: 0 0 .15rem #FFF !important;
-}
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx
deleted file mode 100644
index 7ed959b2c5..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/component.jsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import React, { Component } from 'react';
-import Button from '/imports/ui/components/button/component';
-import styles from './styles.scss';
-//
-import { defineMessages, injectIntl } from 'react-intl';
-
-class OpenAudioModalButton extends Component {
-
-  render() {
-    return (
-      <h1>asdasdasasdsad</h1>
-    );
-  }
-}
-
-export default injectIntl(OpenAudioModalButton);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx
deleted file mode 100644
index c74a7895b9..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/container.jsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import { createContainer } from 'meteor/react-meteor-data';
-import VoiceUsers from '/imports/api/2.0/voice-users';
-import Auth from '/imports/ui/services/auth/index';
-import MuteAudio from './component';
-import AudioManager from '/imports/ui/services/audio-manager';
-
-const MuteAudioContainer = props => (<MuteAudio {...props} />);
-
-export default createContainer(() => {
-  const userId = Auth.userID;
-  const voiceUser = VoiceUsers.findOne({ intId: userId });
-
-  const { isConnected, isMuted, toggleMuteMicrophone } = AudioManager;
-  const { talking } = voiceUser;
-
-  // const callback = () => makeCall('toggleSelfVoice');
-
-  const data = {
-    isConnected: isConnected,
-    isMuted: isMuted,
-    toggleMuteMicrophone: toggleMuteMicrophone.bind(AudioManager),
-    isTalking: talking,
-  };
-  return data;
-}, MuteAudioContainer);
diff --git a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss b/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss
deleted file mode 100644
index 1c4da32635..0000000000
--- a/bigbluebutton-html5/imports/ui/components/audio/open-audio-modal-button/styles.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.circleGlow > :first-child{
-    box-shadow: 0 0 .15rem #FFF !important;
-}
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
index 98fdde688f..df0b8efa9c 100644
--- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -77,7 +77,7 @@ class AudioManager {
       inputStream: this.isListenOnly ? this.createListenOnlyStream() : this.inputStream,
     };
 
-    return this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this))
+    return this.bridge.joinAudio(callOptions, this.callStateCallback.bind(this));
   }
 
   exitAudio() {
@@ -100,7 +100,7 @@ class AudioManager {
     this.isConnected = true;
 
     if (!this.isEchoTest) {
-      notify(this.messages.info.JOINED_AUDIO, 'info', 'audio_on');
+      this.notify(this.messages.info.JOINED_AUDIO);
     }
   }
 
@@ -115,7 +115,7 @@ class AudioManager {
 
 
     if (!this.error && !this.isEchoTest) {
-      notify(this.messages.info.LEFT_AUDIO, 'info', 'audio_on');
+      this.notify(this.messages.info.LEFT_AUDIO);
     }
     this.isEchoTest = false;
   }
@@ -135,6 +135,7 @@ class AudioManager {
       const {
         status,
         error,
+        bridgeError,
       } = response;
 
       if (status === STARTED) {
@@ -144,8 +145,8 @@ class AudioManager {
         this.onAudioExit();
       } else if (status === FAILED) {
         this.error = error;
-        notify(this.messages.error[error], 'error', 'audio_on');
-        console.error('Audio Error:', error);
+        this.notify(this.messages.error[error]);
+        console.error('Audio Error:', error, bridgeError);
         this.onAudioExit();
       }
     });
@@ -164,7 +165,12 @@ class AudioManager {
   }
 
   async changeInputDevice(deviceId) {
-    this.inputDevice = await this.bridge.changeInputDevice(deviceId);
+    try {
+      this.inputDevice = await this.bridge.changeInputDevice(deviceId);
+    } catch(err) {
+      this.error = err;
+      this.notify('There was a problem getting the media devices');
+    }
   }
 
   async changeOutputDevice(deviceId) {
@@ -192,6 +198,12 @@ class AudioManager {
   get userData() {
     return this._userData;
   }
+
+  notify(message) {
+    notify(message,
+           this.error ? 'error' : 'info',
+           this.isListenOnly ? 'audio_on' : 'unmute');
+  }
 }
 
 const audioManager = new AudioManager();
-- 
GitLab