State where a resized row goes instead of walking it there
Correcting by the error each pass could see, and asking again on the pass that answered, was a frame per pass with the ones in between drawn: opening a card visibly stepped. It also still missed, because two of the passes were spent finding out what the list would do rather than telling it. `requestScrollToItem` against the row itself says it outright, in one pass: the row is placed wherever it has ended up and whether or not it is still on screen, and a negative offset -- which is the list being asked for the rows below a card that has just given the screen its whole height back -- is exactly what a close needs and works. Everything else follows from where that puts it. A call opened or shut *inside* a group is a third case, and it was being treated as the second: the group is not the thing opening, it is the container, and centring it on the tap threw a group of six the length of the screen. What keeps the call under the finger is holding the group's top edge, so that everything above the change -- that call's own heading included -- stays where it is. Checked with ktfmtFormat, compileDebugKotlin, lintDebug and testDebugUnitTest, and on the emulator against the sandbox with sampling as fast as the device will report it, so an intermediate frame would show: a 2,785px card closed at 600, 1200 and 1800 lands centred on 600, 1200 and 1800 to the pixel, each in one step; opening by the heading holds the heading still; and opening or closing a call inside a group of five leaves the group's heading exactly where it was.
This commit is contained in:
1 parent
1b38579b97
commit
581e07624f
2 files changed
+73
-86
No files matched your search
@@ -1190,8 +1190,9 @@ dev-updater (Kotlin 2.4.x, CMP 1.11.x, JDK 21).
|
||||
One rule in two places (`AskedQuestion` and `PermissionAsk`). An answer
|
||||
typed into **Other** matches no option, so that one is still written out.
|
||||
- **Opening a row keeps still the end nearest the tap; closing one lands
|
||||
the closed row centred on the tap itself** (2026-09-16). A row about to
|
||||
open is small, so both its edges are within a heading's height of the
|
||||
the closed row centred on the tap itself; and a call opened or shut
|
||||
*inside* a group keeps the group's top edge** (2026-09-16). A row about
|
||||
to open is small, so both its edges are within a heading's height of the
|
||||
finger and the wanted one is the edge pressed: touch the upper half and
|
||||
the top edge holds, so it opens downwards; touch the lower half and the
|
||||
bottom edge holds, as the list does by default. A row about to close
|
||||
@@ -1200,23 +1201,29 @@ dev-updater (Kotlin 2.4.x, CMP 1.11.x, JDK 21).
|
||||
screen settles it, since both of its edges can be a screen's length from
|
||||
the hand, and holding a *share* of the card's height was the same miss in
|
||||
miniature: tap away from the middle of a long card and the heading landed
|
||||
a card's height off. Where there is not enough conversation on the far
|
||||
side to scroll, the row lands as close as the list can put it.
|
||||
**The correction is measured, never predicted, and it is asked for from
|
||||
a card's height off. The third case is the one where the row is not the
|
||||
thing being opened at all but the container of it; what the reader is
|
||||
looking at is the call under their finger, and holding the group's top
|
||||
edge is what keeps everything above the change — that call's own heading
|
||||
included — exactly where it is. Centring the group instead threw a group
|
||||
of six the length of the screen. Where there is not enough conversation
|
||||
on the far side to scroll, the row lands as close as the list can put it.
|
||||
**The position is stated, not converged on, and it is asked for from
|
||||
inside the list's own measure** (`settleHold`, called from
|
||||
`TranscriptList`'s `afterMeasure`). Both halves of that were paid for:
|
||||
working the scroll out from the change in height needs the list to behave
|
||||
`TranscriptList`'s `afterMeasure`). Three things were paid for to get
|
||||
there. A scroll asked for during the *placement* phase is never picked up
|
||||
by another measure, so it does nothing whatever; from a coroutine it
|
||||
arrives a frame late, which is the flick this mechanism exists to avoid.
|
||||
Working the scroll out from the change in height needs the list to behave
|
||||
the way the arithmetic assumed, and it does not — which item it holds
|
||||
still across a resize, and how much of a scroll it can honour, depend on
|
||||
what it has composed, and a row taller than the screen is anchored on
|
||||
*itself*. And a scroll asked for during the *placement* phase is never
|
||||
picked up by another measure, so it does nothing at all; from a coroutine
|
||||
it arrives a frame late, which is the flick this mechanism exists to
|
||||
avoid. So each pass asks for the error it can see, and the pass that
|
||||
answers is where the rest becomes askable — three passes is the worst
|
||||
case seen, including the one where the shut card has left the viewport
|
||||
entirely and has to be asked back to the bottom edge before it can be
|
||||
measured at all.
|
||||
still across a resize depends on what it has composed, and a row taller
|
||||
than the screen is anchored on *itself*. And correcting by the error a
|
||||
pass can see, then asking again, is a *frame* per pass with the ones in
|
||||
between drawn: opening a card visibly stepped. What is exact and takes
|
||||
one pass is `requestScrollToItem` against the row itself, which places it
|
||||
wherever it has ended up and whether or not it is still on screen — a
|
||||
negative offset included, which is the list being asked for the rows
|
||||
below a card that has just given the screen its whole height back.
|
||||
- **The full-screen image lives on the screen, not in the row that drew
|
||||
the thumbnail** (`SessionImageViewer`). A `Read` whose result is an image
|
||||
is a row of one call until the next call arrives and makes it a group — a
|
||||
|
||||
Reference in new issue
Block a user