| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 | 
							- // @flow
 - 
 - import { NativeEventEmitter, NativeModules } from 'react-native';
 - 
 - import { SET_AUDIO_ONLY } from '../../base/audio-only';
 - import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../../base/app';
 - import {
 -     CONFERENCE_FAILED,
 -     CONFERENCE_LEFT,
 -     CONFERENCE_JOINED,
 -     getCurrentConference
 - } from '../../base/conference';
 - import { MiddlewareRegistry } from '../../base/redux';
 - 
 - import { _SET_AUDIOMODE_DEVICES, _SET_AUDIOMODE_SUBSCRIPTIONS } from './actionTypes';
 - import logger from './logger';
 - 
 - const { AudioMode } = NativeModules;
 - const AudioModeEmitter = new NativeEventEmitter(AudioMode);
 - 
 - /**
 -  * Middleware that captures conference actions and sets the correct audio mode
 -  * based on the type of conference. Audio-only conferences don't use the speaker
 -  * by default, and video conferences do.
 -  *
 -  * @param {Store} store - The redux store.
 -  * @returns {Function}
 -  */
 - MiddlewareRegistry.register(store => next => action => {
 -     /* eslint-disable no-fallthrough */
 - 
 -     switch (action.type) {
 -     case _SET_AUDIOMODE_SUBSCRIPTIONS:
 -         _setSubscriptions(store);
 -         break;
 -     case APP_WILL_UNMOUNT: {
 -         store.dispatch({
 -             type: _SET_AUDIOMODE_SUBSCRIPTIONS,
 -             subscriptions: undefined
 -         });
 -         break;
 -     }
 -     case APP_WILL_MOUNT:
 -         _appWillMount(store);
 -     case CONFERENCE_FAILED: // eslint-disable-line no-fallthrough
 -     case CONFERENCE_LEFT:
 - 
 -     /*
 -     * NOTE: We moved the audio mode setting from CONFERENCE_WILL_JOIN to
 -     * CONFERENCE_JOINED because in case of a locked room, the app goes
 -     * through CONFERENCE_FAILED state and gets to CONFERENCE_JOINED only
 -     * after a correct password, so we want to make sure we have the correct
 -     * audio mode set up when we finally get to the conf, but also make sure
 -     * that the app is in the right audio mode if the user leaves the
 -     * conference after the password prompt appears.
 -     */
 -     case CONFERENCE_JOINED:
 -     case SET_AUDIO_ONLY:
 -         return _updateAudioMode(store, next, action);
 - 
 -     }
 - 
 -     /* eslint-enable no-fallthrough */
 - 
 -     return next(action);
 - });
 - 
 - /**
 -  * Notifies this feature that the action {@link APP_WILL_MOUNT} is being
 -  * dispatched within a specific redux {@code store}.
 -  *
 -  * @param {Store} store - The redux store in which the specified {@code action}
 -  * is being dispatched.
 -  * @private
 -  * @returns {void}
 -  */
 - function _appWillMount(store) {
 -     const subscriptions = [
 -         AudioModeEmitter.addListener(AudioMode.DEVICE_CHANGE_EVENT, _onDevicesUpdate, store)
 -     ];
 - 
 -     store.dispatch({
 -         type: _SET_AUDIOMODE_SUBSCRIPTIONS,
 -         subscriptions
 -     });
 - }
 - 
 - /**
 -  * Handles audio device changes. The list will be stored on the redux store.
 -  *
 -  * @param {Object} devices - The current list of devices.
 -  * @private
 -  * @returns {void}
 -  */
 - function _onDevicesUpdate(devices) {
 -     const { dispatch } = this; // eslint-disable-line no-invalid-this
 - 
 -     dispatch({
 -         type: _SET_AUDIOMODE_DEVICES,
 -         devices
 -     });
 - }
 - 
 - /**
 -  * Notifies this feature that the action
 -  * {@link _SET_AUDIOMODE_SUBSCRIPTIONS} is being dispatched within
 -  * a specific redux {@code store}.
 -  *
 -  * @param {Store} store - The redux store in which the specified {@code action}
 -  * is being dispatched.
 -  * @private
 -  * @returns {void}
 -  */
 - function _setSubscriptions({ getState }) {
 -     const { subscriptions } = getState()['features/mobile/audio-mode'];
 - 
 -     if (subscriptions) {
 -         for (const subscription of subscriptions) {
 -             subscription.remove();
 -         }
 -     }
 - }
 - 
 - /**
 -  * Updates the audio mode based on the current (redux) state.
 -  *
 -  * @param {Store} store - The redux store in which the specified {@code action}
 -  * is being dispatched.
 -  * @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
 -  * specified {@code action} in the specified {@code store}.
 -  * @param {Action} action - The redux action which is
 -  * being dispatched in the specified {@code store}.
 -  * @private
 -  * @returns {*} The value returned by {@code next(action)}.
 -  */
 - function _updateAudioMode({ getState }, next, action) {
 -     const result = next(action);
 -     const state = getState();
 -     const conference = getCurrentConference(state);
 -     const { enabled: audioOnly } = state['features/base/audio-only'];
 -     let mode;
 - 
 -     if (conference) {
 -         mode = audioOnly ? AudioMode.AUDIO_CALL : AudioMode.VIDEO_CALL;
 -     } else {
 -         mode = AudioMode.DEFAULT;
 -     }
 - 
 -     AudioMode.setMode(mode).catch(err => logger.error(`Failed to set audio mode ${String(mode)}: ${err}`));
 - 
 -     return result;
 - }
 
 
  |