mirror of https://github.com/jitsi/jitsi-meet
feat: Additional setting to order participants in speaker stats (#9751)
* Additional setting to order participants in speaker stats #9742 * Setting to order speaker stats optimisations #9742 * Lint fixes #9742 * Replace APP references #9742 * Lint fixes #9742 * Setting to order speaker stats optimisations 2 #9742 * Lint fixes #9742 * Remove unnecessary param #9742 * Add more speaker-stats reducer _updateStats docs #9742pull/9913/head jitsi-meet_6306
parent
db473dfef5
commit
5e152b4a42
@ -0,0 +1,39 @@ |
||||
// @flow
|
||||
|
||||
/** |
||||
* Action type to start search. |
||||
* |
||||
* { |
||||
* type: INIT_SEARCH |
||||
* } |
||||
*/ |
||||
export const INIT_SEARCH = 'INIT_SEARCH'; |
||||
|
||||
/** |
||||
* Action type to start stats retrieval. |
||||
* |
||||
* { |
||||
* type: INIT_UPDATE_STATS, |
||||
* getSpeakerStats: Function |
||||
* } |
||||
*/ |
||||
export const INIT_UPDATE_STATS = 'INIT_UPDATE_STATS'; |
||||
|
||||
/** |
||||
* Action type to update stats. |
||||
* |
||||
* { |
||||
* type: UPDATE_STATS, |
||||
* stats: Object |
||||
* } |
||||
*/ |
||||
export const UPDATE_STATS = 'UPDATE_STATS'; |
||||
|
||||
/** |
||||
* Action type to initiate reordering of the stats. |
||||
* |
||||
* { |
||||
* type: INIT_REORDER_STATS |
||||
* } |
||||
*/ |
||||
export const INIT_REORDER_STATS = 'INIT_REORDER_STATS'; |
||||
@ -0,0 +1,58 @@ |
||||
// @flow
|
||||
|
||||
import { |
||||
INIT_SEARCH, |
||||
INIT_UPDATE_STATS, |
||||
UPDATE_STATS, |
||||
INIT_REORDER_STATS |
||||
} from './actionTypes'; |
||||
|
||||
/** |
||||
* Starts a search by criteria. |
||||
* |
||||
* @param {string} criteria - The search criteria. |
||||
* @returns {Object} |
||||
*/ |
||||
export function initSearch(criteria: string) { |
||||
return { |
||||
type: INIT_SEARCH, |
||||
criteria |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Gets the new stats and triggers update. |
||||
* |
||||
* @param {Function} getSpeakerStats - Function to get the speaker stats. |
||||
* @returns {Object} |
||||
*/ |
||||
export function initUpdateStats(getSpeakerStats: Function) { |
||||
return { |
||||
type: INIT_UPDATE_STATS, |
||||
getSpeakerStats |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Updates the stats with new stats. |
||||
* |
||||
* @param {Object} stats - The new stats. |
||||
* @returns {Object} |
||||
*/ |
||||
export function updateStats(stats: Object) { |
||||
return { |
||||
type: UPDATE_STATS, |
||||
stats |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* Initiates reordering of the stats. |
||||
* |
||||
* @returns {Object} |
||||
*/ |
||||
export function initReorderStats() { |
||||
return { |
||||
type: INIT_REORDER_STATS |
||||
}; |
||||
} |
||||
@ -0,0 +1 @@ |
||||
export const SPEAKER_STATS_RELOAD_INTERVAL = 1000; |
||||
@ -0,0 +1,49 @@ |
||||
// @flow
|
||||
|
||||
import { |
||||
PARTICIPANT_JOINED, |
||||
PARTICIPANT_KICKED, |
||||
PARTICIPANT_LEFT, |
||||
PARTICIPANT_UPDATED |
||||
} from '../base/participants/actionTypes'; |
||||
import { MiddlewareRegistry } from '../base/redux'; |
||||
|
||||
import { INIT_SEARCH, INIT_UPDATE_STATS } from './actionTypes'; |
||||
import { initReorderStats, updateStats } from './actions'; |
||||
import { filterBySearchCriteria, getSortedSpeakerStats, getPendingReorder } from './functions'; |
||||
|
||||
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => { |
||||
const result = next(action); |
||||
|
||||
switch (action.type) { |
||||
|
||||
case INIT_SEARCH: { |
||||
const state = getState(); |
||||
const stats = filterBySearchCriteria(state); |
||||
|
||||
dispatch(updateStats(stats)); |
||||
break; |
||||
} |
||||
|
||||
case INIT_UPDATE_STATS: |
||||
if (action.getSpeakerStats) { |
||||
const state = getState(); |
||||
const speakerStats = { ...action.getSpeakerStats() }; |
||||
const stats = filterBySearchCriteria(state, speakerStats); |
||||
const pendingReorder = getPendingReorder(state); |
||||
|
||||
dispatch(updateStats(pendingReorder ? getSortedSpeakerStats(state, stats) : stats)); |
||||
} |
||||
break; |
||||
case PARTICIPANT_JOINED: |
||||
case PARTICIPANT_LEFT: |
||||
case PARTICIPANT_KICKED: |
||||
case PARTICIPANT_UPDATED: { |
||||
dispatch(initReorderStats()); |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
}); |
||||
@ -0,0 +1,119 @@ |
||||
// @flow
|
||||
|
||||
import _ from 'lodash'; |
||||
|
||||
import { ReducerRegistry } from '../base/redux'; |
||||
|
||||
import { |
||||
INIT_SEARCH, |
||||
UPDATE_STATS, |
||||
INIT_REORDER_STATS |
||||
} from './actionTypes'; |
||||
|
||||
/** |
||||
* The initial state of the feature speaker-stats. |
||||
* |
||||
* @type {Object} |
||||
*/ |
||||
const INITIAL_STATE = { |
||||
stats: {}, |
||||
pendingReorder: true, |
||||
criteria: '' |
||||
}; |
||||
|
||||
ReducerRegistry.register('features/speaker-stats', (state = _getInitialState(), action) => { |
||||
switch (action.type) { |
||||
case INIT_SEARCH: |
||||
return _updateCriteria(state, action); |
||||
case UPDATE_STATS: |
||||
return _updateStats(state, action); |
||||
case INIT_REORDER_STATS: |
||||
return _initReorderStats(state); |
||||
} |
||||
|
||||
return state; |
||||
}); |
||||
|
||||
/** |
||||
* Gets the initial state of the feature speaker-stats. |
||||
* |
||||
* @returns {Object} |
||||
*/ |
||||
function _getInitialState() { |
||||
return INITIAL_STATE; |
||||
} |
||||
|
||||
/** |
||||
* Reduces a specific Redux action INIT_SEARCH of the feature |
||||
* speaker-stats. |
||||
* |
||||
* @param {Object} state - The Redux state of the feature speaker-stats. |
||||
* @param {Action} action - The Redux action INIT_SEARCH to reduce. |
||||
* @private |
||||
* @returns {Object} The new state after the reduction of the specified action. |
||||
*/ |
||||
function _updateCriteria(state, { criteria }) { |
||||
return _.assign( |
||||
{}, |
||||
state, |
||||
{ criteria }, |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Reduces a specific Redux action UPDATE_STATS of the feature |
||||
* speaker-stats. |
||||
* The speaker stats order is based on the stats object properties. |
||||
* When updating without reordering, the new stats object properties are reordered |
||||
* as the last in state, otherwise the order would be lost on each update. |
||||
* If there was already a pending reorder, the stats object properties already have |
||||
* the correct order, so the property order is not changing. |
||||
* |
||||
* @param {Object} state - The Redux state of the feature speaker-stats. |
||||
* @param {Action} action - The Redux action UPDATE_STATS to reduce. |
||||
* @private |
||||
* @returns {Object} - The new state after the reduction of the specified action. |
||||
*/ |
||||
function _updateStats(state, { stats }) { |
||||
const finalStats = state.pendingReorder ? stats : state.stats; |
||||
|
||||
if (!state.pendingReorder) { |
||||
// Avoid reordering the speaker stats object properties
|
||||
const finalKeys = Object.keys(stats); |
||||
|
||||
finalKeys.forEach(newStatId => { |
||||
finalStats[newStatId] = _.clone(stats[newStatId]); |
||||
}); |
||||
|
||||
Object.keys(finalStats).forEach(key => { |
||||
if (!finalKeys.includes(key)) { |
||||
delete finalStats[key]; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
return _.assign( |
||||
{}, |
||||
state, |
||||
{ |
||||
stats: finalStats, |
||||
pendingReorder: false |
||||
}, |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Reduces a specific Redux action INIT_REORDER_STATS of the feature |
||||
* speaker-stats. |
||||
* |
||||
* @param {Object} state - The Redux state of the feature speaker-stats. |
||||
* @private |
||||
* @returns {Object} The new state after the reduction of the specified action. |
||||
*/ |
||||
function _initReorderStats(state) { |
||||
return _.assign( |
||||
{}, |
||||
state, |
||||
{ pendingReorder: true }, |
||||
); |
||||
} |
||||
Loading…
Reference in new issue