fix: fallback to legacy media URL on 401, fix EC avatar letter centering

downloadMedia: on 401 (SW session race or allow_redirect hop stripping
auth), retry via /_matrix/media/v3/ which is public on this homeserver
(allow_public_access_to_media_repo: true). Fixes images not loading
after sending, and avatar 401s in call prescreen tiles.

CallEmbed: inject flex-centering CSS for EC 0.19.4 participant avatar
container so the initial letter is correctly centered in its circle.
CSS class names are scoped to _avatarContainer_1mrho_40 in EC 0.19.4.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 22:01:45 -04:00
parent 8dec8169dc
commit 73420242d0
2 changed files with 20 additions and 3 deletions
+3
View File
@@ -321,6 +321,9 @@ export class CallEmbed {
'html, body { background: none !important; }',
`:root { color-scheme: ${this.themeKind}; }`,
'[style*="height: 0"][style*="z-index: 1"][style*="align-self: center"] { display: none !important; }',
// EC 0.19.4: avatar uses line-height centering which breaks in some tile sizes;
// override with flexbox for reliable centering of the initial letter.
'._avatarContainer_1mrho_40 ._avatar_va14e_8 { display: flex !important; align-items: center !important; justify-content: center !important; line-height: 1 !important; }',
].join('\n');
}
+17 -3
View File
@@ -299,9 +299,23 @@ export const mxcUrlToHttp = (
export const downloadMedia = async (src: string): Promise<Blob> => {
// this request is authenticated by service worker
const res = await fetch(src, { method: 'GET' });
if (!res.ok) throw new Error(`Media download failed: ${res.status} ${res.statusText}`);
const blob = await res.blob();
return blob;
if (res.ok) return res.blob();
// On 401 fall back to the legacy unauthenticated media path.
// This covers the race where the SW session isn't set yet, or when matrix-js-sdk
// appends ?allow_redirect=true and Synapse strips auth on the redirect hop.
// Requires allow_public_access_to_media_repo: true on the homeserver.
if (res.status === 401) {
const legacyUrl = src
.replace('/_matrix/client/v1/media/download/', '/_matrix/media/v3/download/')
.replace('/_matrix/client/v1/media/thumbnail/', '/_matrix/media/v3/thumbnail/');
if (legacyUrl !== src) {
const legacyRes = await fetch(legacyUrl, { method: 'GET' });
if (legacyRes.ok) return legacyRes.blob();
}
}
throw new Error(`Media download failed: ${res.status} ${res.statusText}`);
};
export const downloadEncryptedMedia = async (