diff --git a/app/views/RoomsListView/hooks/useGetItemLayout.ts b/app/views/RoomsListView/hooks/useGetFixedItemSize.ts
similarity index 72%
rename from app/views/RoomsListView/hooks/useGetItemLayout.ts
rename to app/views/RoomsListView/hooks/useGetFixedItemSize.ts
index 27c40ea897..ef2542b021 100644
--- a/app/views/RoomsListView/hooks/useGetItemLayout.ts
+++ b/app/views/RoomsListView/hooks/useGetFixedItemSize.ts
@@ -1,23 +1,15 @@
import { useCallback } from 'react';
import { shallowEqual } from 'react-redux';
+import { type IRoomItem } from '~/containers/RoomItem/interfaces';
import { DisplayMode } from '~/lib/constants/constantDisplayMode';
import { useAppSelector } from '~/lib/hooks/useAppSelector';
import { useResponsiveLayout } from '~/lib/hooks/useResponsiveLayout/useResponsiveLayout';
-export const useGetItemLayout = () => {
+export const useGetFixedItemSize = () => {
const { rowHeight, rowHeightCondensed } = useResponsiveLayout();
const { displayMode } = useAppSelector(state => state.sortPreferences, shallowEqual);
const height = displayMode === DisplayMode.Condensed ? rowHeightCondensed : rowHeight;
- const getItemLayout = useCallback(
- (_: any, index: number) => ({
- length: height,
- offset: height * index,
- index
- }),
- [height]
- );
-
- return getItemLayout;
+ return useCallback((item: IRoomItem) => (item.separator ? undefined : height), [height]);
};
diff --git a/app/views/RoomsListView/index.tsx b/app/views/RoomsListView/index.tsx
index b7229c126c..bcaf14bd90 100644
--- a/app/views/RoomsListView/index.tsx
+++ b/app/views/RoomsListView/index.tsx
@@ -1,6 +1,7 @@
import { useNavigation } from '@react-navigation/native';
import { memo, useContext, useEffect } from 'react';
-import { BackHandler, FlatList, RefreshControl } from 'react-native';
+import { LegendList } from '@legendapp/list/react-native';
+import { BackHandler, RefreshControl } from 'react-native';
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
import { shallowEqual } from 'react-redux';
@@ -14,7 +15,7 @@ import i18n from '~/i18n';
import { MAX_SIDEBAR_WIDTH } from '~/lib/constants/tablet';
import { useAppSelector } from '~/lib/hooks/useAppSelector';
import { useMasterDetail } from '~/lib/hooks/useMasterDetail';
-import { getRoomAvatar, getRoomTitle, getUidDirectMessage, isIOS, isRead, isTablet } from '~/lib/methods/helpers';
+import { getRoomAvatar, getRoomTitle, getUidDirectMessage, isIOS, isRead } from '~/lib/methods/helpers';
import { goRoom } from '~/lib/methods/helpers/goRoom';
import { events, logEvent } from '~/lib/methods/helpers/log';
import { getUserSelector } from '~/selectors/login';
@@ -23,14 +24,12 @@ import Container from './components/Container';
import ListHeader from './components/ListHeader';
import SectionHeader from './components/SectionHeader';
import RoomsSearchProvider, { RoomsSearchContext } from './contexts/RoomsSearchProvider';
-import { useGetItemLayout } from './hooks/useGetItemLayout';
+import { useGetFixedItemSize } from './hooks/useGetFixedItemSize';
import { useHeader } from './hooks/useHeader';
import { useRefresh } from './hooks/useRefresh';
import { useSubscriptions } from './hooks/useSubscriptions';
import styles from './styles';
-const INITIAL_NUM_TO_RENDER = isTablet ? 20 : 12;
-
const RoomsListView = memo(function RoomsListView() {
useHeader();
const { searching, searchEnabled, searchResults, stopSearch } = useContext(RoomsSearchContext);
@@ -44,7 +43,7 @@ const RoomsListView = memo(function RoomsListView() {
const navigation = useNavigation();
const { width } = useSafeAreaFrame();
const { bottom } = useSafeAreaInsets();
- const getItemLayout = useGetItemLayout();
+ const getFixedItemSize = useGetFixedItemSize();
const { subscriptions, loading } = useSubscriptions();
const subscribedRoom = useAppSelector(state => state.room.subscribedRoom);
const changingServer = useAppSelector(state => state.server.changingServer);
@@ -125,22 +124,32 @@ const RoomsListView = memo(function RoomsListView() {
return ;
}
+ const rooms = searchEnabled ? searchResults : subscriptions;
+
return (
- `${item.rid}-${searchEnabled}`}
+ getItemType={item => (item.separator ? 'separator' : 'room')}
+ getFixedItemSize={getFixedItemSize}
style={[styles.list, { backgroundColor: colors.surfaceRoom }]}
contentContainerStyle={{ paddingBottom: bottom }}
renderItem={renderItem}
ListHeaderComponent={ListHeader}
- ListFooterComponent={searching ? () => : undefined}
- getItemLayout={getItemLayout}
+ ListFooterComponent={searching ? : undefined}
keyboardShouldPersistTaps='always'
- initialNumToRender={INITIAL_NUM_TO_RENDER}
refreshControl={}
- windowSize={9}
- onEndReachedThreshold={0.5}
keyboardDismissMode={isIOS ? 'on-drag' : 'none'}
/>
);
diff --git a/package.json b/package.json
index 96cf9e39a5..6855adc354 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"@bugsnag/react-native": "8.4.0",
"@expo/vector-icons": "^15.0.3",
"@hookform/resolvers": "^2.9.10",
+ "@legendapp/list": "3.4.0",
"@lodev09/react-native-true-sheet": "~3.7.0",
"@magrinj/expo-quick-look": "0.4.0",
"@nozbe/watermelondb": "^0.28.1-0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ef04948241..3fc53628cb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -23,6 +23,9 @@ importers:
'@hookform/resolvers':
specifier: ^2.9.10
version: 2.9.11(react-hook-form@7.34.2(react@19.2.3))
+ '@legendapp/list':
+ specifier: 3.4.0
+ version: 3.4.0(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native-community/cli@20.0.0(typescript@7.0.2))(@react-native/jest-preset@0.86.3(@babel/core@7.29.7)(react@19.2.3))(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.2.18)(react@19.2.3))(react@19.2.3)
'@lodev09/react-native-true-sheet':
specifier: ~3.7.0
version: 3.7.3(4eac27da23d45fdf91d899c57069aba2)
@@ -2125,6 +2128,18 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@legendapp/list@3.4.0':
+ resolution: {integrity: sha512-Tlx7Uf9pRP/JbrekuWdKf1+42C9MTfl1wGkP8Lvmg2E2T9rCWQphYOs8aOkcvgbAkJ2S+WR+RTXHS2+6U+nROw==}
+ peerDependencies:
+ react: '*'
+ react-dom: '*'
+ react-native: '*'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
'@lodev09/react-native-true-sheet@3.7.3':
resolution: {integrity: sha512-vX/3F6lD3qH0GZfSVXL+JD/bjFPZtJa35Vyr9KCv94szOHXsjoEyCyi/52r5jw6jmq/KRALCqwidt9A15qq9gw==}
peerDependencies:
@@ -10321,6 +10336,14 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@legendapp/list@3.4.0(react-dom@19.2.3(react@19.2.3))(react-native@0.86.3(@babel/core@7.29.7)(@react-native-community/cli@20.0.0(typescript@7.0.2))(@react-native/jest-preset@0.86.3(@babel/core@7.29.7)(react@19.2.3))(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.2.18)(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ react: 19.2.3
+ use-sync-external-store: 1.6.0(react@19.2.3)
+ optionalDependencies:
+ react-dom: 19.2.3(react@19.2.3)
+ react-native: 0.86.3(@babel/core@7.29.7)(@react-native-community/cli@20.0.0(typescript@7.0.2))(@react-native/jest-preset@0.86.3(@babel/core@7.29.7)(react@19.2.3))(@react-native/metro-config@0.86.3(@babel/core@7.29.7))(@types/react@19.2.18)(react@19.2.3)
+
'@lodev09/react-native-true-sheet@3.7.3(4eac27da23d45fdf91d899c57069aba2)':
dependencies:
react: 19.2.3