<commit_before>// @flow

import { batch } from 'react-redux';

import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
import { CONFERENCE_FAILED, CONFERENCE_JOINED } from '../base/conference';
import { JitsiConferenceErrors, JitsiConferenceEvents } from '../base/lib-jitsi-meet';
import { getFirstLoadableAvatarUrl, getParticipantDisplayName } from '../base/participants';
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
import { playSound, registerSound, unregisterSound } from '../base/sounds';
import { isTestModeEnabled } from '../base/testing';
import {
    NOTIFICATION_TIMEOUT_TYPE,
    NOTIFICATION_TYPE,
    showNotification
} from '../notifications';
import { shouldAutoKnock } from '../prejoin/functions';

import { KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED } from './actionTypes';
import {
    hideLobbyScreen,
    knockingParticipantLeft,
    openLobbyScreen,
    participantIsKnockingOrUpdated,
    setLobbyModeEnabled,
    startKnocking,
    setPasswordJoinFailed
} from './actions';
import { KNOCKING_PARTICIPANT_SOUND_ID } from './constants';
import { KNOCKING_PARTICIPANT_FILE } from './sounds';

declare var APP: Object;

MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case APP_WILL_MOUNT:
        store.dispatch(registerSound(KNOCKING_PARTICIPANT_SOUND_ID, KNOCKING_PARTICIPANT_FILE));
        break;
    case APP_WILL_UNMOUNT:
        store.dispatch(unregisterSound(KNOCKING_PARTICIPANT_SOUND_ID));
        break;
    case CONFERENCE_FAILED:
        return _conferenceFailed(store, next, action);
    case CONFERENCE_JOINED:
        return _conferenceJoined(store, next, action);
    case KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED: {
        // We need the full update result to be in the store already
        const result = next(action);

        _findLoadableAvatarForKnockingParticipant(store, action.participant);

        return result;
    }
    }

    return next(action);
});

/**
 * Registers a change handler for state['features/base/conference'].conference to
 * set the event listeners needed for the lobby feature to operate.
 */
StateListenerRegistry.register(
    state => state['features/base/conference'].conference,
    (conference, { dispatch, getState }, previousConference) => {
        if (conference && !previousConference) {
            conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, enabled => {
                dispatch(setLobbyModeEnabled(enabled));
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id, name) => {
                batch(() => {
                    dispatch(
                        participantIsKnockingOrUpdated({
                            id,
                            name
                        })
                    );
                    dispatch(playSound(KNOCKING_PARTICIPANT_SOUND_ID));
                    if (typeof APP !== 'undefined') {
                        APP.API.notifyKnockingParticipant({
                            id,
                            name
                        });
                    }
                });
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id, participant) => {
                dispatch(
                    participantIsKnockingOrUpdated({
                        ...participant,
                        id
                    })
                );
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, id => {
                dispatch(knockingParticipantLeft(id));
            });

            conference.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, (origin, sender) =>
                _maybeSendLobbyNotification(origin, sender, {
                    dispatch,
                    getState
                })
            );
        }
    }
);

/**
 * Function to handle the conference failed event and navigate the user to the lobby screen
 * based on the failure reason.
 *
 * @param {Object} store - The Redux store.
 * @param {Function} next - The Redux next function.
 * @param {Object} action - The Redux action.
 * @returns {Object}
 */
function _conferenceFailed({ dispatch, getState }, next, action) {
    const { error } = action;
    const state = getState();
    const nonFirstFailure = Boolean(state['features/base/conference'].membersOnly);

    if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) {
        if (typeof error.recoverable === 'undefined') {
            error.recoverable = true;
        }

        const result = next(action);

        dispatch(openLobbyScreen());

        if (shouldAutoKnock(state)) {
            dispatch(startKnocking());
        }

        dispatch(setPasswordJoinFailed(nonFirstFailure));

        return result;
    }

    dispatch(hideLobbyScreen());

    if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) {
        dispatch(
            showNotification({
                appearance: NOTIFICATION_TYPE.ERROR,
                hideErrorSupportLink: true,
                titleKey: 'lobby.joinRejectedMessage'
            }, NOTIFICATION_TIMEOUT_TYPE.LONG)<commit_msg>fix: Fixes correct state in lobby screen on wrong password.<commit_after>// @flow

import { batch } from 'react-redux';

import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app';
import {
    CONFERENCE_FAILED,
    CONFERENCE_JOINED,
    conferenceWillJoin
} from '../base/conference';
import { JitsiConferenceErrors, JitsiConferenceEvents } from '../base/lib-jitsi-meet';
import { getFirstLoadableAvatarUrl, getParticipantDisplayName } from '../base/participants';
import { MiddlewareRegistry, StateListenerRegistry } from '../base/redux';
import { playSound, registerSound, unregisterSound } from '../base/sounds';
import { isTestModeEnabled } from '../base/testing';
import {
    NOTIFICATION_TIMEOUT_TYPE,
    NOTIFICATION_TYPE,
    showNotification
} from '../notifications';
import { shouldAutoKnock } from '../prejoin/functions';

import { KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED } from './actionTypes';
import {
    hideLobbyScreen,
    knockingParticipantLeft,
    openLobbyScreen,
    participantIsKnockingOrUpdated,
    setLobbyModeEnabled,
    startKnocking,
    setPasswordJoinFailed
} from './actions';
import { KNOCKING_PARTICIPANT_SOUND_ID } from './constants';
import { KNOCKING_PARTICIPANT_FILE } from './sounds';

declare var APP: Object;

MiddlewareRegistry.register(store => next => action => {
    switch (action.type) {
    case APP_WILL_MOUNT:
        store.dispatch(registerSound(KNOCKING_PARTICIPANT_SOUND_ID, KNOCKING_PARTICIPANT_FILE));
        break;
    case APP_WILL_UNMOUNT:
        store.dispatch(unregisterSound(KNOCKING_PARTICIPANT_SOUND_ID));
        break;
    case CONFERENCE_FAILED:
        return _conferenceFailed(store, next, action);
    case CONFERENCE_JOINED:
        return _conferenceJoined(store, next, action);
    case KNOCKING_PARTICIPANT_ARRIVED_OR_UPDATED: {
        // We need the full update result to be in the store already
        const result = next(action);

        _findLoadableAvatarForKnockingParticipant(store, action.participant);

        return result;
    }
    }

    return next(action);
});

/**
 * Registers a change handler for state['features/base/conference'].conference to
 * set the event listeners needed for the lobby feature to operate.
 */
StateListenerRegistry.register(
    state => state['features/base/conference'].conference,
    (conference, { dispatch, getState }, previousConference) => {
        if (conference && !previousConference) {
            conference.on(JitsiConferenceEvents.MEMBERS_ONLY_CHANGED, enabled => {
                dispatch(setLobbyModeEnabled(enabled));
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_JOINED, (id, name) => {
                batch(() => {
                    dispatch(
                        participantIsKnockingOrUpdated({
                            id,
                            name
                        })
                    );
                    dispatch(playSound(KNOCKING_PARTICIPANT_SOUND_ID));
                    if (typeof APP !== 'undefined') {
                        APP.API.notifyKnockingParticipant({
                            id,
                            name
                        });
                    }
                });
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_UPDATED, (id, participant) => {
                dispatch(
                    participantIsKnockingOrUpdated({
                        ...participant,
                        id
                    })
                );
            });

            conference.on(JitsiConferenceEvents.LOBBY_USER_LEFT, id => {
                dispatch(knockingParticipantLeft(id));
            });

            conference.on(JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, (origin, sender) =>
                _maybeSendLobbyNotification(origin, sender, {
                    dispatch,
                    getState
                })
            );
        }
    }
);

/**
 * Function to handle the conference failed event and navigate the user to the lobby screen
 * based on the failure reason.
 *
 * @param {Object} store - The Redux store.
 * @param {Function} next - The Redux next function.
 * @param {Object} action - The Redux action.
 * @returns {Object}
 */
function _conferenceFailed({ dispatch, getState }, next, action) {
    const { error } = action;
    const state = getState();
    const { membersOnly } = state['features/base/conference'];
    const nonFirstFailure = Boolean(membersOnly);

    if (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR) {
        if (typeof error.recoverable === 'undefined') {
            error.recoverable = true;
        }

        const result = next(action);

        dispatch(openLobbyScreen());

        if (shouldAutoKnock(state)) {
            dispatch(startKnocking());
        }

        // In case of wrong password we need to be in the right state if in the meantime someone allows us to join
        if (nonFirstFailure) {
            dispatch(conferenceWillJoin(membersOnly));
        }

        dispatch(setPasswordJoinFailed(nonFirstFailure));

        return result;
    }

    dispatch(hideLobbyScreen());

    if (error.name === JitsiConferenceErrors.CONFERENCE_ACCESS_DENIED) {
        dispatch(
            showNotification({
                appearance: NOTIFICATION_TYPE.ERROR,
                hideErrorSupportLink: true,
                titleKey: 'lobby.joinRejectedMessage'
            }, NOTIFICATION_TIMEOUT_TYPE.LONG)
{'fraction_non_alphanumeric': 0.09719222462203024, 'fraction_numerical': 0.0, 'mean_word_length': 2.252901649358583, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, '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': '5917785', 'n_tokens_mistral': 3019, 'n_tokens_neox': 2897, 'n_words': 593}