<commit_before>// @flow

import {
    createStartAudioOnlyEvent,
    createStartMutedConfigurationEvent,
    createSyncTrackStateEvent,
    createTrackMutedEvent,
    sendAnalytics
} from '../../analytics';
import { APP_STATE_CHANGED } from '../../mobile/background';
import {
    NOTIFICATION_TIMEOUT_TYPE,
    showWarningNotification
} from '../../notifications';
import { isForceMuted } from '../../participants-pane/functions';
import { SET_AUDIO_ONLY, setAudioOnly } from '../audio-only';
import { isRoomValid, SET_ROOM } from '../conference';
import { getLocalParticipant } from '../participants';
import { MiddlewareRegistry } from '../redux';
import { getPropertyValue } from '../settings';
import {
    destroyLocalTracks,
    isLocalTrackMuted,
    isLocalVideoTrackDesktop,
    setTrackMuted,
    TRACK_ADDED
} from '../tracks';

import {
    SET_AUDIO_MUTED,
    SET_AUDIO_UNMUTE_PERMISSIONS,
    SET_VIDEO_MUTED,
    SET_VIDEO_UNMUTE_PERMISSIONS
} from './actionTypes';
import { setAudioMuted, setCameraFacingMode, setVideoMuted } from './actions';
import {
    CAMERA_FACING_MODE,
    MEDIA_TYPE,
    VIDEO_MUTISM_AUTHORITY
} from './constants';
import { getStartWithAudioMuted, getStartWithVideoMuted } from './functions';
import logger from './logger';
import {
    _AUDIO_INITIAL_MEDIA_STATE,
    _VIDEO_INITIAL_MEDIA_STATE
} from './reducer';

/**
 * Implements the entry point of the middleware of the feature base/media.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case APP_STATE_CHANGED:
        return _appStateChanged(store, next, action);

    case SET_AUDIO_ONLY:
        return _setAudioOnly(store, next, action);

    case SET_ROOM:
        return _setRoom(store, next, action);

    case TRACK_ADDED: {
        const result = next(action);
        const { track } = action;

        // Don't sync track mute state with the redux store for screenshare
        // since video mute state represents local camera mute state only.
        track.local && track.videoType !== 'desktop'
            && _syncTrackMutedState(store, track);

        return result;
    }

    case SET_AUDIO_MUTED: {
        const state = store.getState();
        const participant = getLocalParticipant(state);

        if (!action.muted && isForceMuted(participant, MEDIA_TYPE.AUDIO, state)) {
            return;
        }
        break;
    }

    case SET_AUDIO_UNMUTE_PERMISSIONS: {
        const { blocked } = action;
        const state = store.getState();
        const tracks = state['features/base/tracks'];
        const isAudioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);

        if (blocked && isAudioMuted) {
            store.dispatch(showWarningNotification({
                descriptionKey: 'notify.audioUnmuteBlockedDescription',
                titleKey: 'notify.audioUnmuteBlockedTitle'
            }, NOTIFICATION_TIMEOUT_TYPE.LONG));
        }
        break;
    }

    case SET_VIDEO_MUTED: {
        const state = store.getState();
        const participant = getLocalParticipant(state);

        if (!action.muted && isForceMuted(participant, MEDIA_TYPE.VIDEO, state)) {
            return;
        }
        break;
    }

    case SET_VIDEO_UNMUTE_PERMISSIONS: {
        const { blocked } = action;
        const state = store.getState();
        const tracks = state['features/base/tracks'];
        const isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);

        if (blocked && isVideoMuted) {
            store.dispatch(showWarningNotification({
                descriptionKey: 'notify.videoUnmuteBlockedDescription',
                titleKey: 'notify.videoUnmuteBlockedTitle'
            }, NOTIFICATION_TIMEOUT_TYPE.LONG));
        }
        break;
    }
    }

    return next(action);
});

/**
 * Adjusts the video muted state based on the app state.
 *
 * @param {Store} store - The redux store in which the specified {@code action}<commit_msg>fix(notifications) Adjust the timeout for unmute blocked notifications.<commit_after>// @flow

import {
    createStartAudioOnlyEvent,
    createStartMutedConfigurationEvent,
    createSyncTrackStateEvent,
    createTrackMutedEvent,
    sendAnalytics
} from '../../analytics';
import { APP_STATE_CHANGED } from '../../mobile/background';
import {
    NOTIFICATION_TIMEOUT_TYPE,
    showWarningNotification
} from '../../notifications';
import { isForceMuted } from '../../participants-pane/functions';
import { SET_AUDIO_ONLY, setAudioOnly } from '../audio-only';
import { isRoomValid, SET_ROOM } from '../conference';
import { getLocalParticipant } from '../participants';
import { MiddlewareRegistry } from '../redux';
import { getPropertyValue } from '../settings';
import {
    destroyLocalTracks,
    isLocalTrackMuted,
    isLocalVideoTrackDesktop,
    setTrackMuted,
    TRACK_ADDED
} from '../tracks';

import {
    SET_AUDIO_MUTED,
    SET_AUDIO_UNMUTE_PERMISSIONS,
    SET_VIDEO_MUTED,
    SET_VIDEO_UNMUTE_PERMISSIONS
} from './actionTypes';
import { setAudioMuted, setCameraFacingMode, setVideoMuted } from './actions';
import {
    CAMERA_FACING_MODE,
    MEDIA_TYPE,
    VIDEO_MUTISM_AUTHORITY
} from './constants';
import { getStartWithAudioMuted, getStartWithVideoMuted } from './functions';
import logger from './logger';
import {
    _AUDIO_INITIAL_MEDIA_STATE,
    _VIDEO_INITIAL_MEDIA_STATE
} from './reducer';

/**
 * Implements the entry point of the middleware of the feature base/media.
 *
 * @param {Store} store - The redux store.
 * @returns {Function}
 */
MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case APP_STATE_CHANGED:
        return _appStateChanged(store, next, action);

    case SET_AUDIO_ONLY:
        return _setAudioOnly(store, next, action);

    case SET_ROOM:
        return _setRoom(store, next, action);

    case TRACK_ADDED: {
        const result = next(action);
        const { track } = action;

        // Don't sync track mute state with the redux store for screenshare
        // since video mute state represents local camera mute state only.
        track.local && track.videoType !== 'desktop'
            && _syncTrackMutedState(store, track);

        return result;
    }

    case SET_AUDIO_MUTED: {
        const state = store.getState();
        const participant = getLocalParticipant(state);

        if (!action.muted && isForceMuted(participant, MEDIA_TYPE.AUDIO, state)) {
            return;
        }
        break;
    }

    case SET_AUDIO_UNMUTE_PERMISSIONS: {
        const { blocked } = action;
        const state = store.getState();
        const tracks = state['features/base/tracks'];
        const isAudioMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.AUDIO);

        if (blocked && isAudioMuted) {
            store.dispatch(showWarningNotification({
                descriptionKey: 'notify.audioUnmuteBlockedDescription',
                titleKey: 'notify.audioUnmuteBlockedTitle'
            }, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
        }
        break;
    }

    case SET_VIDEO_MUTED: {
        const state = store.getState();
        const participant = getLocalParticipant(state);

        if (!action.muted && isForceMuted(participant, MEDIA_TYPE.VIDEO, state)) {
            return;
        }
        break;
    }

    case SET_VIDEO_UNMUTE_PERMISSIONS: {
        const { blocked } = action;
        const state = store.getState();
        const tracks = state['features/base/tracks'];
        const isVideoMuted = isLocalTrackMuted(tracks, MEDIA_TYPE.VIDEO);

        if (blocked && isVideoMuted) {
            store.dispatch(showWarningNotification({
                descriptionKey: 'notify.videoUnmuteBlockedDescription',
                titleKey: 'notify.videoUnmuteBlockedTitle'
            }, NOTIFICATION_TIMEOUT_TYPE.MEDIUM));
        }
        break;
    }
    }

    return next(action);
});

/**
 * Adjusts the video muted state based on the app state.
 *
 * @param {Store} store - The redux store in which the specified {@code action}
{'fraction_non_alphanumeric': 0.10511363636363637, 'fraction_numerical': 0.0, 'mean_word_length': 2.8356229275225013, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '918050', 'n_tokens_mistral': 2449, 'n_tokens_neox': 2377, 'n_words': 542}