<commit_before>// @flow

import debounce from 'lodash/debounce';

import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
import {
    FAKE_SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
    SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
    SET_TILE_VIEW
} from '../../video-layout/actionTypes';
import { SET_AUDIO_ONLY } from '../audio-only/actionTypes';
import { CONFERENCE_JOINED } from '../conference/actionTypes';
import {
    PARTICIPANT_JOINED,
    PARTICIPANT_KICKED,
    PARTICIPANT_LEFT
} from '../participants/actionTypes';
import {
    getParticipantById,
    getParticipantCount
} from '../participants/functions';
import { MiddlewareRegistry } from '../redux';
import { isLocalVideoTrackDesktop } from '../tracks/functions';

import { setLastN } from './actions';
import { limitLastN } from './functions';
import logger from './logger';

/**
 * Updates the last N value in the conference based on the current state of the redux store.
 *
 * @param {Store} store - The redux store.
 * @private
 * @returns {void}
 */
const _updateLastN = debounce(({ dispatch, getState }) => {
    const state = getState();
    const { conference } = state['features/base/conference'];

    if (!conference) {
        logger.debug('There is no active conference, not updating last N');

        return;
    }

    const { enabled: audioOnly } = state['features/base/audio-only'];
    const { appState } = state['features/background'] || {};
    const { enabled: filmStripEnabled } = state['features/filmstrip'];
    const config = state['features/base/config'];
    const { lastNLimits, lastN } = state['features/base/lastn'];
    const participantCount = getParticipantCount(state);

    // Select the lastN value based on the following preference order.
    // 1. The last-n value in redux.
    // 2. The last-n value from 'startLastN' if it is specified in config.js
    // 3. The last-n value from 'channelLastN' if specified in config.js.
    // 4. -1 as the default value.
    let lastNSelected = lastN || (config.startLastN ?? (config.channelLastN ?? -1));

    // Apply last N limit based on the # of participants and config settings.
    const limitedLastN = limitLastN(participantCount, lastNLimits);

    if (limitedLastN !== undefined) {
        lastNSelected = lastNSelected === -1 ? limitedLastN : Math.min(limitedLastN, lastNSelected);
    }

    if (typeof appState !== 'undefined' && appState !== 'active') {
        lastNSelected = isLocalVideoTrackDesktop(state) ? 1 : 0;
    } else if (audioOnly) {
        const { remoteScreenShares, tileViewEnabled } = state['features/video-layout'];
        const largeVideoParticipantId = state['features/large-video'].participantId;
        const largeVideoParticipant
            = largeVideoParticipantId ? getParticipantById(state, largeVideoParticipantId) : undefined;

        // Use tileViewEnabled state from redux here instead of determining if client should be in tile
        // view since we make an exception only for screenshare when in audio-only mode. If the user unpins
        // the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
        if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
            lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId) ? 1 : 0;
        } else {
            lastNSelected = 0;<commit_msg>fix(lastN) fix last N getting stuck on 1<commit_after>// @flow

import debounce from 'lodash/debounce';

import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
import {
    FAKE_SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
    SCREEN_SHARE_REMOTE_PARTICIPANTS_UPDATED,
    SET_TILE_VIEW
} from '../../video-layout/actionTypes';
import { SET_AUDIO_ONLY } from '../audio-only/actionTypes';
import { CONFERENCE_JOINED } from '../conference/actionTypes';
import {
    PARTICIPANT_JOINED,
    PARTICIPANT_KICKED,
    PARTICIPANT_LEFT
} from '../participants/actionTypes';
import {
    getParticipantById,
    getParticipantCount
} from '../participants/functions';
import { MiddlewareRegistry } from '../redux';
import { isLocalVideoTrackDesktop } from '../tracks/functions';

import { setLastN } from './actions';
import { limitLastN } from './functions';
import logger from './logger';

/**
 * Updates the last N value in the conference based on the current state of the redux store.
 *
 * @param {Store} store - The redux store.
 * @private
 * @returns {void}
 */
const _updateLastN = debounce(({ dispatch, getState }) => {
    const state = getState();
    const { conference } = state['features/base/conference'];

    if (!conference) {
        logger.debug('There is no active conference, not updating last N');

        return;
    }

    const { enabled: audioOnly } = state['features/base/audio-only'];
    const { appState } = state['features/background'] || {};
    const { enabled: filmStripEnabled } = state['features/filmstrip'];
    const config = state['features/base/config'];
    const { lastNLimits } = state['features/base/lastn'];
    const participantCount = getParticipantCount(state);

    // Select the (initial) lastN value based on the following preference order.
    // 1. The last-n value from 'startLastN' if it is specified in config.js
    // 2. The last-n value from 'channelLastN' if specified in config.js.
    // 3. -1 as the default value.
    let lastNSelected = config.startLastN ?? (config.channelLastN ?? -1);

    // Apply last N limit based on the # of participants and config settings.
    const limitedLastN = limitLastN(participantCount, lastNLimits);

    if (limitedLastN !== undefined) {
        lastNSelected = lastNSelected === -1 ? limitedLastN : Math.min(limitedLastN, lastNSelected);
    }

    if (typeof appState !== 'undefined' && appState !== 'active') {
        lastNSelected = isLocalVideoTrackDesktop(state) ? 1 : 0;
    } else if (audioOnly) {
        const { remoteScreenShares, tileViewEnabled } = state['features/video-layout'];
        const largeVideoParticipantId = state['features/large-video'].participantId;
        const largeVideoParticipant
            = largeVideoParticipantId ? getParticipantById(state, largeVideoParticipantId) : undefined;

        // Use tileViewEnabled state from redux here instead of determining if client should be in tile
        // view since we make an exception only for screenshare when in audio-only mode. If the user unpins
        // the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
        if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
            lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId) ? 1 : 0;
        } else {
            lastNSelected = 0;
{'fraction_non_alphanumeric': 0.11608903916596225, 'fraction_numerical': 0.0039447731755424065, 'mean_word_length': 3.442428035043805, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '3418987', 'n_tokens_mistral': 2102, 'n_tokens_neox': 2026, 'n_words': 597}