You've already forked element-web
mirror of
https://github.com/element-hq/element-web.git
synced 2026-10-24 23:19:26 +03:00
* Fix virtual-core scroll compensation during in-flight scrolls Patch fixes so the timeline holds its place when rows change size while a scroll is still settling: decisions use the up-to-date scroll position, the stay-at-bottom correction retries if the browser clamped it, and corrections now also apply while scrolling upwards. All candidates for upstreaming. * Use the timeline's own 4px tolerance when deciding it is at the bottom * Fix full-width timeline rows overflowing the right-hand edge The list kept the browser's default 40px indent, which pushed every row 40px too wide. Only full-width rows (the read marker line, date separators) showed it. * Add a labelled "New" style to the read marker The new design: a green line with a "New" label at its right-hand end. Opt-in via a new label prop, so the legacy timeline keeps its plain line. Also adds an as="div" option for callers that already provide the list item. * Fix the reserved image box collapsing while the image loads The box meant to hold a photo's space before it downloads was being sized to zero by the browser, so the message grew when the photo arrived and shoved the timeline. Failed images also keep the reserved height now instead of collapsing to one line. * Fix the timeline stalling at the top with more history available A request to load more history that arrived while a fetch was already running was silently dropped, and the view would sometimes never re-ask — leaving the timeline stuck at the top until the user jiggled the scroll. Such requests are now remembered and run when the current fetch finishes, matching what the old ScrollPanel did. * Render polls at full size straight away The question and options are in the event we already have; only votes need fetching. Rendering them immediately stops a freshly loaded poll growing ~180px when its votes arrive and shoving the timeline. * Add a compact reply preview that keeps one height while it loads For the new timeline: the quoted message shows immediately when it is already loaded, a fixed-height skeleton stands in while one is fetched, and the rows are pinned to one height so the preview never resizes and shoves the messages around it. Opt-in via a new EventTile prop; the legacy timeline is unchanged. * Add the new timeline to the room view behind a labs flag The new virtualised timeline panel, rendering events through the legacy EventTile for now. Enabled by the "Improved timeline scrolling and navigation" labs setting; the existing timeline is untouched when the flag is off. * Address SonarCloud findings Mark component props read-only, hoist the timeline row renderer to module level, pass the quoted event into the reply header fetch instead of re-reading state after the await, and drop a TODO tag. * Fix image overflow in narrow panes, and tidy up timeline rows The clamp stopping a reserved image box from overflowing its container lived in new-timeline CSS, but the box is drawn by a shared component the legacy timeline and thread panel use too, so images could overflow there. Moved it onto the component's own link wrapper, beside the width that makes it necessary: a 757px image in a 350px pane rendered at 757px before and 350px after, and still takes its natural size when there is room. Also, for the new timeline's rows: skip a row whose event has gone from the room rather than letting the tile crash and lose the whole timeline, drop a leftover placeholder that drew the word "Gap", and give the pagination spinner a label screen readers can announce. * Add vis baseline and padding for the labelled read marker story The story had no left/right inset, so the label rendered flush against the edge of the frame and was clipped. Pads it like the timeline does, and adds the baseline image the visual test needs. * Add tests for the new timeline panel, tile adapter and reply preview Covers how the panel draws each kind of row — messages, the read marker, date separators, the loading spinner, gaps — along with the layout fallback, edit state scoping, and skipping a row whose event has gone. Also covers the tile adapter's pass-through and the reply preview's three states (already loaded, skeleton while fetching, and error). The panel's tests stand in a stub for the virtualised TimelineView, which needs real layout the test environment doesn't have and has its own tests. * Show the read marker properly in its stories The stories dropped the marker into a plain list with no room around it, so the browser's list styling came along for the ride: every baseline had a bullet in it, and the rule was pressed against the top edge of the frame, hard to see and liable to be clipped by the marker's own 1px offset. The hidden-marker story was a picture of a bullet and nothing else. Resetting the list and insetting the stories draws the marker the way a timeline does — a hairline, evenly inset, with room above it. * Update the bubble media baseline for the reserved-size fix The second media box in that story was being shrunk to fit its content (255px wide) rather than taking the size the event declares; with the reserved box now holding, it renders at 297px and its spinner and timestamp sit inside it instead of overflowing. Every other story in the timeline suite is unchanged. * Create new-timeline.spec.ts * Move panel CSS to mx_NewTimelinePanel and use new DateSeperator * fix tanstack virtial patch and remove reply clamping to 1 line clamping the reply to one line is awkward and not real needed now that above the fold compensation works. it will visually expand when on screen. One of our tanstack fixes was fixed upstreamed so can be removed. * Update media---bubble---default-auto.png
66 lines
2.7 KiB
Plaintext
66 lines
2.7 KiB
Plaintext
/*
|
|
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.
|
|
*/
|
|
|
|
/*
|
|
* The new timeline's reply-preview rules — the loading skeleton and the row
|
|
* heights that keep it height-neutral — live alongside the reply components in
|
|
* _ReplyChain.pcss / _ReplyTile.pcss.
|
|
*/
|
|
.mx_NewTimelinePanel {
|
|
/* Fill the room view body, like the old message panel does. */
|
|
height: 100%;
|
|
|
|
/* Kept mounted but invisible, e.g. while search results are shown, so the
|
|
timeline keeps its scroll position and loaded window. */
|
|
&.mx_NewTimelinePanel_hidden {
|
|
display: none;
|
|
}
|
|
|
|
/* The virtualized timeline renders its rows as an <ol role="list"> of <li>
|
|
tiles (mx_TimelineView_list / mx_TimelineView_tile in TimelineView; the <ol>
|
|
and <li> reset their own list markers inline). Inset the tile content to
|
|
match the legacy mx_RoomView_MessageList padding so messages don't sit flush
|
|
against the panel edges.
|
|
|
|
The inset goes on the tiles rather than the <ol>: the rows are absolutely
|
|
positioned, so their containing block is the <ol>'s padding box and padding
|
|
there would not inset them. box-sizing + padding-inline on each row does,
|
|
and — being horizontal only — leaves the virtualizer's measured row heights
|
|
and vertical offsets untouched. */
|
|
.mx_TimelineView_tile {
|
|
box-sizing: border-box;
|
|
padding-inline: var(--RoomView_MessageList-padding);
|
|
}
|
|
|
|
/* The row holding the spinner shown while more history is fetched. Its height is
|
|
fixed so the row always measures the same. */
|
|
.mx_NewTimelinePanel_loading {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 32px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* An image that fails to load replaces its reserved media box with a short
|
|
error message, which would otherwise pull every row below it upwards. Hold
|
|
the row at the height of the box being replaced — ImageBodyView passes it
|
|
as --mx-image-reserved-height, and only for images whose event declared
|
|
dimensions; anything else reserved no box, so it gets no minimum.
|
|
|
|
The error state sets `display: block`, so laying the message out needs flex
|
|
re-asserting here; the root's `flex-direction: column` then means the cross
|
|
axis is horizontal, and centring in the box is align-items (horizontally)
|
|
plus justify-content (vertically). */
|
|
span.mx_ImageBody {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: var(--mx-image-reserved-height, 0);
|
|
}
|
|
}
|