fix(embeds): quality pass — close button, focus, a11y, perf, SoundCloud revert

From the quality-review agents:
- Revert on.soundcloud.com support: the w.soundcloud widget doesn't follow the
  redirect (needs an oEmbed resolve, deferred).
- Add a Close button to playing video/TikTok embeds and a Collapse button to the
  expanded X post — playback was previously one-way (only escapable by scrolling).
- focus-visible ring on the embed facade (folds resets outline:none, leaving
  keyboard users with no indicator).
- Only subscribe to resize postMessages while the iframe is mounted (was attaching
  a global listener per Instagram/Reddit facade before play).
- TikTok oEmbed fetch now uses AbortController (abort on unmount) + aria-busy /
  'Loading…' label on the resolving spinner.
- Decorative facade thumbnails use alt="" (parent already names them); drop the
  dangling-colon aria-labels when there's no title.
- Cap URL previews at 6 per message so a link-dump can't spawn dozens of fetches.

Tests 728. No CSP change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 00:45:51 -04:00
parent a28c305835
commit a52c9e12a4
5 changed files with 98 additions and 24 deletions
+3 -1
View File
@@ -86,7 +86,9 @@ export function RenderMessageContent({
eventId,
}: RenderMessageContentProps) {
const renderUrlsPreview = (urls: string[]) => {
const filteredUrls = urls.filter((url) => !testMatrixTo(url));
// Cap previews per message so a link-dump doesn't spawn dozens of preview
// fetches + iframes at once.
const filteredUrls = urls.filter((url) => !testMatrixTo(url)).slice(0, 6);
if (filteredUrls.length === 0) return undefined;
return (
<UrlPreviewHolder>