@react-native-ohos/flash-list 1.8.3-rc.1 → 1.8.3-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.OpenSource +1 -1
- package/README.md +1 -1
- package/dist/AnimatedFlashList.d.ts +1 -4
- package/dist/AnimatedFlashList.d.ts.map +1 -1
- package/dist/FlashList.d.ts +3 -5
- package/dist/FlashList.d.ts.map +1 -1
- package/dist/FlashList.js +20 -23
- package/dist/FlashList.js.map +1 -1
- package/dist/GridLayoutProviderWithProps.js +1 -2
- package/dist/GridLayoutProviderWithProps.js.map +1 -1
- package/dist/MasonryFlashList.d.ts +1 -1
- package/dist/MasonryFlashList.d.ts.map +1 -1
- package/dist/MasonryFlashList.js.map +1 -1
- package/dist/PureComponentWrapper.d.ts +1 -1
- package/dist/PureComponentWrapper.js +1 -1
- package/dist/PureComponentWrapper.js.map +1 -1
- package/dist/benchmark/AutoScrollHelper.js +2 -2
- package/dist/benchmark/AutoScrollHelper.js.map +1 -1
- package/dist/benchmark/JSFPSMonitor.js.map +1 -1
- package/dist/benchmark/roundToDecimalPlaces.js +1 -2
- package/dist/benchmark/roundToDecimalPlaces.js.map +1 -1
- package/dist/benchmark/useBenchmark.js +2 -3
- package/dist/benchmark/useBenchmark.js.map +1 -1
- package/dist/benchmark/useBlankAreaTracker.js +1 -2
- package/dist/benchmark/useBlankAreaTracker.js.map +1 -1
- package/dist/benchmark/useDataMultiplier.js +1 -2
- package/dist/benchmark/useDataMultiplier.js.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts +0 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.js +1 -2
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/errors/CustomError.js.map +1 -1
- package/dist/fabric/AutoLayoutNativeComponent.d.ts.map +1 -1
- package/dist/fabric/CellContainerNativeComponent.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts +1 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutView.js +1 -1
- package/dist/native/auto-layout/AutoLayoutView.js.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts +1 -2
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.d.ts +1 -2
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.harmony.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts +1 -2
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts.map +1 -1
- package/dist/native/cell-container/CellContainer.android.d.ts +1 -1
- package/dist/native/cell-container/CellContainer.android.d.ts.map +1 -1
- package/dist/native/cell-container/CellContainer.d.ts +1 -2
- package/dist/native/cell-container/CellContainer.d.ts.map +1 -1
- package/dist/native/cell-container/CellContainer.harmony.d.ts +1 -1
- package/dist/native/cell-container/CellContainer.harmony.d.ts.map +1 -1
- package/dist/native/cell-container/CellContainer.ios.d.ts +1 -1
- package/dist/native/cell-container/CellContainer.ios.d.ts.map +1 -1
- package/dist/native/cell-container/CellContainer.web.d.ts +1 -2
- package/dist/native/cell-container/CellContainer.web.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.harmony.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/ContentContainerUtils.d.ts.map +1 -1
- package/dist/utils/ContentContainerUtils.js.map +1 -1
- package/dist/viewability/ViewabilityHelper.js.map +1 -1
- package/dist/viewability/ViewabilityManager.d.ts.map +1 -1
- package/dist/viewability/ViewabilityManager.js.map +1 -1
- package/harmony/flash_list/BuildProfile.ets +1 -1
- package/harmony/flash_list/oh-package.json5 +1 -1
- package/harmony/flash_list/src/main/cpp/AutoLayoutNode.cpp +106 -29
- package/harmony/flash_list.har +0 -0
- package/jestSetup.js +0 -1
- package/package.json +3 -3
- package/src/FlashList.tsx +18 -24
|
@@ -22,42 +22,119 @@
|
|
|
22
22
|
* SOFTWARE.
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
|
-
#include
|
|
26
|
-
#include <memory>
|
|
25
|
+
#include <react/renderer/components/view/ViewProps.h>
|
|
27
26
|
#include <glog/logging.h>
|
|
27
|
+
#include <sys/param.h>
|
|
28
|
+
#include <thread>
|
|
29
|
+
#include "AutoLayoutShadow.h"
|
|
30
|
+
#include <random>
|
|
28
31
|
|
|
29
32
|
namespace rnoh {
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
maybeThrow(NativeNodeApi::getInstance()->insertChildAt(m_nodeHandle, child.getArkUINodeHandle(), index));
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
void AutoLayoutNode::removeChild(ArkUINode &child) {
|
|
41
|
-
maybeThrow(NativeNodeApi::getInstance()->removeChild(m_nodeHandle, child.getArkUINodeHandle()));
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
void AutoLayoutNode::onNodeEvent(ArkUI_NodeEventType eventType, EventArgs &eventArgs) {
|
|
45
|
-
if (eventType == ArkUI_NodeEventType::NODE_EVENT_ON_APPEAR) {
|
|
46
|
-
m_autoLayoutNodeDelegate->onAppear();
|
|
34
|
+
/**checks for overlaps or gaps.between adjacent items and then applies a correction (Only Grid layouts with varying
|
|
35
|
+
* spans) Performance: RecyclerListView renders very small number of views and this is not going to trigger multiple
|
|
36
|
+
* layouts on Android side. Not expecting any major perf issu.*/
|
|
37
|
+
void AutoLayoutShadow::clearGapsAndOverlaps(std::vector<CellContainerComponentInstance::Shared> sortedItems) {
|
|
38
|
+
if (sortedItems.empty()) {
|
|
39
|
+
return;
|
|
47
40
|
}
|
|
41
|
+
Float maxBound = 0;
|
|
42
|
+
Float minBound = INT_MAX;
|
|
43
|
+
Float maxBoundNeighbour = 0;
|
|
44
|
+
lastMaxBoundOverall = 0;
|
|
45
|
+
for (int i = 0; i < sortedItems.size() - 1; i++) {
|
|
46
|
+
auto cell = sortedItems[i];
|
|
47
|
+
auto neighbour = sortedItems[i + 1];
|
|
48
|
+
std::optional<facebook::react::LayoutMetrics> neighbourMetrics;
|
|
49
|
+
// Only apply correction if the next cell is consecutive.
|
|
50
|
+
bool isNeighbourConsecutive = neighbour->getIndex() == cell->getIndex() + 1;
|
|
51
|
+
if (isWithinBounds(cell->getLayoutMetrics())) {
|
|
52
|
+
if (!horizontal) {
|
|
53
|
+
maxBound = MAX(maxBound, cell->getBottom());
|
|
54
|
+
minBound = MIN(minBound, cell->getTop());
|
|
55
|
+
maxBoundNeighbour = maxBound;
|
|
56
|
+
if (isNeighbourConsecutive) {
|
|
57
|
+
neighbourMetrics = neighbour->getLayoutMetrics();
|
|
58
|
+
if (cell->getLeft() < neighbour->getLeft()) {
|
|
59
|
+
if (cell->getRight() != neighbour->getLeft()) {
|
|
60
|
+
neighbourMetrics.value().frame.origin.x = cell->getRight();
|
|
61
|
+
}
|
|
62
|
+
if (cell->getTop() != neighbour->getTop()) {
|
|
63
|
+
neighbourMetrics.value().frame.origin.y = cell->getTop();
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
neighbourMetrics.value().frame.origin.y = maxBound;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (isWithinBounds(*neighbourMetrics)) {
|
|
70
|
+
float bottom = neighbourMetrics->frame.origin.y + neighbourMetrics->frame.size.height;
|
|
71
|
+
maxBoundNeighbour = MAX(maxBound, bottom);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
maxBound = MAX(maxBound, cell->getRight());
|
|
75
|
+
minBound = MIN(minBound, cell->getLeft());
|
|
76
|
+
maxBoundNeighbour = maxBound;
|
|
77
|
+
if (isNeighbourConsecutive) {
|
|
78
|
+
neighbourMetrics = neighbour->getLayoutMetrics();
|
|
79
|
+
if (cell->getTop() < neighbour->getTop()) {
|
|
80
|
+
if (cell->getBottom() != neighbour->getTop()) {
|
|
81
|
+
neighbourMetrics.value().frame.origin.y = cell->getBottom();
|
|
82
|
+
}
|
|
83
|
+
if (cell->getLeft() != neighbour->getLeft()) {
|
|
84
|
+
neighbourMetrics.value().frame.origin.x = cell->getLeft();
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
neighbourMetrics.value().frame.origin.x = maxBound;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (isWithinBounds(*neighbourMetrics)) {
|
|
91
|
+
float right = neighbourMetrics->frame.origin.x + neighbourMetrics->frame.size.width;
|
|
92
|
+
maxBoundNeighbour = MAX(maxBound, right);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (horizontal) {
|
|
97
|
+
lastMaxBoundOverall = MAX(lastMaxBoundOverall, cell->getRight());
|
|
98
|
+
float right = neighbourMetrics->frame.origin.x + neighbourMetrics->frame.size.width;
|
|
99
|
+
lastMaxBoundOverall = MAX(lastMaxBoundOverall, neighbour->getRight());
|
|
100
|
+
} else {
|
|
101
|
+
lastMaxBoundOverall = MAX(lastMaxBoundOverall, cell->getBottom());
|
|
102
|
+
float bottom = neighbourMetrics->frame.origin.y + neighbourMetrics->frame.size.height;
|
|
103
|
+
lastMaxBoundOverall = MAX(lastMaxBoundOverall, bottom);
|
|
104
|
+
}
|
|
105
|
+
cell->setLayout(cell->getLayoutMetrics());
|
|
106
|
+
neighbour->setLayout(neighbourMetrics ? neighbourMetrics.value() : neighbour->getLayoutMetrics());
|
|
107
|
+
}
|
|
108
|
+
lastMaxBound = maxBoundNeighbour;
|
|
109
|
+
lastMinBound = minBound;
|
|
48
110
|
}
|
|
49
111
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
112
|
+
/** Offset provider by react can be one frame behind the real one, it's important that this method is called with
|
|
113
|
+
* offset taken directly from scrollview object*/
|
|
114
|
+
Float AutoLayoutShadow::computeBlankFromGivenOffset(Float actualScrollOffset, Float distanceFromWindowStart,
|
|
115
|
+
Float distanceFromWindowEnd) {
|
|
116
|
+
blankOffsetAtStart = lastMinBound - actualScrollOffset - distanceFromWindowStart;
|
|
117
|
+
blankOffsetAtEnd = actualScrollOffset + windowSize - renderOffset - lastMaxBound - distanceFromWindowEnd;
|
|
118
|
+
return MAX(blankOffsetAtStart, blankOffsetAtEnd);
|
|
56
119
|
}
|
|
57
120
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
121
|
+
/**It's importance to aviod correcting views outside the render window. An item that isn't being recycled might
|
|
122
|
+
* still remain in the view tree. If views outside get considered then gaps between unused items will cause
|
|
123
|
+
* algorithm to fail.*/
|
|
124
|
+
bool AutoLayoutShadow::isWithinBounds(const facebook::react::LayoutMetrics& metrics) {
|
|
125
|
+
auto boundsStart = scrollOffset - renderOffset;
|
|
126
|
+
auto boundsEnd = scrollOffset + windowSize;
|
|
127
|
+
float top = metrics.frame.origin.y;
|
|
128
|
+
float bottom = metrics.frame.origin.y + metrics.frame.size.height;
|
|
129
|
+
float left = metrics.frame.origin.x;
|
|
130
|
+
float right = metrics.frame.origin.x + metrics.frame.size.width;
|
|
131
|
+
|
|
132
|
+
if (!this->horizontal) {
|
|
133
|
+
return (top >= boundsStart || bottom >= boundsStart) &&
|
|
134
|
+
(top <= boundsEnd || bottom <= boundsEnd);
|
|
135
|
+
} else {
|
|
136
|
+
return (left >= boundsStart || right >= boundsStart) &&
|
|
137
|
+
(left <= boundsEnd || right <= boundsEnd);
|
|
138
|
+
}
|
|
62
139
|
}
|
|
63
|
-
} // namespace rnoh
|
|
140
|
+
} // namespace rnoh
|
package/harmony/flash_list.har
CHANGED
|
Binary file
|
package/jestSetup.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-ohos/flash-list",
|
|
3
|
-
"version": "1.8.3-rc.
|
|
3
|
+
"version": "1.8.3-rc.2",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"react-native",
|
|
6
6
|
"recyclerview",
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
|
-
"url": "https://
|
|
25
|
+
"url": "https://gitcode.com/openharmony-sig/rntpc_flash-list.git"
|
|
26
26
|
},
|
|
27
27
|
"description": "FlashList is a more performant FlatList replacement",
|
|
28
28
|
"author": "shopify",
|
|
29
29
|
"license": "MIT",
|
|
30
|
-
"homepage": "https://
|
|
30
|
+
"homepage": "https://gitcode.com/openharmony-sig/rntpc_flash-list/tree/br_rnoh0.77#readme",
|
|
31
31
|
"main": "dist/index.js",
|
|
32
32
|
"types": "dist/index.d.ts",
|
|
33
33
|
"scripts": {
|
package/src/FlashList.tsx
CHANGED
|
@@ -82,6 +82,7 @@ export interface FlashListState<T> {
|
|
|
82
82
|
data?: ReadonlyArray<T> | null;
|
|
83
83
|
extraData?: ExtraData<unknown>;
|
|
84
84
|
renderItem?: FlashListProps<T>["renderItem"];
|
|
85
|
+
lastInverted?: boolean;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
interface ExtraData<T> {
|
|
@@ -95,10 +96,6 @@ class FlashList<T> extends React.PureComponent<
|
|
|
95
96
|
private rlvRef?: RecyclerListView<RecyclerListViewProps, any>;
|
|
96
97
|
private stickyContentContainerRef?: PureComponentWrapper;
|
|
97
98
|
private listFixedDimensionSize = 0;
|
|
98
|
-
private transformStyle = PlatformConfig.invertedTransformStyle;
|
|
99
|
-
private transformStyleHorizontal =
|
|
100
|
-
PlatformConfig.invertedTransformStyleHorizontal;
|
|
101
|
-
|
|
102
99
|
private distanceFromWindow = 0;
|
|
103
100
|
private contentStyle: ContentStyleExplicit = {
|
|
104
101
|
paddingBottom: 0,
|
|
@@ -207,11 +204,13 @@ class FlashList<T> extends React.PureComponent<
|
|
|
207
204
|
newState.layoutProvider.shouldRefreshWithAnchoring = Boolean(
|
|
208
205
|
!prevState.layoutProvider?.hasExpired
|
|
209
206
|
);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
207
|
+
if (nextProps.data !== prevState.data || prevState.lastInverted !== nextProps.inverted) {
|
|
208
|
+
const processedData = nextProps.inverted
|
|
209
|
+
? (nextProps.data ? [...nextProps.data].reverse() : nextProps.data)
|
|
210
|
+
: nextProps.data;
|
|
211
|
+
newState.data = processedData;
|
|
213
212
|
newState.dataProvider = prevState.dataProvider.cloneWithRows(
|
|
214
|
-
|
|
213
|
+
processedData as any[]
|
|
215
214
|
);
|
|
216
215
|
if (nextProps.renderItem !== prevState.renderItem) {
|
|
217
216
|
newState.extraData = { ...prevState.extraData };
|
|
@@ -221,6 +220,7 @@ class FlashList<T> extends React.PureComponent<
|
|
|
221
220
|
newState.extraData = { value: nextProps.extraData };
|
|
222
221
|
}
|
|
223
222
|
newState.renderItem = nextProps.renderItem;
|
|
223
|
+
newState.lastInverted = nextProps.inverted ?? undefined;
|
|
224
224
|
return newState;
|
|
225
225
|
}
|
|
226
226
|
|
|
@@ -287,6 +287,8 @@ class FlashList<T> extends React.PureComponent<
|
|
|
287
287
|
numColumns,
|
|
288
288
|
props.extraData
|
|
289
289
|
);
|
|
290
|
+
console.log('mutableLayout:', mutableLayout);
|
|
291
|
+
|
|
290
292
|
return mutableLayout?.size;
|
|
291
293
|
},
|
|
292
294
|
flashListProps
|
|
@@ -359,8 +361,8 @@ class FlashList<T> extends React.PureComponent<
|
|
|
359
361
|
stickyHeaderIndices={stickyHeaderIndices}
|
|
360
362
|
style={
|
|
361
363
|
this.props.horizontal
|
|
362
|
-
? {
|
|
363
|
-
: { flex: 1, overflow: "hidden"
|
|
364
|
+
? { }
|
|
365
|
+
: { flex: 1, overflow: "hidden" }
|
|
364
366
|
}
|
|
365
367
|
>
|
|
366
368
|
<ProgressiveListView
|
|
@@ -533,7 +535,6 @@ class FlashList<T> extends React.PureComponent<
|
|
|
533
535
|
...props.style,
|
|
534
536
|
flexDirection: this.props.horizontal ? "row" : "column",
|
|
535
537
|
alignItems: "stretch",
|
|
536
|
-
...this.getTransform(),
|
|
537
538
|
...getCellContainerPlatformStyles(this.props.inverted!!, parentProps),
|
|
538
539
|
}}
|
|
539
540
|
index={parentProps.index}
|
|
@@ -561,13 +562,6 @@ class FlashList<T> extends React.PureComponent<
|
|
|
561
562
|
}
|
|
562
563
|
};
|
|
563
564
|
|
|
564
|
-
private getTransform() {
|
|
565
|
-
const transformStyle = this.props.horizontal
|
|
566
|
-
? this.transformStyleHorizontal
|
|
567
|
-
: this.transformStyle;
|
|
568
|
-
return (this.props.inverted && transformStyle) || undefined;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
565
|
private separator = (index: number) => {
|
|
572
566
|
// Make sure we have data and don't read out of bounds
|
|
573
567
|
if (
|
|
@@ -602,7 +596,7 @@ class FlashList<T> extends React.PureComponent<
|
|
|
602
596
|
/>
|
|
603
597
|
|
|
604
598
|
<View
|
|
605
|
-
style={[this.props.ListHeaderComponentStyle
|
|
599
|
+
style={[this.props.ListHeaderComponentStyle]}
|
|
606
600
|
>
|
|
607
601
|
{this.getValidComponent(this.props.ListHeaderComponent)}
|
|
608
602
|
</View>
|
|
@@ -619,7 +613,7 @@ class FlashList<T> extends React.PureComponent<
|
|
|
619
613
|
<>
|
|
620
614
|
<FooterContainer
|
|
621
615
|
index={-1}
|
|
622
|
-
style={[this.props.ListFooterComponentStyle
|
|
616
|
+
style={[this.props.ListFooterComponentStyle]}
|
|
623
617
|
>
|
|
624
618
|
{this.getValidComponent(this.props.ListFooterComponent)}
|
|
625
619
|
</FooterContainer>
|
|
@@ -674,7 +668,7 @@ class FlashList<T> extends React.PureComponent<
|
|
|
674
668
|
private rowRendererWithIndex = (index: number, target: RenderTarget) => {
|
|
675
669
|
// known issue: expected to pass separators which isn't available in RLV
|
|
676
670
|
return this.props.renderItem?.({
|
|
677
|
-
item: this.
|
|
671
|
+
item: this.state.data![index],
|
|
678
672
|
index,
|
|
679
673
|
target,
|
|
680
674
|
extraData: this.state.extraData?.value,
|
|
@@ -693,7 +687,6 @@ class FlashList<T> extends React.PureComponent<
|
|
|
693
687
|
private getCellContainerChild = (index: number) => {
|
|
694
688
|
return (
|
|
695
689
|
<>
|
|
696
|
-
{this.props.inverted ? this.separator(index) : null}
|
|
697
690
|
<View
|
|
698
691
|
style={{
|
|
699
692
|
flexDirection:
|
|
@@ -704,7 +697,7 @@ class FlashList<T> extends React.PureComponent<
|
|
|
704
697
|
>
|
|
705
698
|
{this.rowRendererWithIndex(index, RenderTargetOptions.Cell)}
|
|
706
699
|
</View>
|
|
707
|
-
{this.
|
|
700
|
+
{this.separator(index)}
|
|
708
701
|
</>
|
|
709
702
|
);
|
|
710
703
|
};
|
|
@@ -920,7 +913,8 @@ class FlashList<T> extends React.PureComponent<
|
|
|
920
913
|
* @returns {Object} The layout of the item at the given index.
|
|
921
914
|
*/
|
|
922
915
|
public getLayout(index: number) : Layout | undefined {
|
|
923
|
-
|
|
916
|
+
const l = this.rlvRef?.getLayout(index);
|
|
917
|
+
return l;
|
|
924
918
|
}
|
|
925
919
|
|
|
926
920
|
/**
|