feat: Add name overwrite API (#11543)
This commit is contained in:
parent
f5004a2a0c
commit
769f0a8452
|
@ -40,7 +40,8 @@ import {
|
|||
isParticipantModerator,
|
||||
isLocalParticipantModerator,
|
||||
hasRaisedHand,
|
||||
grantModerator
|
||||
grantModerator,
|
||||
overwriteParticipantsNames
|
||||
} from '../../react/features/base/participants';
|
||||
import { updateSettings } from '../../react/features/base/settings';
|
||||
import { isToggleCameraEnabled, toggleCamera } from '../../react/features/base/tracks';
|
||||
|
@ -428,6 +429,11 @@ function initCommands() {
|
|||
logger.error('Failed sending endpoint text message', err);
|
||||
}
|
||||
},
|
||||
'overwrite-names': participantList => {
|
||||
logger.debug('Overwrite names command received');
|
||||
|
||||
APP.store.dispatch(overwriteParticipantsNames(participantList));
|
||||
},
|
||||
'toggle-e2ee': enabled => {
|
||||
logger.debug('Toggle E2EE key command received');
|
||||
APP.store.dispatch(toggleE2EE(enabled));
|
||||
|
@ -1660,6 +1666,19 @@ class API {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application that the breakout rooms changed.
|
||||
*
|
||||
* @param {Array} rooms - Array of breakout rooms.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyBreakoutRoomsUpdated(rooms) {
|
||||
this._sendEvent({
|
||||
name: 'breakout-rooms-updated',
|
||||
rooms
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the allocated resources.
|
||||
*
|
||||
|
|
|
@ -46,6 +46,7 @@ const commands = {
|
|||
kickParticipant: 'kick-participant',
|
||||
muteEveryone: 'mute-everyone',
|
||||
overwriteConfig: 'overwrite-config',
|
||||
overwriteNames: 'overwrite-names',
|
||||
password: 'password',
|
||||
pinParticipant: 'pin-participant',
|
||||
rejectParticipant: 'reject-participant',
|
||||
|
@ -94,6 +95,7 @@ const events = {
|
|||
'avatar-changed': 'avatarChanged',
|
||||
'audio-availability-changed': 'audioAvailabilityChanged',
|
||||
'audio-mute-status-changed': 'audioMuteStatusChanged',
|
||||
'breakout-rooms-updated': 'breakoutRoomsUpdated',
|
||||
'browser-support': 'browserSupport',
|
||||
'camera-error': 'cameraError',
|
||||
'chat-updated': 'chatUpdated',
|
||||
|
|
|
@ -212,3 +212,22 @@ export const RAISE_HAND_UPDATED = 'RAISE_HAND_UPDATED';
|
|||
* }
|
||||
*/
|
||||
export const LOCAL_PARTICIPANT_AUDIO_LEVEL_CHANGED = 'LOCAL_PARTICIPANT_AUDIO_LEVEL_CHANGED'
|
||||
|
||||
/**
|
||||
* The type of Redux action which overwrites the name of a participant.
|
||||
* {
|
||||
* type: OVERWRITE_PARTICIPANT_NAME,
|
||||
* id: string,
|
||||
* name: string
|
||||
* }
|
||||
*/
|
||||
export const OVERWRITE_PARTICIPANT_NAME = 'OVERWRITE_PARTICIPANT_NAME';
|
||||
|
||||
/**
|
||||
* The type of Redux action which overwrites the names of multiple participants.
|
||||
* {
|
||||
* type: OVERWRITE_PARTICIPANTS_NAMES,
|
||||
* participantsList: Array<Object>,
|
||||
* }
|
||||
*/
|
||||
export const OVERWRITE_PARTICIPANTS_NAMES = 'OVERWRITE_PARTICIPANTS_NAMES';
|
||||
|
|
|
@ -18,7 +18,9 @@ import {
|
|||
PIN_PARTICIPANT,
|
||||
SCREENSHARE_PARTICIPANT_NAME_CHANGED,
|
||||
SET_LOADABLE_AVATAR_URL,
|
||||
RAISE_HAND_UPDATED
|
||||
RAISE_HAND_UPDATED,
|
||||
OVERWRITE_PARTICIPANT_NAME,
|
||||
OVERWRITE_PARTICIPANTS_NAMES
|
||||
} from './actionTypes';
|
||||
import {
|
||||
DISCO_REMOTE_CONTROL_FEATURE
|
||||
|
@ -653,3 +655,31 @@ export function localParticipantAudioLevelChanged(level) {
|
|||
level
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the name of the participant with the given id.
|
||||
*
|
||||
* @param {string} id - Participant id;.
|
||||
* @param {string} name - New participant name.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function overwriteParticipantName(id, name) {
|
||||
return {
|
||||
type: OVERWRITE_PARTICIPANT_NAME,
|
||||
id,
|
||||
name
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the names of the given participants.
|
||||
*
|
||||
* @param {Array<Object>} participantList - The list of participants to overwrite.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export function overwriteParticipantsNames(participantList) {
|
||||
return {
|
||||
type: OVERWRITE_PARTICIPANTS_NAMES,
|
||||
participantList
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import { batch } from 'react-redux';
|
|||
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
import { approveParticipant } from '../../av-moderation/actions';
|
||||
import { UPDATE_BREAKOUT_ROOMS } from '../../breakout-rooms/actionTypes';
|
||||
import { getBreakoutRooms } from '../../breakout-rooms/functions';
|
||||
import { toggleE2EE } from '../../e2ee/actions';
|
||||
import { MAX_MODE } from '../../e2ee/constants';
|
||||
import {
|
||||
|
@ -34,6 +36,8 @@ import {
|
|||
LOCAL_PARTICIPANT_AUDIO_LEVEL_CHANGED,
|
||||
LOCAL_PARTICIPANT_RAISE_HAND,
|
||||
MUTE_REMOTE_PARTICIPANT,
|
||||
OVERWRITE_PARTICIPANTS_NAMES,
|
||||
OVERWRITE_PARTICIPANT_NAME,
|
||||
PARTICIPANT_DISPLAY_NAME_CHANGED,
|
||||
PARTICIPANT_JOINED,
|
||||
PARTICIPANT_LEFT,
|
||||
|
@ -44,6 +48,7 @@ import {
|
|||
localParticipantIdChanged,
|
||||
localParticipantJoined,
|
||||
localParticipantLeft,
|
||||
overwriteParticipantName,
|
||||
participantLeft,
|
||||
participantUpdated,
|
||||
raiseHand,
|
||||
|
@ -68,6 +73,7 @@ import {
|
|||
hasRaisedHand,
|
||||
isLocalParticipantModerator
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
import { PARTICIPANT_JOINED_FILE, PARTICIPANT_LEFT_FILE } from './sounds';
|
||||
import './subscriber';
|
||||
|
||||
|
@ -231,6 +237,74 @@ MiddlewareRegistry.register(store => next => action => {
|
|||
case PARTICIPANT_UPDATED:
|
||||
return _participantJoinedOrUpdated(store, next, action);
|
||||
|
||||
case OVERWRITE_PARTICIPANTS_NAMES: {
|
||||
const { participantList } = action;
|
||||
|
||||
if (!Array.isArray(participantList)) {
|
||||
logger.error('Overwrite names failed. Argument is not an array.');
|
||||
|
||||
return;
|
||||
}
|
||||
batch(() => {
|
||||
participantList.forEach(p => {
|
||||
store.dispatch(overwriteParticipantName(p.id, p.name));
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
case OVERWRITE_PARTICIPANT_NAME: {
|
||||
const { dispatch, getState } = store;
|
||||
const state = getState();
|
||||
const { id, name } = action;
|
||||
|
||||
let breakoutRoom = false, identifier = id;
|
||||
|
||||
if (id.indexOf('@') !== -1) {
|
||||
identifier = id.slice(id.indexOf('/') + 1);
|
||||
breakoutRoom = true;
|
||||
action.id = identifier;
|
||||
}
|
||||
|
||||
if (breakoutRoom) {
|
||||
const rooms = getBreakoutRooms(state);
|
||||
const roomCounter = state['features/breakout-rooms'].roomCounter;
|
||||
const newRooms = {};
|
||||
|
||||
Object.entries(rooms).forEach(([ key, r ]) => {
|
||||
const participants = r?.participants || {};
|
||||
const jid = Object.keys(participants).find(p =>
|
||||
p.slice(p.indexOf('/') + 1) === identifier);
|
||||
|
||||
if (jid) {
|
||||
newRooms[key] = {
|
||||
...r,
|
||||
participants: {
|
||||
...participants,
|
||||
[jid]: {
|
||||
...participants[jid],
|
||||
displayName: name
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
newRooms[key] = r;
|
||||
}
|
||||
});
|
||||
dispatch({
|
||||
type: UPDATE_BREAKOUT_ROOMS,
|
||||
rooms,
|
||||
roomCounter,
|
||||
updatedNames: true
|
||||
});
|
||||
} else {
|
||||
dispatch(participantUpdated({
|
||||
id: identifier,
|
||||
name
|
||||
}));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return next(action);
|
||||
|
@ -491,6 +565,7 @@ function _maybePlaySounds({ getState, dispatch }, action) {
|
|||
*/
|
||||
function _participantJoinedOrUpdated(store, next, action) {
|
||||
const { dispatch, getState } = store;
|
||||
const { overwrittenNameList } = store.getState()['features/base/participants'];
|
||||
const { participant: { avatarURL, email, id, local, name, raisedHandTimestamp } } = action;
|
||||
|
||||
// Send an external update of the local participant's raised hand state
|
||||
|
@ -508,6 +583,10 @@ function _participantJoinedOrUpdated(store, next, action) {
|
|||
}
|
||||
}
|
||||
|
||||
if (overwrittenNameList[id]) {
|
||||
action.participant.name = overwrittenNameList[id];
|
||||
}
|
||||
|
||||
// Allow the redux update to go through and compare the old avatar
|
||||
// to the new avatar and emit out change events if necessary.
|
||||
const result = next(action);
|
||||
|
|
|
@ -7,6 +7,7 @@ import { ReducerRegistry, set } from '../redux';
|
|||
|
||||
import {
|
||||
DOMINANT_SPEAKER_CHANGED,
|
||||
OVERWRITE_PARTICIPANT_NAME,
|
||||
PARTICIPANT_ID_CHANGED,
|
||||
PARTICIPANT_JOINED,
|
||||
PARTICIPANT_LEFT,
|
||||
|
@ -63,6 +64,7 @@ const DEFAULT_STATE = {
|
|||
haveParticipantWithScreenSharingFeature: false,
|
||||
local: undefined,
|
||||
localScreenShare: undefined,
|
||||
overwrittenNameList: {},
|
||||
pinnedParticipant: undefined,
|
||||
raisedHandsQueue: [],
|
||||
remote: new Map(),
|
||||
|
@ -413,6 +415,17 @@ ReducerRegistry.register('features/base/participants', (state = DEFAULT_STATE, a
|
|||
|
||||
return { ...state };
|
||||
}
|
||||
case OVERWRITE_PARTICIPANT_NAME: {
|
||||
const { id, name } = action;
|
||||
|
||||
return {
|
||||
...state,
|
||||
overwrittenNameList: {
|
||||
...state.overwrittenNameList,
|
||||
[id]: name
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
|
|
|
@ -7,9 +7,10 @@ import { editMessage, MESSAGE_TYPE_REMOTE } from '../chat';
|
|||
|
||||
import { UPDATE_BREAKOUT_ROOMS } from './actionTypes';
|
||||
import { moveToRoom } from './actions';
|
||||
import { getBreakoutRooms } from './functions';
|
||||
import logger from './logger';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Registers a change handler for state['features/base/conference'].conference to
|
||||
* set the event listeners needed for the breakout rooms feature to operate.
|
||||
|
@ -25,6 +26,9 @@ StateListenerRegistry.register(
|
|||
|
||||
conference.on(JitsiConferenceEvents.BREAKOUT_ROOMS_UPDATED, ({ rooms, roomCounter }) => {
|
||||
logger.debug('Room list updated');
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.API.notifyBreakoutRoomsUpdated(rooms);
|
||||
}
|
||||
dispatch({
|
||||
type: UPDATE_BREAKOUT_ROOMS,
|
||||
rooms,
|
||||
|
@ -36,16 +40,50 @@ StateListenerRegistry.register(
|
|||
|
||||
MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
const { type } = action;
|
||||
const result = next(action);
|
||||
|
||||
switch (type) {
|
||||
case UPDATE_BREAKOUT_ROOMS: {
|
||||
const { messages } = getState()['features/chat'];
|
||||
// edit name if it was overwritten
|
||||
if (!action.updatedNames) {
|
||||
const { overwrittenNameList } = getState()['features/base/participants'];
|
||||
|
||||
if (Object.keys(overwrittenNameList).length > 0) {
|
||||
const newRooms = {};
|
||||
|
||||
Object.entries(action.rooms).forEach(([ key, r ]) => {
|
||||
let participants = r?.participants || {};
|
||||
let jid;
|
||||
|
||||
for (const id of Object.keys(overwrittenNameList)) {
|
||||
jid = Object.keys(participants).find(p => p.slice(p.indexOf('/') + 1) === id);
|
||||
|
||||
if (jid) {
|
||||
participants = {
|
||||
...participants,
|
||||
[jid]: {
|
||||
...participants[jid],
|
||||
displayName: overwrittenNameList[id]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
newRooms[key] = {
|
||||
...r,
|
||||
participants
|
||||
};
|
||||
});
|
||||
|
||||
action.rooms = newRooms;
|
||||
}
|
||||
}
|
||||
|
||||
// edit the chat history to match names for participants in breakout rooms
|
||||
const { messages } = getState()['features/chat'];
|
||||
|
||||
messages && messages.forEach(m => {
|
||||
if (m.messageType === MESSAGE_TYPE_REMOTE && !getParticipantById(getState(), m.id)) {
|
||||
const rooms = getBreakoutRooms(getState);
|
||||
const rooms = action.rooms;
|
||||
|
||||
for (const room of Object.values(rooms)) {
|
||||
// $FlowExpectedError
|
||||
|
@ -65,5 +103,5 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
|||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return next(action);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue