fix(multi-stream) update screenshare display name (#11376)

This commit is contained in:
William Liang 2022-04-14 13:07:17 -04:00 committed by GitHub
parent a6ad592d25
commit 4a375aa2a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 114 additions and 9 deletions

View File

@ -54,7 +54,11 @@ import {
sendLocalParticipant,
nonParticipantMessageReceived
} from './react/features/base/conference';
import { getReplaceParticipant, getMultipleVideoSupportFeatureFlag } from './react/features/base/config/functions';
import {
getReplaceParticipant,
getMultipleVideoSupportFeatureFlag,
getSourceNameSignalingFeatureFlag
} from './react/features/base/config/functions';
import {
checkAndNotifyForNewDevice,
getAvailableDevices,
@ -93,6 +97,7 @@ import {
dominantSpeakerChanged,
getLocalParticipant,
getNormalizedDisplayName,
getScreenshareParticipantByOwnerId,
localParticipantAudioLevelChanged,
localParticipantConnectionStatusChanged,
localParticipantRoleChanged,
@ -102,6 +107,7 @@ import {
participantPresenceChanged,
participantRoleChanged,
participantUpdated,
screenshareParticipantDisplayNameChanged,
updateRemoteParticipantFeatures
} from './react/features/base/participants';
import {
@ -2258,6 +2264,17 @@ export default {
id,
name: formattedDisplayName
}));
if (getSourceNameSignalingFeatureFlag(state)) {
const screenshareParticipantId = getScreenshareParticipantByOwnerId(state, id)?.id;
if (screenshareParticipantId) {
APP.store.dispatch(
screenshareParticipantDisplayNameChanged(screenshareParticipantId, formattedDisplayName)
);
}
}
APP.API.notifyDisplayNameChanged(id, {
displayName: formattedDisplayName,
formattedDisplayName:

View File

@ -173,6 +173,17 @@ export const HIDDEN_PARTICIPANT_LEFT = 'HIDDEN_PARTICIPANT_LEFT';
*/
export const SET_LOADABLE_AVATAR_URL = 'SET_LOADABLE_AVATAR_URL';
/**
* The type of Redux action which notifies that the screenshare participant's display name has changed.
*
* {
* type: SCREENSHARE_PARTICIPANT_NAME_CHANGED,
* id: string,
* name: string
* }
*/
export const SCREENSHARE_PARTICIPANT_NAME_CHANGED = 'SCREENSHARE_PARTICIPANT_NAME_CHANGED';
/**
* Raises hand for the local participant.
* {

View File

@ -16,6 +16,7 @@ import {
PARTICIPANT_LEFT,
PARTICIPANT_UPDATED,
PIN_PARTICIPANT,
SCREENSHARE_PARTICIPANT_NAME_CHANGED,
SET_LOADABLE_AVATAR_URL,
RAISE_HAND_UPDATED
} from './actionTypes';
@ -432,6 +433,25 @@ export function participantRoleChanged(id, role) {
});
}
/**
* Action to signal that a participant's display name has changed.
*
* @param {string} id - Screenshare participant's ID.
* @param {name} name - The new display name of the screenshare participant's owner.
* @returns {{
* type: SCREENSHARE_PARTICIPANT_NAME_CHANGED,
* id: string,
* name: string
* }}
*/
export function screenshareParticipantDisplayNameChanged(id, name) {
return {
type: SCREENSHARE_PARTICIPANT_NAME_CHANGED,
id,
name
};
}
/**
* Action to signal that some of participant properties has been changed.
*

View File

@ -105,6 +105,22 @@ export function getLocalScreenShareParticipant(stateful: Object | Function) {
return state.localScreenShare;
}
/**
* Returns screenshare participant.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state features/base/participants.
* @param {string} id - The owner ID of the screenshare participant to retrieve.
* @returns {(Participant|undefined)}
*/
export function getScreenshareParticipantByOwnerId(stateful: Object | Function, id: string) {
const track = getTrackByMediaTypeAndParticipant(
toState(stateful)['features/base/tracks'], MEDIA_TYPE.SCREENSHARE, id
);
return getParticipantById(stateful, track?.jitsiTrack.getSourceName());
}
/**
* Normalizes a display name so then no invalid values (padding, length...etc)
* can be set.
@ -244,14 +260,12 @@ export function getParticipantCountWithFake(stateful: Object | Function) {
/**
* Returns participant's display name.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's
* {@code getState} function to be used to retrieve the state.
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state.
* @param {string} id - The ID of the participant's display name to retrieve.
* @returns {string}
*/
export function getParticipantDisplayName(
stateful: Object | Function,
id: string) {
export function getParticipantDisplayName(stateful: Object | Function, id: string) {
const participant = getParticipantById(stateful, id);
const {
defaultLocalDisplayName,
@ -259,6 +273,10 @@ export function getParticipantDisplayName(
} = toState(stateful)['features/base/config'];
if (participant) {
if (participant.isFakeScreenShareParticipant) {
return getScreenshareParticipantDisplayName(stateful, id);
}
if (participant.name) {
return participant.name;
}
@ -271,6 +289,20 @@ export function getParticipantDisplayName(
return defaultRemoteDisplayName;
}
/**
* Returns screenshare participant's display name.
*
* @param {(Function|Object)} stateful - The (whole) redux state, or redux's {@code getState} function to be used to
* retrieve the state.
* @param {string} id - The ID of the screenshare participant's display name to retrieve.
* @returns {string}
*/
export function getScreenshareParticipantDisplayName(stateful: Object | Function, id: string) {
const owner = getParticipantById(stateful, getFakeScreenShareParticipantOwnerId(id));
return `${owner.name}'s screen`;
}
/**
* Returns the presence status of a participant associated with the passed id.
*

View File

@ -13,6 +13,7 @@ import {
PARTICIPANT_UPDATED,
PIN_PARTICIPANT,
RAISE_HAND_UPDATED,
SCREENSHARE_PARTICIPANT_NAME_CHANGED,
SET_LOADABLE_AVATAR_URL
} from './actionTypes';
import { LOCAL_PARTICIPANT_DEFAULT_ID, PARTICIPANT_ROLE } from './constants';
@ -209,6 +210,23 @@ ReducerRegistry.register('features/base/participants', (state = DEFAULT_STATE, a
...state
};
}
case SCREENSHARE_PARTICIPANT_NAME_CHANGED: {
const { id, name } = action;
if (state.sortedRemoteFakeScreenShareParticipants.has(id)) {
state.sortedRemoteFakeScreenShareParticipants.delete(id);
const sortedRemoteFakeScreenShareParticipants = [ ...state.sortedRemoteFakeScreenShareParticipants ];
sortedRemoteFakeScreenShareParticipants.push([ id, name ]);
sortedRemoteFakeScreenShareParticipants.sort((a, b) => a[1].localeCompare(b[1]));
state.sortedRemoteFakeScreenShareParticipants = new Map(sortedRemoteFakeScreenShareParticipants);
}
return { ...state };
}
case PARTICIPANT_JOINED: {
const participant = _participantJoined(action);
const { id, isFakeParticipant, isFakeScreenShareParticipant, isLocalScreenShare, name, pinned } = participant;

View File

@ -400,7 +400,7 @@ function createFakeScreenShareParticipant({ dispatch, getState }, { track }) {
id: track.jitsiTrack.getSourceName(),
isFakeScreenShareParticipant: true,
isLocalScreenShare: track?.jitsiTrack.isLocal(),
name: `${participant.name}'s screen`
name: participant.name
}));
} else {
logger.error(`Failed to create a screenshare participant for participantId: ${participantId}`);

View File

@ -6,7 +6,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import { isDisplayNameVisible } from '../../../base/config/functions.any';
import { getLocalParticipant } from '../../../base/participants';
import { getLocalParticipant, getParticipantDisplayName } from '../../../base/participants';
import { withPixelLineHeight } from '../../../base/styles/functions.web';
import { getLargeVideoParticipant } from '../../../large-video/functions';
import { isToolboxVisible } from '../../../toolbox/functions.web';
@ -44,8 +44,8 @@ const useStyles = makeStyles(theme => {
const StageParticipantNameLabel = () => {
const classes = useStyles();
const largeVideoParticipant = useSelector(getLargeVideoParticipant);
const nameToDisplay = largeVideoParticipant?.name;
const selectedId = largeVideoParticipant?.id;
const nameToDisplay = useSelector(state => getParticipantDisplayName(state, selectedId));
const localParticipant = useSelector(getLocalParticipant);
const localId = localParticipant?.id;

View File

@ -12,6 +12,13 @@ StateListenerRegistry.register(
/* selector */ state => state['features/video-layout'].remoteScreenShares,
/* listener */ (remoteScreenShares, store) => updateRemoteParticipants(store));
/**
* Listens for changes to the remote screenshare participants to recompute the reordered list of the remote endpoints.
*/
StateListenerRegistry.register(
/* selector */ state => state['features/base/participants'].sortedRemoteFakeScreenShareParticipants,
/* listener */ (sortedRemoteFakeScreenShareParticipants, store) => updateRemoteParticipants(store));
/**
* Listens for changes to the dominant speaker to recompute the reordered list of the remote endpoints.
*/