Files
ThreadNet-Web/packages/shared-components/.storybook/waitForImages.ts
T
6c2c962588 Collapsed URL previews in timeline (#34165)
* Fetches link previews for all links in message (instead of just the first one)

* message url component to display preview for multiple urls

* Revert visible behaviour back to only showing one URL preview

While fetching all link previews in the text message.

* Moved URL preview VM to MessageComposer

* Added com.beeper.linkpreviews to messages sent with the markdown compositor

* MSC 4452 implemented for the older (markdown) composer

* claude told me to use logger instead of console

* Previews generated with snapshot instead of vm

* moved attachPreviews to a separate file

* added attach URL previews to rich text editor

* don't let attachUrlPreviews block clearning the composer

* fixed linter errors

* moved url preview behind labs feature gate

* passed linters

* moved lab feature checking to where attach preview is used

* claude wrote some unit tests for url previewing

* fixed linter errors

* added feature to labs.md

* fixed linter errors

* fixed oxfmt error

* set previews to none if all previews failed

* resolved PR reviews besides the ones that requires a larger code change

* moved url preview VM creation to message composer

* removed delay when clearing composer url preview on message send

* Collpased URL previews in timeline

* CSS for collapsed URL previews

* fixed typo thing?

* update class for this component

* remove dead code from css

* minor changes to stop using globals everywhere

* moved debouncing responsibility to urlpreviewVM

* minor lint fixes

* added comment

* remove composer content from the state of urlpreview, moved it to the vm

* urlpreviewwrapper depends on the vm only

* added comments

* edited the comment

* one slow preview no longer blocks up the current batch of previews from loading

* show failed and loading url previews

* collapsed urlpreview styles to match the expanded preview

* css formtting

* composer url preview summary bar

* prefer site icon

* Revert "Merge branch 'url-preview-loading-indicator' into collapsed-url-previews"

This reverts commit b7a1ccb0e74661458e16c128814ba1939bdf400e, reversing
changes made to 1340b216407cf9af95741174819f97a144c13bb3.

* updated shared-components Punit test snapshots

* updated snapshots

* wait for tall image to load before capturing snapshot (claude wrote this)

* try remove requestanimation frame

* use semantic tokens instead of specifying hard values in some places

* Update packages/shared-components/src/room/timeline/event-tile/UrlPreviewGroupView/LinkPreview/LinkPreview.tsx

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>

* changed css so previews looks less horrendous on different front sizes, particularly very small font sizes

* updated unit test snapshots

* regenerated playwright story screenshots

---------

Co-authored-by: Florian Duros <florian.duros@ormaz.fr>
2026-07-20 09:39:48 +00:00

38 lines
1.5 KiB
TypeScript

/*
* Copyright 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
/**
* A Storybook `play` helper that waits for every CSS `background-image` inside the
* rendered story to finish decoding before the visual-regression snapshot is taken.
*
* Components such as `LinkPreview` render their thumbnails as CSS `background-image`s
* rather than `<img>` elements, so there is no load event for the snapshot machinery
* to await. A larger image (e.g. the tall test image) can therefore still be decoding
* when the screenshot is captured, producing a non-deterministic placeholder frame.
* Decoding the images up-front populates the browser cache so the background paints
* synchronously on the next frame.
*/
export async function waitForBackgroundImages(root: HTMLElement): Promise<void> {
const urls = new Set<string>();
for (const el of root.querySelectorAll<HTMLElement>("*")) {
const match = /url\(["']?(.+?)["']?\)/.exec(getComputedStyle(el).backgroundImage);
if (match) urls.add(match[1]);
}
await Promise.all(
[...urls].map(async (src) => {
const img = new Image();
img.src = src;
try {
await img.decode();
} catch {
// Ignore images that fail to decode; the snapshot captures whatever renders.
}
}),
);
}