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
pull/21833/head
David Baker 2021-03-17 19:09:43 +00:00
parent 9ac5f4d2ee
commit f6a87386bc
1 changed files with 17 additions and 2 deletions

View File

@ -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<IState> {
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<IState> {
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<IState> {
// 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});
};