From f6a87386bc2f0b15892920dd19d85820b9eeb647 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 Mar 2021 19:09:43 +0000 Subject: [PATCH] Fix username showing instead of display name in Jitsi widgets If you opened element and entered a jitsi conference straight away in the room you landed in, your jitsi display name would be your matrix username rather than your display name. This was because OwnProfileStore was still busy fetching your profile from the server while the room, and therefore jitsi widget, was rendered. Blocking these widgets loading on this profile fetch completing isn't really an option, so store the profile data in localstorage and seed OwnProfileStore with the values from there. Bonus: the name in the top left will now be your display name as soon as the app is loaded, rather than being your username for the first several seconds after you load the app. Fixes https://github.com/vector-im/element-web/issues/16577 --- src/stores/OwnProfileStore.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/stores/OwnProfileStore.ts b/src/stores/OwnProfileStore.ts index 8983380fec..15884b8ad6 100644 --- a/src/stores/OwnProfileStore.ts +++ b/src/stores/OwnProfileStore.ts @@ -28,13 +28,22 @@ interface IState { avatarUrl?: string; } +const KEY_DISPLAY_NAME = "mx_profile_displayname"; +const KEY_AVATAR_URL = "mx_profile_avatar_url"; + export class OwnProfileStore extends AsyncStoreWithClient { private static internalInstance = new OwnProfileStore(); private monitoredUser: User; private constructor() { - super(defaultDispatcher, {}); + // seed from localstorage because otherwise we won't get these values until a whole network + // round-trip after the client is ready, and we often load widgets in that time, and we'd + // and up passing them an incorrect display name + super(defaultDispatcher, { + displayName: window.localStorage.getItem(KEY_DISPLAY_NAME), + avatarUrl: window.localStorage.getItem(KEY_AVATAR_URL), + }); } public static get instance(): OwnProfileStore { @@ -73,7 +82,11 @@ export class OwnProfileStore extends AsyncStoreWithClient { public getHttpAvatarUrl(size = 0): string { if (!this.avatarMxc) return null; const adjustedSize = size > 1 ? size : undefined; // don't let negatives or zero through - return this.matrixClient.mxcUrlToHttp(this.avatarMxc, adjustedSize, adjustedSize); + + // XXX: We use MatrixClientPeg here rather than this.matrixClient because otherwise we'll + // race because our data stores aren't set up consistently enough that this will all be + // initialised with a store before these getter methods are called. + return MatrixClientPeg.get().mxcUrlToHttp(this.avatarMxc, adjustedSize, adjustedSize); } protected async onNotReady() { @@ -110,6 +123,8 @@ export class OwnProfileStore extends AsyncStoreWithClient { // We specifically do not use the User object we stored for profile info as it // could easily be wrong (such as per-room instead of global profile). const profileInfo = await this.matrixClient.getProfileInfo(this.matrixClient.getUserId()); + if (profileInfo.displayname) window.localStorage.setItem(KEY_DISPLAY_NAME, profileInfo.displayname); + if (profileInfo.avatar_url) window.localStorage.setItem(KEY_AVATAR_URL, profileInfo.avatar_url); await this.updateState({displayName: profileInfo.displayname, avatarUrl: profileInfo.avatar_url}); };