Skip to content

Commit f1f57d0

Browse files
MxKevinBeqoUrazAkgultan
authored andcommitted
fix(gallery-native): virtual scrolling issue
1 parent b7aa244 commit f1f57d0

File tree

3 files changed

+56
-29
lines changed

3 files changed

+56
-29
lines changed

packages/pluggableWidgets/gallery-native/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Fixed
10+
11+
- We've fixed an issue where the Gallery widget would not properly load more items when scrolling down quickly.
12+
13+
914
## [2.0.0] - 2024-12-3
1015

1116
- Updated react-native-device-info to latest version.

packages/pluggableWidgets/gallery-native/src/components/Gallery.tsx

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createElement, ReactElement, ReactNode } from "react";
1+
import { createElement, ReactElement, ReactNode, useCallback } from "react";
22
import { Text, FlatList, Pressable, View, ViewProps, Platform, TouchableOpacity } from "react-native";
33
import { ObjectItem, DynamicValue } from "mendix";
44
import DeviceInfo from "react-native-device-info";
@@ -32,38 +32,52 @@ export const Gallery = <T extends ObjectItem>(props: GalleryProps<T>): ReactElem
3232
const numColumns = DeviceInfo.isTablet() ? props.tabletColumns : props.phoneColumns;
3333
const firstItemId = props.items?.[0]?.id;
3434
const lastItemId = props.items?.[props.items.length - 1]?.id;
35+
const { name, style, itemRenderer } = props;
3536

3637
const onEndReached = (): void => {
3738
if (props.pagination === "virtualScrolling" && props.hasMoreItems) {
3839
props.loadMoreItems();
3940
}
4041
};
4142

42-
const renderItem = (item: { item: T }): ReactElement =>
43-
props.itemRenderer((children, onPress) => {
44-
const listItemWrapperProps: ViewProps = {
45-
style: isScrollDirectionVertical && { width: `${100 / numColumns}%` },
46-
testID: `${props.name}-list-item-${item.item.id}`
47-
};
48-
const renderListItemContent = (
49-
<View
50-
style={[
51-
props.style.listItem,
52-
firstItemId === item.item.id && props.style.firstItem,
53-
lastItemId === item.item.id && props.style.lastItem
54-
]}
55-
>
56-
{children}
57-
</View>
58-
);
59-
return onPress ? (
60-
<Pressable {...listItemWrapperProps} onPress={onPress}>
61-
{renderListItemContent}
62-
</Pressable>
63-
) : (
64-
<View {...listItemWrapperProps}>{renderListItemContent}</View>
65-
);
66-
}, item.item);
43+
const renderItem = useCallback(
44+
(item: { item: T }): ReactElement =>
45+
itemRenderer((children, onPress) => {
46+
const listItemWrapperProps: ViewProps = {
47+
style: isScrollDirectionVertical && { width: `${100 / numColumns}%` },
48+
testID: `${name}-list-item-${item.item.id}`
49+
};
50+
const renderListItemContent = (
51+
<View
52+
style={[
53+
style.listItem,
54+
firstItemId === item.item.id && style.firstItem,
55+
lastItemId === item.item.id && style.lastItem
56+
]}
57+
>
58+
{children}
59+
</View>
60+
);
61+
return onPress ? (
62+
<Pressable {...listItemWrapperProps} onPress={onPress}>
63+
{renderListItemContent}
64+
</Pressable>
65+
) : (
66+
<View {...listItemWrapperProps}>{renderListItemContent}</View>
67+
);
68+
}, item.item),
69+
[
70+
isScrollDirectionVertical,
71+
numColumns,
72+
itemRenderer,
73+
name,
74+
style.listItem,
75+
style.firstItem,
76+
style.lastItem,
77+
firstItemId,
78+
lastItemId
79+
]
80+
);
6781

6882
const loadMoreButton = (): ReactElement | null => {
6983
const renderButton = (
@@ -80,7 +94,7 @@ export const Gallery = <T extends ObjectItem>(props: GalleryProps<T>): ReactElem
8094
);
8195

8296
const buttonProps = {
83-
testID: `${props.name}-pagination-button`,
97+
testID: `${name}-pagination-button`,
8498
onPress: () => props.hasMoreItems && props.loadMoreItems && props.loadMoreItems(),
8599
style: loadMoreButtonContainerStyle
86100
};
@@ -111,7 +125,7 @@ export const Gallery = <T extends ObjectItem>(props: GalleryProps<T>): ReactElem
111125
);
112126

113127
return (
114-
<View testID={`${props.name}`} style={props.style.container}>
128+
<View testID={`${name}`} style={props.style.container}>
115129
{props.filters ? <View>{props.filters}</View> : null}
116130
<FlatList
117131
{...(isScrollDirectionVertical && props.pullDown ? { onRefresh: props.pullDown } : {})}
@@ -127,10 +141,11 @@ export const Gallery = <T extends ObjectItem>(props: GalleryProps<T>): ReactElem
127141
keyExtractor={item => item.id}
128142
ListEmptyComponent={renderEmptyPlaceholder}
129143
onEndReached={onEndReached}
144+
onEndReachedThreshold={0.6}
130145
scrollEventThrottle={50}
131146
renderItem={renderItem}
132147
style={props.style.list}
133-
testID={`${props.name}-list`}
148+
testID={`${name}-list`}
134149
/>
135150
</View>
136151
);

packages/pluggableWidgets/gallery-native/src/components/__tests__/__snapshots__/Gallery.spec.tsx.snap

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ exports[`Gallery rendering rendering with load more button it shouldn't render t
5050
keyExtractor={[Function]}
5151
onContentSizeChange={[Function]}
5252
onEndReached={[Function]}
53+
onEndReachedThreshold={0.6}
5354
onLayout={[Function]}
5455
onMomentumScrollBegin={[Function]}
5556
onMomentumScrollEnd={[Function]}
@@ -377,6 +378,7 @@ exports[`Gallery rendering rendering with load more button renders correctly 1`]
377378
keyExtractor={[Function]}
378379
onContentSizeChange={[Function]}
379380
onEndReached={[Function]}
381+
onEndReachedThreshold={0.6}
380382
onLayout={[Function]}
381383
onMomentumScrollBegin={[Function]}
382384
onMomentumScrollEnd={[Function]}
@@ -750,6 +752,7 @@ exports[`Gallery rendering rendering with load more button renders correctly wit
750752
keyExtractor={[Function]}
751753
onContentSizeChange={[Function]}
752754
onEndReached={[Function]}
755+
onEndReachedThreshold={0.6}
753756
onLayout={[Function]}
754757
onMomentumScrollBegin={[Function]}
755758
onMomentumScrollEnd={[Function]}
@@ -1123,6 +1126,7 @@ exports[`Gallery rendering renders correctly 1`] = `
11231126
keyExtractor={[Function]}
11241127
onContentSizeChange={[Function]}
11251128
onEndReached={[Function]}
1129+
onEndReachedThreshold={0.6}
11261130
onLayout={[Function]}
11271131
onMomentumScrollBegin={[Function]}
11281132
onMomentumScrollEnd={[Function]}
@@ -1450,6 +1454,7 @@ exports[`Gallery rendering renders correctly horizontal 1`] = `
14501454
keyExtractor={[Function]}
14511455
onContentSizeChange={[Function]}
14521456
onEndReached={[Function]}
1457+
onEndReachedThreshold={0.6}
14531458
onLayout={[Function]}
14541459
onMomentumScrollBegin={[Function]}
14551460
onMomentumScrollEnd={[Function]}
@@ -1758,6 +1763,7 @@ exports[`Gallery rendering renders correctly with empty list and custom placehol
17581763
keyExtractor={[Function]}
17591764
onContentSizeChange={[Function]}
17601765
onEndReached={[Function]}
1766+
onEndReachedThreshold={0.6}
17611767
onLayout={[Function]}
17621768
onMomentumScrollBegin={[Function]}
17631769
onMomentumScrollEnd={[Function]}
@@ -1844,6 +1850,7 @@ exports[`Gallery rendering renders correctly with filter 1`] = `
18441850
keyExtractor={[Function]}
18451851
onContentSizeChange={[Function]}
18461852
onEndReached={[Function]}
1853+
onEndReachedThreshold={0.6}
18471854
onLayout={[Function]}
18481855
onMomentumScrollBegin={[Function]}
18491856
onMomentumScrollEnd={[Function]}

0 commit comments

Comments
 (0)