123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // @flow
-
- import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
- import { CONFERENCE_JOINED } from '../base/conference';
- import {
- formatDeviceLabel,
- setAudioInputDevice
- } from '../base/devices';
- import JitsiMeetJS, { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
- import { MiddlewareRegistry } from '../base/redux';
- import { updateSettings } from '../base/settings';
- import { playSound, registerSound, unregisterSound } from '../base/sounds';
- import { hideNotification, showNotification } from '../notifications';
-
- import { setNoAudioSignalNotificationUid } from './actions';
- import { NO_AUDIO_SIGNAL_SOUND_ID } from './constants';
- import { NO_AUDIO_SIGNAL_SOUND_FILE } from './sounds';
-
- MiddlewareRegistry.register(store => next => async action => {
- const result = next(action);
- const { dispatch } = store;
-
- switch (action.type) {
- case APP_WILL_MOUNT:
- dispatch(registerSound(NO_AUDIO_SIGNAL_SOUND_ID, NO_AUDIO_SIGNAL_SOUND_FILE));
- break;
- case APP_WILL_UNMOUNT:
- dispatch(unregisterSound(NO_AUDIO_SIGNAL_SOUND_ID));
- break;
- case CONFERENCE_JOINED:
- _handleNoAudioSignalNotification(store, action);
- break;
- }
-
- return result;
- });
-
- /**
- * Handles the logic of displaying the no audio input detected notification as well as finding a valid device on the
- * system.
- *
- * @param {Store} store - The redux store in which the specified action is being dispatched.
- * @param {Action} action - The redux action {@code CONFERENCE_JOINED} which is being dispatched in the specified redux
- * store.
- * @private
- * @returns {void}
- */
- async function _handleNoAudioSignalNotification({ dispatch, getState }, action) {
-
- const { conference } = action;
-
- conference.on(JitsiConferenceEvents.AUDIO_INPUT_STATE_CHANGE, hasAudioInput => {
- const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
-
- // In case the notification is displayed but the conference detected audio input signal we hide it.
- if (noAudioSignalNotificationUid && hasAudioInput) {
- dispatch(hideNotification(noAudioSignalNotificationUid));
- dispatch(setNoAudioSignalNotificationUid());
- }
- });
- conference.on(JitsiConferenceEvents.NO_AUDIO_INPUT, async () => {
- const { noSrcDataNotificationUid } = getState()['features/base/no-src-data'];
-
- // In case the 'no data detected from source' notification was already shown, we prevent the
- // no audio signal notification as it's redundant i.e. it's clear that the users microphone is
- // muted from system settings.
- if (noSrcDataNotificationUid) {
- return;
- }
-
- const activeDevice = await JitsiMeetJS.getActiveAudioDevice();
-
- // In case there is a previous notification displayed just hide it.
- const { noAudioSignalNotificationUid } = getState()['features/no-audio-signal'];
-
- if (noAudioSignalNotificationUid) {
- dispatch(hideNotification(noAudioSignalNotificationUid));
- dispatch(setNoAudioSignalNotificationUid());
- }
-
-
- let descriptionKey = 'toolbar.noAudioSignalDesc';
- let customActionNameKey;
- let customActionHandler;
-
- // In case the detector picked up a device show a notification with a device suggestion
- if (activeDevice.deviceLabel !== '') {
- descriptionKey = 'toolbar.noAudioSignalDescSuggestion';
-
- // Preferably the label should be passed as an argument paired with a i18next string, however
- // at the point of the implementation the showNotification function only supports doing that for
- // the description.
- // TODO Add support for arguments to showNotification title and customAction strings.
- customActionNameKey = `Use ${formatDeviceLabel(activeDevice.deviceLabel)}`;
- customActionHandler = () => {
- // Select device callback
- dispatch(
- updateSettings({
- userSelectedMicDeviceId: activeDevice.deviceId,
- userSelectedMicDeviceLabel: activeDevice.deviceLabel
- })
- );
-
- dispatch(setAudioInputDevice(activeDevice.deviceId));
- };
- }
-
- const notification = showNotification({
- titleKey: 'toolbar.noAudioSignalTitle',
- descriptionKey,
- customActionNameKey,
- customActionHandler
- });
-
- dispatch(notification);
-
- dispatch(playSound(NO_AUDIO_SIGNAL_SOUND_ID));
-
- // Store the current notification uid so we can check for this state and hide it in case
- // a new track was added, thus changing the context of the notification
- dispatch(setNoAudioSignalNotificationUid(notification.uid));
- });
- }
|