@shopify/flash-list 2.0.0-rc.9 → 2.0.0
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.md +27 -97
- package/dist/AnimatedFlashList.js +2 -2
- package/dist/AnimatedFlashList.js.map +1 -1
- package/dist/FlashList.d.ts +1 -167
- package/dist/FlashList.d.ts.map +1 -1
- package/dist/FlashList.js +3 -595
- package/dist/FlashList.js.map +1 -1
- package/dist/FlashListProps.d.ts +7 -63
- package/dist/FlashListProps.d.ts.map +1 -1
- package/dist/FlashListProps.js.map +1 -1
- package/dist/__tests__/LayoutCommitObserver.test.d.ts +2 -0
- package/dist/__tests__/LayoutCommitObserver.test.d.ts.map +1 -0
- package/dist/__tests__/LayoutCommitObserver.test.js +35 -0
- package/dist/__tests__/LayoutCommitObserver.test.js.map +1 -0
- package/dist/__tests__/ViewabilityHelper.test.js +3 -4
- package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
- package/dist/benchmark/JSFPSMonitor.d.ts.map +1 -1
- package/dist/benchmark/JSFPSMonitor.js +2 -1
- package/dist/benchmark/JSFPSMonitor.js.map +1 -1
- package/dist/benchmark/useBenchmark.d.ts +2 -4
- package/dist/benchmark/useBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useBenchmark.js +12 -49
- package/dist/benchmark/useBenchmark.js.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
- package/dist/benchmark/useFlatListBenchmark.js +2 -1
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/errors/ErrorMessages.d.ts +16 -0
- package/dist/errors/ErrorMessages.d.ts.map +1 -0
- package/dist/errors/ErrorMessages.js +19 -0
- package/dist/errors/ErrorMessages.js.map +1 -0
- package/dist/errors/WarningMessages.d.ts +4 -0
- package/dist/errors/WarningMessages.d.ts.map +1 -0
- package/dist/errors/WarningMessages.js +7 -0
- package/dist/errors/WarningMessages.js.map +1 -0
- package/dist/index.d.ts +4 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -29
- package/dist/index.js.map +1 -1
- package/dist/isNewArch.d.ts +2 -0
- package/dist/isNewArch.d.ts.map +1 -0
- package/dist/isNewArch.js +25 -0
- package/dist/isNewArch.js.map +1 -0
- package/dist/native/config/PlatformHelper.android.d.ts +1 -22
- package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.js +1 -16
- package/dist/native/config/PlatformHelper.android.js.map +1 -1
- package/dist/native/config/PlatformHelper.d.ts +1 -22
- package/dist/native/config/PlatformHelper.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.d.ts +1 -22
- package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.js +1 -15
- package/dist/native/config/PlatformHelper.ios.js.map +1 -1
- package/dist/native/config/PlatformHelper.js +1 -16
- package/dist/native/config/PlatformHelper.js.map +1 -1
- package/dist/native/config/PlatformHelper.web.d.ts +1 -23
- package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.web.js +1 -18
- package/dist/native/config/PlatformHelper.web.js.map +1 -1
- package/dist/recyclerview/LayoutCommitObserver.d.ts +12 -0
- package/dist/recyclerview/LayoutCommitObserver.d.ts.map +1 -0
- package/dist/recyclerview/LayoutCommitObserver.js +62 -0
- package/dist/recyclerview/LayoutCommitObserver.js.map +1 -0
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerView.js +20 -9
- package/dist/recyclerview/RecyclerView.js.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.d.ts +4 -1
- package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.js +43 -34
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/RecyclerViewProps.d.ts +1 -8
- package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts +6 -2
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.js +3 -1
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.js +38 -7
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.js +16 -9
- package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js +2 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
- package/dist/recyclerview/viewability/ViewToken.d.ts.map +1 -0
- package/dist/recyclerview/viewability/ViewToken.js.map +1 -0
- package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.d.ts +2 -2
- package/dist/recyclerview/viewability/ViewabilityHelper.d.ts.map +1 -0
- package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.js +2 -4
- package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.js.map +1 -1
- package/dist/{viewability → recyclerview/viewability}/ViewabilityManager.d.ts +3 -3
- package/dist/recyclerview/viewability/ViewabilityManager.d.ts.map +1 -0
- package/dist/{viewability → recyclerview/viewability}/ViewabilityManager.js +16 -16
- package/dist/recyclerview/viewability/ViewabilityManager.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -14
- package/src/AnimatedFlashList.ts +2 -2
- package/src/FlashList.ts +1 -0
- package/src/FlashListProps.ts +8 -79
- package/src/__tests__/LayoutCommitObserver.test.tsx +60 -0
- package/src/__tests__/ViewabilityHelper.test.ts +13 -14
- package/src/benchmark/JSFPSMonitor.ts +3 -3
- package/src/benchmark/useBenchmark.ts +12 -77
- package/src/benchmark/useFlatListBenchmark.ts +3 -1
- package/src/errors/ErrorMessages.ts +26 -0
- package/src/errors/WarningMessages.ts +4 -0
- package/src/index.ts +11 -43
- package/src/isNewArch.ts +25 -0
- package/src/native/config/PlatformHelper.android.ts +1 -25
- package/src/native/config/PlatformHelper.ios.ts +1 -24
- package/src/native/config/PlatformHelper.ts +1 -25
- package/src/native/config/PlatformHelper.web.ts +1 -30
- package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
- package/src/recyclerview/RecyclerView.tsx +25 -12
- package/src/recyclerview/RecyclerViewManager.ts +40 -40
- package/src/recyclerview/RecyclerViewProps.ts +1 -11
- package/src/recyclerview/ViewHolderCollection.tsx +9 -2
- package/src/recyclerview/hooks/useBoundDetection.ts +48 -6
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +19 -14
- package/src/recyclerview/layout-managers/LayoutManager.ts +2 -1
- package/src/{viewability → recyclerview/viewability}/ViewabilityHelper.ts +8 -9
- package/src/{viewability → recyclerview/viewability}/ViewabilityManager.ts +18 -20
- package/RNFlashList.podspec +0 -37
- package/android/build.gradle +0 -89
- package/android/src/main/AndroidManifest.xml +0 -3
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +0 -105
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +0 -158
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +0 -70
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +0 -29
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainer.java +0 -16
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerImpl.kt +0 -16
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +0 -34
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/FlashListPackage.kt +0 -19
- package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerDelegate.java +0 -47
- package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerInterface.java +0 -21
- package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerDelegate.java +0 -32
- package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerInterface.java +0 -16
- package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +0 -147
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/Rect.kt +0 -61
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestCollection.kt +0 -6
- package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestDataModel.kt +0 -8
- package/android/src/test/resources/LayoutTestData.json +0 -788
- package/dist/GridLayoutProviderWithProps.d.ts +0 -42
- package/dist/GridLayoutProviderWithProps.d.ts.map +0 -1
- package/dist/GridLayoutProviderWithProps.js +0 -114
- package/dist/GridLayoutProviderWithProps.js.map +0 -1
- package/dist/MasonryFlashList.d.ts +0 -51
- package/dist/MasonryFlashList.d.ts.map +0 -1
- package/dist/MasonryFlashList.js +0 -252
- package/dist/MasonryFlashList.js.map +0 -1
- package/dist/PureComponentWrapper.d.ts +0 -22
- package/dist/PureComponentWrapper.d.ts.map +0 -1
- package/dist/PureComponentWrapper.js +0 -37
- package/dist/PureComponentWrapper.js.map +0 -1
- package/dist/__tests__/ContentContainerUtils.test.d.ts +0 -2
- package/dist/__tests__/ContentContainerUtils.test.d.ts.map +0 -1
- package/dist/__tests__/ContentContainerUtils.test.js +0 -85
- package/dist/__tests__/ContentContainerUtils.test.js.map +0 -1
- package/dist/__tests__/FlashList.test.d.ts +0 -2
- package/dist/__tests__/FlashList.test.d.ts.map +0 -1
- package/dist/__tests__/FlashList.test.js +0 -902
- package/dist/__tests__/FlashList.test.js.map +0 -1
- package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts +0 -2
- package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts.map +0 -1
- package/dist/__tests__/GridLayoutProviderWithProps.test.js +0 -143
- package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +0 -1
- package/dist/__tests__/MasonryFlashList.test.d.ts +0 -2
- package/dist/__tests__/MasonryFlashList.test.d.ts.map +0 -1
- package/dist/__tests__/MasonryFlashList.test.js +0 -254
- package/dist/__tests__/MasonryFlashList.test.js.map +0 -1
- package/dist/__tests__/PlatformHelper.web.test.d.ts +0 -2
- package/dist/__tests__/PlatformHelper.web.test.d.ts.map +0 -1
- package/dist/__tests__/PlatformHelper.web.test.js +0 -33
- package/dist/__tests__/PlatformHelper.web.test.js.map +0 -1
- package/dist/__tests__/helpers/mountFlashList.d.ts +0 -19
- package/dist/__tests__/helpers/mountFlashList.d.ts.map +0 -1
- package/dist/__tests__/helpers/mountFlashList.js +0 -44
- package/dist/__tests__/helpers/mountFlashList.js.map +0 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +0 -18
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +0 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.js +0 -49
- package/dist/__tests__/helpers/mountMasonryFlashList.js.map +0 -1
- package/dist/__tests__/useBlankAreaTracker.test.d.ts +0 -2
- package/dist/__tests__/useBlankAreaTracker.test.d.ts.map +0 -1
- package/dist/__tests__/useBlankAreaTracker.test.js +0 -179
- package/dist/__tests__/useBlankAreaTracker.test.js.map +0 -1
- package/dist/benchmark/useBlankAreaTracker.d.ts +0 -34
- package/dist/benchmark/useBlankAreaTracker.d.ts.map +0 -1
- package/dist/benchmark/useBlankAreaTracker.js +0 -66
- package/dist/benchmark/useBlankAreaTracker.js.map +0 -1
- package/dist/enableNewCore.d.ts +0 -3
- package/dist/enableNewCore.d.ts.map +0 -1
- package/dist/enableNewCore.js +0 -25
- package/dist/enableNewCore.js.map +0 -1
- package/dist/errors/CustomError.d.ts +0 -8
- package/dist/errors/CustomError.d.ts.map +0 -1
- package/dist/errors/CustomError.js +0 -14
- package/dist/errors/CustomError.js.map +0 -1
- package/dist/errors/ExceptionList.d.ts +0 -24
- package/dist/errors/ExceptionList.d.ts.map +0 -1
- package/dist/errors/ExceptionList.js +0 -26
- package/dist/errors/ExceptionList.js.map +0 -1
- package/dist/errors/Warnings.d.ts +0 -9
- package/dist/errors/Warnings.d.ts.map +0 -1
- package/dist/errors/Warnings.js +0 -13
- package/dist/errors/Warnings.js.map +0 -1
- package/dist/native/auto-layout/AutoLayoutView.d.ts +0 -22
- package/dist/native/auto-layout/AutoLayoutView.d.ts.map +0 -1
- package/dist/native/auto-layout/AutoLayoutView.js +0 -48
- package/dist/native/auto-layout/AutoLayoutView.js.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts +0 -4
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js +0 -6
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts +0 -5
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts +0 -4
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js +0 -6
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js +0 -6
- package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +0 -16
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +0 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js +0 -3
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js.map +0 -1
- package/dist/native/cell-container/CellContainer.android.d.ts +0 -6
- package/dist/native/cell-container/CellContainer.android.d.ts.map +0 -1
- package/dist/native/cell-container/CellContainer.android.js +0 -9
- package/dist/native/cell-container/CellContainer.android.js.map +0 -1
- package/dist/native/cell-container/CellContainer.d.ts +0 -8
- package/dist/native/cell-container/CellContainer.d.ts.map +0 -1
- package/dist/native/cell-container/CellContainer.ios.d.ts +0 -6
- package/dist/native/cell-container/CellContainer.ios.d.ts.map +0 -1
- package/dist/native/cell-container/CellContainer.ios.js +0 -9
- package/dist/native/cell-container/CellContainer.ios.js.map +0 -1
- package/dist/native/cell-container/CellContainer.js +0 -11
- package/dist/native/cell-container/CellContainer.js.map +0 -1
- package/dist/native/cell-container/CellContainer.web.d.ts +0 -7
- package/dist/native/cell-container/CellContainer.web.d.ts.map +0 -1
- package/dist/native/cell-container/CellContainer.web.js +0 -13
- package/dist/native/cell-container/CellContainer.web.js.map +0 -1
- package/dist/specs/AutoLayoutNativeComponent.d.ts +0 -18
- package/dist/specs/AutoLayoutNativeComponent.d.ts.map +0 -1
- package/dist/specs/AutoLayoutNativeComponent.js +0 -6
- package/dist/specs/AutoLayoutNativeComponent.js.map +0 -1
- package/dist/specs/CellContainerNativeComponent.d.ts +0 -8
- package/dist/specs/CellContainerNativeComponent.d.ts.map +0 -1
- package/dist/specs/CellContainerNativeComponent.js +0 -6
- package/dist/specs/CellContainerNativeComponent.js.map +0 -1
- package/dist/utils/ContentContainerUtils.d.ts +0 -27
- package/dist/utils/ContentContainerUtils.d.ts.map +0 -1
- package/dist/utils/ContentContainerUtils.js +0 -48
- package/dist/utils/ContentContainerUtils.js.map +0 -1
- package/dist/viewability/ViewToken.d.ts.map +0 -1
- package/dist/viewability/ViewToken.js.map +0 -1
- package/dist/viewability/ViewabilityHelper.d.ts.map +0 -1
- package/dist/viewability/ViewabilityManager.d.ts.map +0 -1
- package/dist/viewability/ViewabilityManager.js.map +0 -1
- package/ios/RNFlashList.xcodeproj/project.pbxproj +0 -3
- package/ios/RNFlashList.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -4
- package/ios/Sources/AutoLayoutView.swift +0 -294
- package/ios/Sources/AutoLayoutViewComponentView.h +0 -16
- package/ios/Sources/AutoLayoutViewComponentView.mm +0 -90
- package/ios/Sources/AutoLayoutViewManager.mm +0 -14
- package/ios/Sources/AutoLayoutViewManager.swift +0 -12
- package/ios/Sources/CellContainerComponentView.h +0 -18
- package/ios/Sources/CellContainerComponentView.mm +0 -62
- package/ios/Sources/CellContainerManager.mm +0 -8
- package/ios/Sources/CellContainerManager.swift +0 -12
- package/ios/Sources/FlatListPro-Bridging-Header.h +0 -11
- package/ios/Tests/AutoLayoutViewTests.swift +0 -113
- package/src/FlashList.tsx +0 -953
- package/src/GridLayoutProviderWithProps.ts +0 -180
- package/src/MasonryFlashList.tsx +0 -476
- package/src/PureComponentWrapper.tsx +0 -42
- package/src/__tests__/ContentContainerUtils.test.ts +0 -130
- package/src/__tests__/FlashList.test.tsx +0 -1001
- package/src/__tests__/GridLayoutProviderWithProps.test.ts +0 -179
- package/src/__tests__/MasonryFlashList.test.ts +0 -292
- package/src/__tests__/PlatformHelper.web.test.ts +0 -45
- package/src/__tests__/helpers/mountFlashList.tsx +0 -62
- package/src/__tests__/helpers/mountMasonryFlashList.tsx +0 -70
- package/src/__tests__/useBlankAreaTracker.test.tsx +0 -206
- package/src/benchmark/useBlankAreaTracker.ts +0 -117
- package/src/enableNewCore.ts +0 -24
- package/src/errors/CustomError.ts +0 -10
- package/src/errors/ExceptionList.ts +0 -28
- package/src/errors/Warnings.ts +0 -15
- package/src/native/auto-layout/AutoLayoutView.tsx +0 -73
- package/src/native/auto-layout/AutoLayoutViewNativeComponent.android.ts +0 -7
- package/src/native/auto-layout/AutoLayoutViewNativeComponent.ios.ts +0 -7
- package/src/native/auto-layout/AutoLayoutViewNativeComponent.ts +0 -7
- package/src/native/auto-layout/AutoLayoutViewNativeComponentProps.ts +0 -17
- package/src/native/cell-container/CellContainer.android.ts +0 -7
- package/src/native/cell-container/CellContainer.ios.ts +0 -7
- package/src/native/cell-container/CellContainer.tsx +0 -14
- package/src/native/cell-container/CellContainer.web.tsx +0 -9
- package/src/specs/AutoLayoutNativeComponent.ts +0 -24
- package/src/specs/CellContainerNativeComponent.ts +0 -9
- package/src/utils/ContentContainerUtils.ts +0 -92
- /package/dist/{viewability → recyclerview/viewability}/ViewToken.d.ts +0 -0
- /package/dist/{viewability → recyclerview/viewability}/ViewToken.js +0 -0
- /package/src/{viewability → recyclerview/viewability}/ViewToken.ts +0 -0
|
@@ -1,30 +1,7 @@
|
|
|
1
|
-
import { BaseItemAnimator } from "recyclerlistview";
|
|
2
|
-
|
|
3
1
|
const PlatformConfig = {
|
|
4
2
|
defaultDrawDistance: 250,
|
|
5
3
|
supportsOffsetCorrection: true,
|
|
6
4
|
trackAverageRenderTimeForOffsetProjection: false,
|
|
7
|
-
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
8
|
-
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
9
|
-
};
|
|
10
|
-
const getCellContainerPlatformStyles = (
|
|
11
|
-
inverted: boolean,
|
|
12
|
-
parentProps: { x: number; y: number; isHorizontal?: boolean }
|
|
13
|
-
): { transform: string; WebkitTransform: string } | undefined => {
|
|
14
|
-
return undefined;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const getItemAnimator = (): BaseItemAnimator | undefined => {
|
|
18
|
-
return undefined;
|
|
19
5
|
};
|
|
20
6
|
|
|
21
|
-
|
|
22
|
-
return undefined;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
export {
|
|
26
|
-
PlatformConfig,
|
|
27
|
-
getCellContainerPlatformStyles,
|
|
28
|
-
getItemAnimator,
|
|
29
|
-
getFooterContainer,
|
|
30
|
-
};
|
|
7
|
+
export { PlatformConfig };
|
|
@@ -1,31 +1,7 @@
|
|
|
1
|
-
import { BaseItemAnimator } from "recyclerlistview";
|
|
2
|
-
import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";
|
|
3
|
-
|
|
4
1
|
const PlatformConfig = {
|
|
5
2
|
defaultDrawDistance: 250,
|
|
6
3
|
supportsOffsetCorrection: false,
|
|
7
4
|
trackAverageRenderTimeForOffsetProjection: false,
|
|
8
|
-
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
9
|
-
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
10
|
-
};
|
|
11
|
-
const getCellContainerPlatformStyles = (
|
|
12
|
-
inverted: boolean,
|
|
13
|
-
parentProps: { x: number; y: number; isHorizontal?: boolean }
|
|
14
|
-
): { transform: string; WebkitTransform: string } | undefined => {
|
|
15
|
-
return undefined;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const getItemAnimator = (): BaseItemAnimator | undefined => {
|
|
19
|
-
return new DefaultJSItemAnimator();
|
|
20
5
|
};
|
|
21
6
|
|
|
22
|
-
|
|
23
|
-
return undefined;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export {
|
|
27
|
-
PlatformConfig,
|
|
28
|
-
getCellContainerPlatformStyles,
|
|
29
|
-
getItemAnimator,
|
|
30
|
-
getFooterContainer,
|
|
31
|
-
};
|
|
7
|
+
export { PlatformConfig };
|
|
@@ -1,36 +1,7 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { View } from "react-native";
|
|
3
|
-
import { BaseItemAnimator } from "recyclerlistview";
|
|
4
|
-
import { DefaultJSItemAnimator } from "recyclerlistview/dist/reactnative/platform/reactnative/itemanimators/defaultjsanimator/DefaultJSItemAnimator";
|
|
5
|
-
|
|
6
1
|
const PlatformConfig = {
|
|
7
2
|
defaultDrawDistance: 500,
|
|
8
3
|
supportsOffsetCorrection: false,
|
|
9
4
|
trackAverageRenderTimeForOffsetProjection: false,
|
|
10
|
-
invertedTransformStyle: { transform: [{ scaleY: -1 }] },
|
|
11
|
-
invertedTransformStyleHorizontal: { transform: [{ scaleX: -1 }] },
|
|
12
|
-
};
|
|
13
|
-
const getCellContainerPlatformStyles = (
|
|
14
|
-
inverted: boolean,
|
|
15
|
-
parentProps: { x: number; y: number; isHorizontal?: boolean }
|
|
16
|
-
): { transform: string; WebkitTransform: string } | undefined => {
|
|
17
|
-
const transformValue = `translate(${parentProps.x}px,${parentProps.y}px)${
|
|
18
|
-
inverted ? ` ${parentProps.isHorizontal ? `scaleX` : `scaleY`}(-1)` : ``
|
|
19
|
-
}`;
|
|
20
|
-
return { transform: transformValue, WebkitTransform: transformValue };
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const getItemAnimator = (): BaseItemAnimator | undefined => {
|
|
24
|
-
return new DefaultJSItemAnimator();
|
|
25
5
|
};
|
|
26
6
|
|
|
27
|
-
|
|
28
|
-
return View;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export {
|
|
32
|
-
PlatformConfig,
|
|
33
|
-
getCellContainerPlatformStyles,
|
|
34
|
-
getItemAnimator,
|
|
35
|
-
getFooterContainer,
|
|
36
|
-
};
|
|
7
|
+
export { PlatformConfig };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { useLayoutEffect, useMemo, useRef } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
RecyclerViewContext,
|
|
5
|
+
RecyclerViewContextProvider,
|
|
6
|
+
useRecyclerViewContext,
|
|
7
|
+
} from "./RecyclerViewContextProvider";
|
|
8
|
+
import { useLayoutState } from "./hooks/useLayoutState";
|
|
9
|
+
|
|
10
|
+
export interface LayoutCommitObserverProps {
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
onCommitLayoutEffect?: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* LayoutCommitObserver can be used to observe when FlashList commits a layout.
|
|
17
|
+
* It is useful when your component has one or more FlashLists somewhere down the tree.
|
|
18
|
+
* LayoutCommitObserver will trigger `onCommitLayoutEffect` when all of the FlashLists in the tree have finished their first commit.
|
|
19
|
+
*/
|
|
20
|
+
export const LayoutCommitObserver = React.memo(
|
|
21
|
+
(props: LayoutCommitObserverProps) => {
|
|
22
|
+
const { children, onCommitLayoutEffect } = props;
|
|
23
|
+
const parentRecyclerViewContext = useRecyclerViewContext();
|
|
24
|
+
const [_, setRenderId] = useLayoutState(0);
|
|
25
|
+
const pendingChildIds = useRef<Set<string>>(new Set()).current;
|
|
26
|
+
|
|
27
|
+
useLayoutEffect(() => {
|
|
28
|
+
if (pendingChildIds.size > 0) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
onCommitLayoutEffect?.();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Create context for child components
|
|
35
|
+
const recyclerViewContext: RecyclerViewContext<unknown> = useMemo(() => {
|
|
36
|
+
return {
|
|
37
|
+
layout: () => {
|
|
38
|
+
setRenderId((prev) => prev + 1);
|
|
39
|
+
},
|
|
40
|
+
getRef: () => {
|
|
41
|
+
return parentRecyclerViewContext?.getRef() ?? null;
|
|
42
|
+
},
|
|
43
|
+
getParentRef: () => {
|
|
44
|
+
return parentRecyclerViewContext?.getParentRef() ?? null;
|
|
45
|
+
},
|
|
46
|
+
getParentScrollViewRef: () => {
|
|
47
|
+
return parentRecyclerViewContext?.getParentScrollViewRef() ?? null;
|
|
48
|
+
},
|
|
49
|
+
getScrollViewRef: () => {
|
|
50
|
+
return parentRecyclerViewContext?.getScrollViewRef() ?? null;
|
|
51
|
+
},
|
|
52
|
+
markChildLayoutAsPending: (id: string) => {
|
|
53
|
+
parentRecyclerViewContext?.markChildLayoutAsPending(id);
|
|
54
|
+
pendingChildIds.add(id);
|
|
55
|
+
},
|
|
56
|
+
unmarkChildLayoutAsPending: (id: string) => {
|
|
57
|
+
parentRecyclerViewContext?.unmarkChildLayoutAsPending(id);
|
|
58
|
+
if (pendingChildIds.has(id)) {
|
|
59
|
+
pendingChildIds.delete(id);
|
|
60
|
+
recyclerViewContext.layout();
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}, [parentRecyclerViewContext, pendingChildIds, setRenderId]);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<RecyclerViewContextProvider value={recyclerViewContext}>
|
|
68
|
+
{children}
|
|
69
|
+
</RecyclerViewContextProvider>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
LayoutCommitObserver.displayName = "LayoutCommitObserver";
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from "react-native";
|
|
21
21
|
|
|
22
22
|
import { FlashListRef } from "../FlashListRef";
|
|
23
|
+
import { ErrorMessages } from "../errors/ErrorMessages";
|
|
23
24
|
|
|
24
25
|
import { RVDimension } from "./layout-managers/LayoutManager";
|
|
25
26
|
import {
|
|
@@ -384,6 +385,9 @@ const RecyclerViewComponent = <T,>(
|
|
|
384
385
|
stickyHeaderIndices &&
|
|
385
386
|
stickyHeaderIndices.length > 0
|
|
386
387
|
) {
|
|
388
|
+
if (horizontal) {
|
|
389
|
+
throw new Error(ErrorMessages.stickyHeadersNotSupportedForHorizontal);
|
|
390
|
+
}
|
|
387
391
|
return (
|
|
388
392
|
<StickyHeaders
|
|
389
393
|
stickyHeaderIndices={stickyHeaderIndices}
|
|
@@ -402,6 +406,7 @@ const RecyclerViewComponent = <T,>(
|
|
|
402
406
|
stickyHeaderIndices,
|
|
403
407
|
renderItem,
|
|
404
408
|
scrollY,
|
|
409
|
+
horizontal,
|
|
405
410
|
recyclerViewManager,
|
|
406
411
|
extraData,
|
|
407
412
|
]);
|
|
@@ -434,16 +439,6 @@ const RecyclerViewComponent = <T,>(
|
|
|
434
439
|
recyclerViewManager.getDataLength() > 0 &&
|
|
435
440
|
(maintainVisibleContentPosition?.startRenderingFromBottom ?? false);
|
|
436
441
|
|
|
437
|
-
// Calculate minimum height adjustment for bottom rendering
|
|
438
|
-
const adjustmentMinHeight = recyclerViewManager.hasLayout()
|
|
439
|
-
? Math.max(
|
|
440
|
-
0,
|
|
441
|
-
recyclerViewManager.getWindowSize().height -
|
|
442
|
-
recyclerViewManager.getChildContainerDimensions().height -
|
|
443
|
-
recyclerViewManager.firstItemOffset
|
|
444
|
-
)
|
|
445
|
-
: 0;
|
|
446
|
-
|
|
447
442
|
// Create view for measuring bounded size
|
|
448
443
|
const viewToMeasureBoundedSize = useMemo(() => {
|
|
449
444
|
return (
|
|
@@ -451,12 +446,11 @@ const RecyclerViewComponent = <T,>(
|
|
|
451
446
|
style={{
|
|
452
447
|
height: horizontal ? undefined : 0,
|
|
453
448
|
width: horizontal ? 0 : undefined,
|
|
454
|
-
minHeight: shouldRenderFromBottom ? adjustmentMinHeight : undefined,
|
|
455
449
|
}}
|
|
456
450
|
ref={firstChildViewRef}
|
|
457
451
|
/>
|
|
458
452
|
);
|
|
459
|
-
}, [horizontal
|
|
453
|
+
}, [horizontal]);
|
|
460
454
|
|
|
461
455
|
const scrollAnchor = useMemo(() => {
|
|
462
456
|
if (shouldMaintainVisibleContentPosition) {
|
|
@@ -527,6 +521,25 @@ const RecyclerViewComponent = <T,>(
|
|
|
527
521
|
horizontal={horizontal}
|
|
528
522
|
renderStack={recyclerViewManager.getRenderStack()}
|
|
529
523
|
getLayout={(index) => recyclerViewManager.getLayout(index)}
|
|
524
|
+
getAdjustmentMargin={() => {
|
|
525
|
+
if (!shouldRenderFromBottom || !recyclerViewManager.hasLayout()) {
|
|
526
|
+
return 0;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const windowSize = horizontal
|
|
530
|
+
? recyclerViewManager.getWindowSize().width
|
|
531
|
+
: recyclerViewManager.getWindowSize().height;
|
|
532
|
+
const childContainerSize = horizontal
|
|
533
|
+
? recyclerViewManager.getChildContainerDimensions().width
|
|
534
|
+
: recyclerViewManager.getChildContainerDimensions().height;
|
|
535
|
+
|
|
536
|
+
return Math.max(
|
|
537
|
+
0,
|
|
538
|
+
windowSize -
|
|
539
|
+
childContainerSize -
|
|
540
|
+
recyclerViewManager.firstItemOffset
|
|
541
|
+
);
|
|
542
|
+
}}
|
|
530
543
|
refHolder={refHolder}
|
|
531
544
|
onSizeChanged={validateItemSize}
|
|
532
545
|
renderItem={renderItem}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ErrorMessages } from "../errors/ErrorMessages";
|
|
2
2
|
|
|
3
|
+
import ViewabilityManager from "./viewability/ViewabilityManager";
|
|
3
4
|
import { ConsecutiveNumbers } from "./helpers/ConsecutiveNumbers";
|
|
4
5
|
import { RVGridLayoutManagerImpl } from "./layout-managers/GridLayoutManager";
|
|
5
6
|
import {
|
|
@@ -20,13 +21,14 @@ import {
|
|
|
20
21
|
import { RenderStackManager } from "./RenderStackManager";
|
|
21
22
|
// Abstracts layout manager, render stack manager and viewability manager and generates render stack (progressively on load)
|
|
22
23
|
export class RecyclerViewManager<T> {
|
|
23
|
-
private initialDrawBatchSize =
|
|
24
|
+
private initialDrawBatchSize = 2;
|
|
24
25
|
private engagedIndicesTracker: RVEngagedIndicesTracker;
|
|
25
26
|
private renderStackManager: RenderStackManager;
|
|
26
27
|
private layoutManager?: RVLayoutManager;
|
|
27
28
|
// Map of index to key
|
|
28
29
|
private isFirstLayoutComplete = false;
|
|
29
30
|
private hasRenderedProgressively = false;
|
|
31
|
+
private progressiveRenderCount = 0;
|
|
30
32
|
private propsRef: RecyclerViewProps<T>;
|
|
31
33
|
private itemViewabilityManager: ViewabilityManager<T>;
|
|
32
34
|
private _isDisposed = false;
|
|
@@ -53,8 +55,12 @@ export class RecyclerViewManager<T> {
|
|
|
53
55
|
return this._isDisposed;
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
public get numColumns() {
|
|
59
|
+
return this.propsRef.numColumns ?? 1;
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
constructor(props: RecyclerViewProps<T>) {
|
|
57
|
-
this.
|
|
63
|
+
this.getDataKey = this.getDataKey.bind(this);
|
|
58
64
|
this.getItemType = this.getItemType.bind(this);
|
|
59
65
|
this.overrideItemLayout = this.overrideItemLayout.bind(this);
|
|
60
66
|
this.propsRef = props;
|
|
@@ -68,7 +74,7 @@ export class RecyclerViewManager<T> {
|
|
|
68
74
|
// updates render stack based on the engaged indices which are sorted. Recycles unused keys.
|
|
69
75
|
private updateRenderStack = (engagedIndices: ConsecutiveNumbers): void => {
|
|
70
76
|
this.renderStackManager.sync(
|
|
71
|
-
this.
|
|
77
|
+
this.getDataKey,
|
|
72
78
|
this.getItemType,
|
|
73
79
|
engagedIndices,
|
|
74
80
|
this.getDataLength()
|
|
@@ -87,11 +93,6 @@ export class RecyclerViewManager<T> {
|
|
|
87
93
|
this.propsRef = props;
|
|
88
94
|
this.engagedIndicesTracker.drawDistance =
|
|
89
95
|
props.drawDistance ?? this.engagedIndicesTracker.drawDistance;
|
|
90
|
-
if (this.propsRef.drawDistance === 0) {
|
|
91
|
-
this.initialDrawBatchSize = 1;
|
|
92
|
-
} else {
|
|
93
|
-
this.initialDrawBatchSize = (props.numColumns ?? 1) * 2;
|
|
94
|
-
}
|
|
95
96
|
this.initialDrawBatchSize =
|
|
96
97
|
this.propsRef.overrideProps?.initialDrawBatchSize ??
|
|
97
98
|
this.initialDrawBatchSize;
|
|
@@ -131,9 +132,7 @@ export class RecyclerViewManager<T> {
|
|
|
131
132
|
|
|
132
133
|
getLayout(index: number) {
|
|
133
134
|
if (!this.layoutManager) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
"LayoutManager is not initialized, layout info is unavailable"
|
|
136
|
-
);
|
|
135
|
+
throw new Error(ErrorMessages.layoutManagerNotInitializedLayoutInfo);
|
|
137
136
|
}
|
|
138
137
|
return this.layoutManager.getLayout(index);
|
|
139
138
|
}
|
|
@@ -152,9 +151,7 @@ export class RecyclerViewManager<T> {
|
|
|
152
151
|
// Doesn't include header / foot etc
|
|
153
152
|
getChildContainerDimensions() {
|
|
154
153
|
if (!this.layoutManager) {
|
|
155
|
-
throw new Error(
|
|
156
|
-
"LayoutManager is not initialized, child container layout is unavailable"
|
|
157
|
-
);
|
|
154
|
+
throw new Error(ErrorMessages.layoutManagerNotInitializedChildContainer);
|
|
158
155
|
}
|
|
159
156
|
return this.layoutManager.getLayoutSize();
|
|
160
157
|
}
|
|
@@ -165,9 +162,7 @@ export class RecyclerViewManager<T> {
|
|
|
165
162
|
|
|
166
163
|
getWindowSize() {
|
|
167
164
|
if (!this.layoutManager) {
|
|
168
|
-
throw new Error(
|
|
169
|
-
"LayoutManager is not initialized, window size is unavailable"
|
|
170
|
-
);
|
|
165
|
+
throw new Error(ErrorMessages.layoutManagerNotInitializedWindowSize);
|
|
171
166
|
}
|
|
172
167
|
return this.layoutManager.getWindowsSize();
|
|
173
168
|
}
|
|
@@ -211,9 +206,7 @@ export class RecyclerViewManager<T> {
|
|
|
211
206
|
Boolean(this.layoutManager?.isHorizontal()) !==
|
|
212
207
|
Boolean(this.propsRef.horizontal)
|
|
213
208
|
) {
|
|
214
|
-
throw new Error(
|
|
215
|
-
"Horizontal prop cannot be toggled, you can use a key on FlashList to recreate it."
|
|
216
|
-
);
|
|
209
|
+
throw new Error(ErrorMessages.horizontalPropCannotBeToggled);
|
|
217
210
|
}
|
|
218
211
|
if (this._isLayoutManagerDirty) {
|
|
219
212
|
this.layoutManager = undefined;
|
|
@@ -221,7 +214,7 @@ export class RecyclerViewManager<T> {
|
|
|
221
214
|
}
|
|
222
215
|
const layoutManagerParams: LayoutParams = {
|
|
223
216
|
windowSize,
|
|
224
|
-
maxColumns: this.
|
|
217
|
+
maxColumns: this.numColumns,
|
|
225
218
|
horizontal: Boolean(this.propsRef.horizontal),
|
|
226
219
|
optimizeItemArrangement: this.propsRef.optimizeItemArrangement ?? true,
|
|
227
220
|
overrideItemLayout: this.overrideItemLayout,
|
|
@@ -245,9 +238,7 @@ export class RecyclerViewManager<T> {
|
|
|
245
238
|
|
|
246
239
|
computeVisibleIndices() {
|
|
247
240
|
if (!this.layoutManager) {
|
|
248
|
-
throw new Error(
|
|
249
|
-
"LayoutManager is not initialized, visible indices are not unavailable"
|
|
250
|
-
);
|
|
241
|
+
throw new Error(ErrorMessages.layoutManagerNotInitializedVisibleIndices);
|
|
251
242
|
}
|
|
252
243
|
return this.engagedIndicesTracker.computeVisibleIndices(this.layoutManager);
|
|
253
244
|
}
|
|
@@ -298,7 +289,7 @@ export class RecyclerViewManager<T> {
|
|
|
298
289
|
processDataUpdate() {
|
|
299
290
|
if (this.hasLayout()) {
|
|
300
291
|
this.modifyChildrenLayout([], this.propsRef.data?.length ?? 0);
|
|
301
|
-
if (!this.recomputeEngagedIndices()) {
|
|
292
|
+
if (this.hasRenderedProgressively && !this.recomputeEngagedIndices()) {
|
|
302
293
|
// recomputeEngagedIndices will update the render stack if there are any changes in the engaged indices.
|
|
303
294
|
// It's important to update render stack so that elements are assgined right keys incase items were deleted.
|
|
304
295
|
this.updateRenderStack(this.engagedIndicesTracker.getEngagedIndices());
|
|
@@ -346,17 +337,28 @@ export class RecyclerViewManager<T> {
|
|
|
346
337
|
return this.propsRef.data?.length ?? 0;
|
|
347
338
|
}
|
|
348
339
|
|
|
340
|
+
hasStableDataKeys() {
|
|
341
|
+
return Boolean(this.propsRef.keyExtractor);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
getDataKey(index: number): string {
|
|
345
|
+
return (
|
|
346
|
+
this.propsRef.keyExtractor?.(this.propsRef.data![index], index) ??
|
|
347
|
+
index.toString()
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
349
351
|
private getLayoutManagerClass() {
|
|
350
352
|
// throw errors for incompatible props
|
|
351
353
|
if (this.propsRef.masonry && this.propsRef.horizontal) {
|
|
352
|
-
throw new Error(
|
|
354
|
+
throw new Error(ErrorMessages.masonryAndHorizontalIncompatible);
|
|
353
355
|
}
|
|
354
|
-
if (
|
|
355
|
-
throw new Error(
|
|
356
|
+
if (this.numColumns > 1 && this.propsRef.horizontal) {
|
|
357
|
+
throw new Error(ErrorMessages.numColumnsAndHorizontalIncompatible);
|
|
356
358
|
}
|
|
357
359
|
return this.propsRef.masonry
|
|
358
360
|
? RVMasonryLayoutManagerImpl
|
|
359
|
-
:
|
|
361
|
+
: this.numColumns > 1 && !this.propsRef.horizontal
|
|
360
362
|
? RVGridLayoutManagerImpl
|
|
361
363
|
: RVLinearLayoutManagerImpl;
|
|
362
364
|
}
|
|
@@ -392,6 +394,7 @@ export class RecyclerViewManager<T> {
|
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
private renderProgressively() {
|
|
397
|
+
this.progressiveRenderCount++;
|
|
395
398
|
const layoutManager = this.layoutManager;
|
|
396
399
|
if (layoutManager) {
|
|
397
400
|
this.applyInitialScrollAdjustment();
|
|
@@ -407,16 +410,20 @@ export class RecyclerViewManager<T> {
|
|
|
407
410
|
this.isFirstLayoutComplete = true;
|
|
408
411
|
}
|
|
409
412
|
|
|
413
|
+
const batchSize =
|
|
414
|
+
this.numColumns *
|
|
415
|
+
this.initialDrawBatchSize ** Math.ceil(this.progressiveRenderCount / 5);
|
|
416
|
+
|
|
410
417
|
// If everything is measured then render stack will be in sync. The buffer items will get rendered in the next update
|
|
411
418
|
// triggered by the useOnLoad hook.
|
|
412
419
|
!this.hasRenderedProgressively &&
|
|
413
420
|
this.updateRenderStack(
|
|
414
|
-
// pick first n indices from visible ones
|
|
421
|
+
// pick first n indices from visible ones based on batch size
|
|
415
422
|
visibleIndices.slice(
|
|
416
423
|
0,
|
|
417
424
|
Math.min(
|
|
418
425
|
visibleIndices.length,
|
|
419
|
-
this.getRenderStack().size +
|
|
426
|
+
this.getRenderStack().size + batchSize
|
|
420
427
|
)
|
|
421
428
|
)
|
|
422
429
|
);
|
|
@@ -430,19 +437,12 @@ export class RecyclerViewManager<T> {
|
|
|
430
437
|
).toString();
|
|
431
438
|
}
|
|
432
439
|
|
|
433
|
-
private getStableId(index: number): string {
|
|
434
|
-
return (
|
|
435
|
-
this.propsRef.keyExtractor?.(this.propsRef.data![index], index) ??
|
|
436
|
-
index.toString()
|
|
437
|
-
);
|
|
438
|
-
}
|
|
439
|
-
|
|
440
440
|
private overrideItemLayout(index: number, layout: SpanSizeInfo) {
|
|
441
441
|
this.propsRef?.overrideItemLayout?.(
|
|
442
442
|
layout,
|
|
443
443
|
this.propsRef.data![index],
|
|
444
444
|
index,
|
|
445
|
-
this.
|
|
445
|
+
this.numColumns,
|
|
446
446
|
this.propsRef.extraData
|
|
447
447
|
);
|
|
448
448
|
}
|
|
@@ -1,11 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { FlashListProps } from "../FlashListProps";
|
|
4
|
-
|
|
5
|
-
export interface RecyclerViewProps<TItem>
|
|
6
|
-
extends Omit<FlashListProps<TItem>, "contentContainerStyle"> {
|
|
7
|
-
/**
|
|
8
|
-
* Style for the RecyclerView's parent container.
|
|
9
|
-
*/
|
|
10
|
-
contentContainerStyle?: ScrollViewProps["contentContainerStyle"];
|
|
11
|
-
}
|
|
1
|
+
export { FlashListProps as RecyclerViewProps } from "../FlashListProps";
|
|
@@ -37,15 +37,19 @@ export interface ViewHolderCollectionProps<TItem> {
|
|
|
37
37
|
/** Function to get the container's layout dimensions */
|
|
38
38
|
getChildContainerLayout: () => RVDimension | undefined;
|
|
39
39
|
/** Callback after layout effects are committed */
|
|
40
|
-
onCommitLayoutEffect
|
|
40
|
+
onCommitLayoutEffect: () => void;
|
|
41
41
|
/** Callback after effects are committed */
|
|
42
|
-
onCommitEffect
|
|
42
|
+
onCommitEffect: () => void;
|
|
43
43
|
/** Optional custom component to wrap each item */
|
|
44
44
|
CellRendererComponent?: FlashListProps<TItem>["CellRendererComponent"];
|
|
45
45
|
/** Optional component to render between items */
|
|
46
46
|
ItemSeparatorComponent?: FlashListProps<TItem>["ItemSeparatorComponent"];
|
|
47
47
|
/** Whether the list is horizontal or vertical */
|
|
48
48
|
horizontal: FlashListProps<TItem>["horizontal"];
|
|
49
|
+
/** Function to get the adjustment margin for the container.
|
|
50
|
+
* For startRenderingFromBottom, we need to adjust the height of the container
|
|
51
|
+
*/
|
|
52
|
+
getAdjustmentMargin: () => number;
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
/**
|
|
@@ -79,6 +83,7 @@ export const ViewHolderCollection = <TItem,>(
|
|
|
79
83
|
ItemSeparatorComponent,
|
|
80
84
|
onCommitEffect,
|
|
81
85
|
horizontal,
|
|
86
|
+
getAdjustmentMargin,
|
|
82
87
|
} = props;
|
|
83
88
|
|
|
84
89
|
const [renderId, setRenderId] = React.useState(0);
|
|
@@ -136,6 +141,8 @@ export const ViewHolderCollection = <TItem,>(
|
|
|
136
141
|
const containerStyle = {
|
|
137
142
|
width: horizontal ? containerLayout?.width : undefined,
|
|
138
143
|
height: containerLayout?.height,
|
|
144
|
+
marginTop: horizontal ? undefined : getAdjustmentMargin(),
|
|
145
|
+
marginLeft: horizontal ? getAdjustmentMargin() : undefined,
|
|
139
146
|
// TODO: Temp workaround, useLayoutEffect doesn't block paint in some cases
|
|
140
147
|
// We need to investigate why this is happening
|
|
141
148
|
opacity: renderId > 0 ? 1 : 0,
|
|
@@ -26,14 +26,35 @@ export function useBoundDetection<T>(
|
|
|
26
26
|
const pendingStartReached = useRef(false);
|
|
27
27
|
// Track whether we should auto-scroll to bottom when new content is added
|
|
28
28
|
const pendingAutoscrollToBottom = useRef(false);
|
|
29
|
+
|
|
30
|
+
const lastCheckBoundsTime = useRef(Date.now());
|
|
31
|
+
|
|
29
32
|
const { data } = recyclerViewManager.props;
|
|
30
33
|
const { requestAnimationFrame } = useUnmountAwareAnimationFrame();
|
|
31
34
|
|
|
35
|
+
const windowHeight = recyclerViewManager.hasLayout()
|
|
36
|
+
? recyclerViewManager.getWindowSize().height
|
|
37
|
+
: 0;
|
|
38
|
+
|
|
39
|
+
const contentHeight = recyclerViewManager.hasLayout()
|
|
40
|
+
? recyclerViewManager.getChildContainerDimensions().height
|
|
41
|
+
: 0;
|
|
42
|
+
|
|
43
|
+
const windowWidth = recyclerViewManager.hasLayout()
|
|
44
|
+
? recyclerViewManager.getWindowSize().width
|
|
45
|
+
: 0;
|
|
46
|
+
|
|
47
|
+
const contentWidth = recyclerViewManager.hasLayout()
|
|
48
|
+
? recyclerViewManager.getChildContainerDimensions().width
|
|
49
|
+
: 0;
|
|
50
|
+
|
|
32
51
|
/**
|
|
33
52
|
* Checks if the scroll position is near the start or end of the list
|
|
34
53
|
* and triggers appropriate callbacks if configured.
|
|
35
54
|
*/
|
|
36
55
|
const checkBounds = useCallback(() => {
|
|
56
|
+
lastCheckBoundsTime.current = Date.now();
|
|
57
|
+
|
|
37
58
|
const {
|
|
38
59
|
onEndReached,
|
|
39
60
|
onStartReached,
|
|
@@ -111,6 +132,20 @@ export function useBoundDetection<T>(
|
|
|
111
132
|
}
|
|
112
133
|
}, [recyclerViewManager]);
|
|
113
134
|
|
|
135
|
+
const runAutoScrollToBottomCheck = useCallback(() => {
|
|
136
|
+
if (pendingAutoscrollToBottom.current) {
|
|
137
|
+
pendingAutoscrollToBottom.current = false;
|
|
138
|
+
requestAnimationFrame(() => {
|
|
139
|
+
const shouldAnimate =
|
|
140
|
+
recyclerViewManager.props.maintainVisibleContentPosition
|
|
141
|
+
?.animateAutoScrollToBottom ?? true;
|
|
142
|
+
scrollViewRef.current?.scrollToEnd({
|
|
143
|
+
animated: shouldAnimate,
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}, [requestAnimationFrame, scrollViewRef, recyclerViewManager]);
|
|
148
|
+
|
|
114
149
|
// Reset end reached state when data changes
|
|
115
150
|
useMemo(() => {
|
|
116
151
|
pendingEndReached.current = false;
|
|
@@ -120,13 +155,20 @@ export function useBoundDetection<T>(
|
|
|
120
155
|
|
|
121
156
|
// Auto-scroll to bottom when new content is added and we're near the bottom
|
|
122
157
|
useEffect(() => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
158
|
+
runAutoScrollToBottomCheck();
|
|
159
|
+
}, [data, runAutoScrollToBottomCheck, windowHeight, windowWidth]);
|
|
160
|
+
|
|
161
|
+
// Since content changes frequently, we try and avoid doing the auto scroll during active scrolls
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
if (Date.now() - lastCheckBoundsTime.current >= 100) {
|
|
164
|
+
runAutoScrollToBottomCheck();
|
|
128
165
|
}
|
|
129
|
-
}, [
|
|
166
|
+
}, [
|
|
167
|
+
contentHeight,
|
|
168
|
+
contentWidth,
|
|
169
|
+
recyclerViewManager.firstItemOffset,
|
|
170
|
+
runAutoScrollToBottomCheck,
|
|
171
|
+
]);
|
|
130
172
|
|
|
131
173
|
return {
|
|
132
174
|
checkBounds,
|