11import { useTheme } from "@react-navigation/native" ;
2- import { useContext , useEffect , useRef , useState } from "react" ;
2+ import { useCallback , useContext , useEffect , useRef , useState } from "react" ;
33import { Alert , Animated , FlatList , Pressable , StyleSheet , View } from "react-native" ;
44import Swipeable from "react-native-gesture-handler/Swipeable" ;
55import {
@@ -16,11 +16,11 @@ import {
1616} from "react-native-paper" ;
1717import { createGroup , getGroups , getOptimizedSettlements } from "../api/groups" ;
1818import { AuthContext } from "../context/AuthContext" ;
19- import { formatCurrency , getCurrencySymbol } from "../utils/currency" ;
19+ import { formatCurrency } from "../utils/currency" ;
2020import { tokens } from "../utils/theme" ;
2121
2222const HomeScreen = ( { navigation } ) => {
23- const { token, logout , user } = useContext ( AuthContext ) ;
23+ const { token, user } = useContext ( AuthContext ) ;
2424 const { colors } = useTheme ( ) ;
2525 const [ groups , setGroups ] = useState ( [ ] ) ;
2626 const [ isLoading , setIsLoading ] = useState ( true ) ;
@@ -80,17 +80,23 @@ const HomeScreen = ({ navigation }) => {
8080
8181 // Fetch settlement status for each group
8282 if ( user ?. _id ) {
83- const settlementPromises = groupsList . map ( async ( group ) => {
84- const status = await calculateSettlementStatus ( group . _id , user . _id ) ;
85- return { groupId : group . _id , status } ;
86- } ) ;
87-
88- const settlementResults = await Promise . all ( settlementPromises ) ;
89- const settlementMap = { } ;
90- settlementResults . forEach ( ( { groupId, status } ) => {
91- settlementMap [ groupId ] = status ;
92- } ) ;
93- setGroupSettlements ( settlementMap ) ;
83+ const chunkSize = 5 ;
84+ // clear previous while loading fresh data
85+ setGroupSettlements ( { } ) ;
86+ for ( let i = 0 ; i < groupsList . length ; i += chunkSize ) {
87+ const slice = groupsList . slice ( i , i + chunkSize ) ;
88+ const results = await Promise . all (
89+ slice . map ( async ( group ) => ( {
90+ groupId : group . _id ,
91+ status : await calculateSettlementStatus ( group . _id , user . _id ) ,
92+ } ) )
93+ ) ;
94+ const partial = results . reduce ( ( acc , { groupId, status } ) => {
95+ acc [ groupId ] = status ;
96+ return acc ;
97+ } , { } ) ;
98+ setGroupSettlements ( ( prev ) => ( { ...prev , ...partial } ) ) ;
99+ }
94100 }
95101 } catch ( error ) {
96102 console . error ( "Failed to fetch groups:" , error ) ;
@@ -125,7 +131,7 @@ const HomeScreen = ({ navigation }) => {
125131 }
126132 } ;
127133
128- const currencySymbol = getCurrencySymbol ( ) ;
134+ // const currencySymbol = getCurrencySymbol(); // not used on this screen currently
129135
130136 // Simple mount animation for list items
131137 const itemAnim = useRef ( new Animated . Value ( 0 ) ) . current ;
@@ -137,7 +143,7 @@ const HomeScreen = ({ navigation }) => {
137143 } ) . start ( ) ;
138144 } , [ groups ] ) ;
139145
140- const renderGroup = ( { item, index } ) => {
146+ const renderGroup = useCallback ( ( { item, index } ) => {
141147 const settlementStatus = groupSettlements [ item . _id ] ;
142148
143149 // Generate settlement status text
@@ -248,7 +254,12 @@ const HomeScreen = ({ navigation }) => {
248254 opacity : itemAnim ,
249255 } }
250256 >
251- < Swipeable renderRightActions = { renderRightActions } renderLeftActions = { renderLeftActions } >
257+ < Swipeable
258+ renderRightActions = { renderRightActions }
259+ renderLeftActions = { renderLeftActions }
260+ friction = { 2 }
261+ overshootFriction = { 8 }
262+ >
252263 < Pressable onPress = { openDetails } onPressIn = { onPressIn } onPressOut = { onPressOut } >
253264 < Card style = { [ styles . card , { backgroundColor : colors . card } ] } >
254265 < Card . Title
@@ -277,7 +288,7 @@ const HomeScreen = ({ navigation }) => {
277288 </ Swipeable >
278289 </ Animated . View >
279290 ) ;
280- } ;
291+ } , [ groupSettlements , colors , itemAnim , navigation ] ) ;
281292
282293 return (
283294 < View style = { styles . container } >
@@ -326,6 +337,9 @@ const HomeScreen = ({ navigation }) => {
326337 renderItem = { renderGroup }
327338 keyExtractor = { ( item ) => item . _id }
328339 contentContainerStyle = { styles . list }
340+ initialNumToRender = { 8 }
341+ windowSize = { 10 }
342+ removeClippedSubviews
329343 ListEmptyComponent = {
330344 < Text style = { styles . emptyText } >
331345 No groups found. Create or join one!
0 commit comments