From e7e9a30c6407e1ae5f72a0af0f11ec728847f48c Mon Sep 17 00:00:00 2001 From: Dan Brewster Date: Tue, 10 Dec 2024 13:22:36 -0500 Subject: [PATCH] fix desktop chatlist jank (#4273) --- packages/ui/src/components/ChatList.tsx | 32 +++++++++++++++++-- .../ui/src/components/ListItem/ListItem.tsx | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/ui/src/components/ChatList.tsx b/packages/ui/src/components/ChatList.tsx index 19ff7d79c3..5f1efec263 100644 --- a/packages/ui/src/components/ChatList.tsx +++ b/packages/ui/src/components/ChatList.tsx @@ -7,6 +7,7 @@ import React, { useEffect, useLayoutEffect, useMemo, + useRef, useState, } from 'react'; import { LayoutChangeEvent } from 'react-native'; @@ -86,11 +87,33 @@ export const ChatList = React.memo(function ChatListComponent({ paddingBottom: 100, // bottom nav height + some cushion }; + const sizeRefs = useRef({ + sectionHeader: 28, + chatListItem: 72, + }); + + const handleHeaderLayout = useCallback((e: LayoutChangeEvent) => { + sizeRefs.current.sectionHeader = e.nativeEvent.layout.height; + }, []); + + const handleItemLayout = useCallback((e: LayoutChangeEvent) => { + sizeRefs.current.chatListItem = e.nativeEvent.layout.height; + }, []); + + const handleOverrideLayout = useCallback( + (layout: { span?: number; size?: number }, item: ChatListItemData) => { + layout.size = isSectionHeader(item) + ? sizeRefs.current.sectionHeader + : sizeRefs.current.chatListItem; + }, + [] + ); + const renderItem: ListRenderItem = useCallback( ({ item }) => { if (isSectionHeader(item)) { return ( - + {item.title} ); @@ -100,6 +123,7 @@ export const ChatList = React.memo(function ChatListComponent({ model={item} onPress={onPressItem} onLongPress={handleLongPress} + onLayout={handleItemLayout} /> ); } else { @@ -108,11 +132,12 @@ export const ChatList = React.memo(function ChatListComponent({ model={item} onPress={onPressItem} onLongPress={handleLongPress} + onLayout={handleItemLayout} /> ); } }, - [onPressItem, handleLongPress] + [handleHeaderLayout, onPressItem, handleLongPress, handleItemLayout] ); const handlePressTryAll = useCallback(() => { @@ -150,7 +175,8 @@ export const ChatList = React.memo(function ChatListComponent({ keyExtractor={getChatKey} renderItem={renderItem} getItemType={getItemType} - estimatedItemSize={getTokenValue('$6xl', 'size')} + estimatedItemSize={sizeRefs.current.chatListItem} + overrideItemLayout={handleOverrideLayout} /> )} diff --git a/packages/ui/src/components/ListItem/ListItem.tsx b/packages/ui/src/components/ListItem/ListItem.tsx index 5d3d4bb237..136960e6d8 100644 --- a/packages/ui/src/components/ListItem/ListItem.tsx +++ b/packages/ui/src/components/ListItem/ListItem.tsx @@ -45,6 +45,7 @@ export const ListItemFrame = styled(XStack, { justifyContent: 'space-between', alignItems: 'stretch', backgroundColor: '$transparent', + height: '$6xl', }); const ListItemIconContainer = styled(View, {