WIP: try legends on native again#29361
Open
chrisnojima wants to merge 2 commits into
Open
Conversation
c11edb7 to
b7612ce
Compare
…ights 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 - SwipeableRow takes an `enabled` prop that conditionally spreads its pan handlers, so a list can shed per-row touch evaluation during a fast fling without unmounting the row. Toggling the Swipeable's subtree instead would remount its children and flash images. No caller passes it yet - 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
Replaces the inverted FlatList + KeyboardChatScrollView native thread with a non-inverted KeyboardAwareLegendList, on top of the list-agnostic row fixes in the parent commit. - non-inverted list: rows render in natural order, so the sent-message animation, separators, and header/footer components swap ends. Bottom clearance for the input bar is reserved statically via contentContainerStyle, with the keyboard composer inset seeded to 0 so the two don't stack. - pagination: onStartReached/onEndReached replace the viewability-window heuristic (useNativeSafeOnViewableItemsChanged is deleted). - prepend jump: maintainScrollAtEnd's dataChange trigger re-pins on ANY data change within maintainScrollAtEndThreshold of the end, so on short threads a load-older prepend yanked the view to the bottom. The threshold stays wide (0.5) because initialScrollAtEnd positions from estimatedItemSize and lands short on our tall rows; instead the re-pin is suspended while a prepend is in flight (prependActive). - initial position: the list is not mounted until the thread is loaded, so its first render always has data and initialScrollAtEnd lands at the newest message. Previously, arriving from the inbox mounted the list empty and the initial scroll ran against no data and never re-fired. - centering: scrollToItem(viewPosition: 0.5) lands accurately here, so the closed-loop offset corrector (viewable-range feedback, damped item-delta scrolls) is deleted in favor of re-asserting across the pagination settle. onScrollToIndexFailed goes with it — LegendList has no such prop. - maintainVisibleContentPosition is on from mount so prepends hold position. - fling cost: experimental_adaptiveRender lets rows shed their swipe pan handlers during fast scroll, via useAdaptiveRender in long-pressable driving the SwipeableRow `enabled` prop added in the parent commit. useAdaptiveRender reads LegendList's state context and throws outside a LegendList, so it can only be wired up here. The Swipeable stays mounted — toggling its tree would remount children and flash images. - stable renderItem: NativeRow reads the centered highlight itself, so renderItem identity never changes and a highlight change doesn't re-render every visible row. Includes a temporary [LISTDBG] dump for the initial-load settle; remove before merging.
a621b5c to
32a520c
Compare
b7612ce to
5e96b94
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.