You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(chat): stop recycled message rows from leaking state and stale heights
These are list-agnostic row fixes, split out of the native LegendList work.
Desktop already renders the thread with a recycling LegendList, so each of
these is a live bug there today; on the native FlatList they are inert
guards.
- per-row state (sent animation, reaction picker, exploding retained height,
ash tower) is now keyed to messageKey. A recycled container reuses the
component instance for a different message, so mount-captured state leaked
across rows: the picker stayed open on the wrong row, the sent-animation
wrapper stuck on, and a measured retain height was applied to the wrong
message (and could not self-correct, since retainHeight forces the style
height so onLayout only ever reports the forced value back)
- recycle-pool suffixes are limited to ones that are stable for the message's
lifetime (:failed, :reply). The pool label is recorded when a container is
allocated and never updated in place, so :pending (flips on every send
confirmation) and :reactions (toggles) left stale labels behind and recycled
containers painted at the wrong pooled height
- getItemType splits headered rows into their own pool (:hdr). A message that
leads its author group is ~40px taller than a grouped follow-on of the same
render type, so a shared pool paints recycled views at the wrong height for
a frame. It reads the same sticky username cache the rows render with, else
a row that keeps its header after a scroll-back load is typed headerless and
poisons the headerless pool's height average
- useSyncRowLayout: when a row's content settles to a new height after first
paint (flip result streams in, reactions appear, an unfurl loads), flush the
row measure synchronously so the list's bottom re-pin uses the final height
on the same frame instead of a frame late, which otherwise parks the thread
above the newest message
- desktop LegendList: dataKey replaces the key remount on conversation switch,
and maintainScrollAtEnd opts back into footerLayout, which 3.x stopped
implying once the trigger set is given explicitly
0 commit comments