mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 11:22:31 +00:00
When a user joins a very large call with SS, sometime SS is not auto-pinned to stage. This may happen when lot of participant joins are processed at the same time and therefore the state for remoteScreenShares may not get updated in time. Added extra logging to help debug if this issue reproduces.
138 lines
4.4 KiB
TypeScript
138 lines
4.4 KiB
TypeScript
import { IStore } from '../app/types';
|
|
import { getCurrentConference } from '../base/conference/functions';
|
|
import { PARTICIPANT_LEFT, PIN_PARTICIPANT } from '../base/participants/actionTypes';
|
|
import { pinParticipant } from '../base/participants/actions';
|
|
import { getParticipantById, getPinnedParticipant } from '../base/participants/functions';
|
|
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
|
|
import StateListenerRegistry from '../base/redux/StateListenerRegistry';
|
|
import { SET_DOCUMENT_EDITING_STATUS } from '../etherpad/actionTypes';
|
|
import { isStageFilmstripEnabled } from '../filmstrip/functions';
|
|
import { isFollowMeActive } from '../follow-me/functions';
|
|
|
|
import { SET_TILE_VIEW } from './actionTypes';
|
|
import { setTileView } from './actions';
|
|
import { getAutoPinSetting, updateAutoPinnedParticipant } from './functions';
|
|
import logger from './logger';
|
|
import './subscriber';
|
|
|
|
let previousTileViewEnabled: boolean | undefined;
|
|
|
|
/**
|
|
* Middleware which intercepts actions and updates tile view related state.
|
|
*
|
|
* @param {Store} store - The redux store.
|
|
* @returns {Function}
|
|
*/
|
|
MiddlewareRegistry.register(store => next => action => {
|
|
|
|
// we want to extract the leaving participant and check its type before actually the participant being removed.
|
|
let shouldUpdateAutoPin = false;
|
|
let oldScreenShares: Array<string> = [];
|
|
|
|
switch (action.type) {
|
|
case PARTICIPANT_LEFT: {
|
|
if (!getAutoPinSetting() || isFollowMeActive(store)) {
|
|
logger.debug('Auto pinning is disabled or Follow Me is active, skipping auto pinning.');
|
|
|
|
break;
|
|
}
|
|
shouldUpdateAutoPin = Boolean(getParticipantById(store.getState(), action.participant.id)?.fakeParticipant);
|
|
|
|
if (shouldUpdateAutoPin) {
|
|
// Capture the old screenshare list before the reducer runs
|
|
oldScreenShares = store.getState()['features/video-layout'].remoteScreenShares || [];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
const result = next(action);
|
|
|
|
switch (action.type) {
|
|
|
|
// Actions that temporarily clear the user preferred state of tile view,
|
|
// then re-set it when needed.
|
|
case PIN_PARTICIPANT: {
|
|
const pinnedParticipant = action.participant?.id;
|
|
|
|
if (pinnedParticipant) {
|
|
_storeTileViewStateAndClear(store);
|
|
} else {
|
|
_restoreTileViewState(store);
|
|
}
|
|
break;
|
|
}
|
|
case SET_DOCUMENT_EDITING_STATUS:
|
|
if (action.editing) {
|
|
_storeTileViewStateAndClear(store);
|
|
} else {
|
|
_restoreTileViewState(store);
|
|
}
|
|
break;
|
|
|
|
// Things to update when tile view state changes
|
|
case SET_TILE_VIEW: {
|
|
const state = store.getState();
|
|
const stageFilmstrip = isStageFilmstripEnabled(state);
|
|
|
|
if (action.enabled && !stageFilmstrip && getPinnedParticipant(state)) {
|
|
store.dispatch(pinParticipant(null));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (shouldUpdateAutoPin) {
|
|
const newScreenShares = store.getState()['features/video-layout'].remoteScreenShares || [];
|
|
|
|
updateAutoPinnedParticipant(oldScreenShares, newScreenShares, store);
|
|
}
|
|
|
|
return result;
|
|
});
|
|
|
|
/**
|
|
* Set up state change listener to perform maintenance tasks when the conference
|
|
* is left or failed.
|
|
*/
|
|
StateListenerRegistry.register(
|
|
state => getCurrentConference(state),
|
|
(conference, { dispatch }, previousConference) => {
|
|
if (conference !== previousConference) {
|
|
// conference changed, left or failed...
|
|
// Clear tile view state.
|
|
dispatch(setTileView());
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Restores tile view state, if it wasn't updated since then.
|
|
*
|
|
* @param {Object} store - The Redux Store.
|
|
* @returns {void}
|
|
*/
|
|
function _restoreTileViewState({ dispatch, getState }: IStore) {
|
|
const { tileViewEnabled } = getState()['features/video-layout'];
|
|
|
|
if (tileViewEnabled === undefined && previousTileViewEnabled !== undefined) {
|
|
dispatch(setTileView(previousTileViewEnabled));
|
|
}
|
|
|
|
previousTileViewEnabled = undefined;
|
|
}
|
|
|
|
/**
|
|
* Stores the current tile view state and clears it.
|
|
*
|
|
* @param {Object} store - The Redux Store.
|
|
* @returns {void}
|
|
*/
|
|
function _storeTileViewStateAndClear({ dispatch, getState }: IStore) {
|
|
const { tileViewEnabled } = getState()['features/video-layout'];
|
|
|
|
if (tileViewEnabled !== undefined) {
|
|
previousTileViewEnabled = tileViewEnabled;
|
|
dispatch(setTileView(undefined));
|
|
}
|
|
}
|