diff --git a/conference.js b/conference.js index 197a64a50ce..4af2765d6c2 100644 --- a/conference.js +++ b/conference.js @@ -111,6 +111,7 @@ import { import { getLocalParticipant, getNormalizedDisplayName, + getParticipantByIdOrUndefined, getVirtualScreenshareParticipantByOwnerId } from './react/features/base/participants/functions'; import { updateSettings } from './react/features/base/settings/actions'; @@ -1775,12 +1776,17 @@ export default { room.addCommandListener( this.commands.defaults.AVATAR_URL, (data, from) => { - APP.store.dispatch( - participantUpdated({ - conference: room, - id: from, - avatarURL: data.value - })); + const participant = getParticipantByIdOrUndefined(APP.store, from); + + // if already set from presence(jwt), skip the command processing + if (!participant?.avatarURL) { + APP.store.dispatch( + participantUpdated({ + conference: room, + id: from, + avatarURL: data.value + })); + } }); room.on( diff --git a/modules/API/API.js b/modules/API/API.js index d4887e3d7a4..10a7c8a1fd1 100644 --- a/modules/API/API.js +++ b/modules/API/API.js @@ -489,7 +489,9 @@ function initCommands() { sendAnalytics(createApiEvent('email.changed')); APP.conference.changeLocalEmail(email); }, - 'avatar-url': avatarUrl => { + 'avatar-url': avatarUrl => { // @deprecated + console.warn('Using command avatarUrl is deprecated. Use context.user.avatar in the jwt.'); + sendAnalytics(createApiEvent('avatar.url.changed')); APP.conference.changeLocalAvatarUrl(avatarUrl); }, diff --git a/react/features/base/conference/actions.any.ts b/react/features/base/conference/actions.any.ts index 64a00b39799..86da22e2f4a 100644 --- a/react/features/base/conference/actions.any.ts +++ b/react/features/base/conference/actions.any.ts @@ -25,7 +25,7 @@ import { participantSourcesUpdated, participantUpdated } from '../participants/actions'; -import { getNormalizedDisplayName } from '../participants/functions'; +import { getNormalizedDisplayName, getParticipantByIdOrUndefined } from '../participants/functions'; import { IJitsiParticipant } from '../participants/types'; import { toState } from '../redux/functions'; import { @@ -277,11 +277,18 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[ conference.addCommandListener( AVATAR_URL_COMMAND, - (data: { value: string; }, id: string) => dispatch(participantUpdated({ - conference, - id, - avatarURL: data.value - }))); + (data: { value: string; }, id: string) => { + const participant = getParticipantByIdOrUndefined(state, id); + + // if already set from presence(jwt), skip the command processing + if (!participant?.avatarURL) { + return dispatch(participantUpdated({ + conference, + id, + avatarURL: data.value + })); + } + }); conference.addCommandListener( EMAIL_COMMAND, (data: { value: string; }, id: string) => dispatch(participantUpdated({ diff --git a/react/features/base/conference/functions.ts b/react/features/base/conference/functions.ts index f08224d1182..14d86e28156 100644 --- a/react/features/base/conference/functions.ts +++ b/react/features/base/conference/functions.ts @@ -90,7 +90,9 @@ export function commonUserJoinedHandling( } else { const isReplacing = user?.isReplacing(); + // the identity and avatar come from jwt and never change in the presence dispatch(participantJoined({ + avatarURL: user.getIdentity()?.user?.avatar, botType: user.getBotType(), conference, id,