@shopify/flash-list 2.0.0-alpha.2 → 2.0.0-alpha.21
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 +67 -96
- package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +2 -2
- package/dist/AnimatedFlashList.d.ts +0 -1
- package/dist/AnimatedFlashList.d.ts.map +1 -1
- package/dist/AnimatedFlashList.js +3 -3
- package/dist/AnimatedFlashList.js.map +1 -1
- package/dist/FlashList.d.ts +9 -0
- package/dist/FlashList.d.ts.map +1 -1
- package/dist/FlashList.js +22 -3
- package/dist/FlashList.js.map +1 -1
- package/dist/FlashListProps.d.ts +33 -13
- package/dist/FlashListProps.d.ts.map +1 -1
- package/dist/FlashListProps.js.map +1 -1
- package/dist/FlashListRef.d.ts +305 -0
- package/dist/FlashListRef.d.ts.map +1 -0
- package/dist/FlashListRef.js +3 -0
- package/dist/FlashListRef.js.map +1 -0
- package/dist/GridLayoutProviderWithProps.js +1 -2
- package/dist/GridLayoutProviderWithProps.js.map +1 -1
- package/dist/MasonryFlashList.d.ts +2 -2
- package/dist/MasonryFlashList.d.ts.map +1 -1
- package/dist/MasonryFlashList.js.map +1 -1
- package/dist/PureComponentWrapper.js +1 -1
- package/dist/PureComponentWrapper.js.map +1 -1
- package/dist/__tests__/AverageWindow.test.js.map +1 -1
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts +2 -0
- package/dist/__tests__/ConsecutiveNumbers.test.d.ts.map +1 -0
- package/dist/__tests__/ConsecutiveNumbers.test.js +224 -0
- package/dist/__tests__/ConsecutiveNumbers.test.js.map +1 -0
- package/dist/__tests__/FlashList.test.js.map +1 -1
- package/dist/__tests__/GridLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/GridLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/GridLayoutManager.test.js +69 -0
- package/dist/__tests__/GridLayoutManager.test.js.map +1 -0
- package/dist/__tests__/GridLayoutProviderWithProps.test.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__/LinearLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/LinearLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/LinearLayoutManager.test.js +140 -0
- package/dist/__tests__/LinearLayoutManager.test.js.map +1 -0
- package/dist/__tests__/MasonryFlashList.test.js.map +1 -1
- package/dist/__tests__/MasonryLayoutManager.test.d.ts +2 -0
- package/dist/__tests__/MasonryLayoutManager.test.d.ts.map +1 -0
- package/dist/__tests__/MasonryLayoutManager.test.js +148 -0
- package/dist/__tests__/MasonryLayoutManager.test.js.map +1 -0
- package/dist/__tests__/RecyclerView.test.d.ts +2 -0
- package/dist/__tests__/RecyclerView.test.d.ts.map +1 -0
- package/dist/__tests__/RecyclerView.test.js +103 -0
- package/dist/__tests__/RecyclerView.test.js.map +1 -0
- package/dist/__tests__/RenderStackManager.test.d.ts +2 -0
- package/dist/__tests__/RenderStackManager.test.d.ts.map +1 -0
- package/dist/__tests__/RenderStackManager.test.js +485 -0
- package/dist/__tests__/RenderStackManager.test.js.map +1 -0
- package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
- package/dist/__tests__/findVisibleIndex.test.d.ts +2 -0
- package/dist/__tests__/findVisibleIndex.test.d.ts.map +1 -0
- package/dist/__tests__/findVisibleIndex.test.js +259 -0
- package/dist/__tests__/findVisibleIndex.test.js.map +1 -0
- package/dist/__tests__/helpers/createLayoutManager.d.ts +34 -0
- package/dist/__tests__/helpers/createLayoutManager.d.ts.map +1 -0
- package/dist/__tests__/helpers/createLayoutManager.js +110 -0
- package/dist/__tests__/helpers/createLayoutManager.js.map +1 -0
- package/dist/__tests__/helpers/mountFlashList.d.ts +2 -2
- package/dist/__tests__/helpers/mountFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountFlashList.js +2 -2
- package/dist/__tests__/helpers/mountFlashList.js.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +2 -2
- package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +1 -1
- package/dist/__tests__/helpers/mountMasonryFlashList.js +2 -2
- package/dist/__tests__/helpers/mountMasonryFlashList.js.map +1 -1
- package/dist/__tests__/useBlankAreaTracker.test.js.map +1 -1
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts +2 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.d.ts.map +1 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.js +185 -0
- package/dist/__tests__/useUnmountAwareCallbacks.test.js.map +1 -0
- 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 -28
- 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 +9 -9
- package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
- package/dist/enableNewCore.d.ts.map +1 -1
- package/dist/enableNewCore.js +4 -4
- package/dist/enableNewCore.js.map +1 -1
- package/dist/errors/CustomError.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -3
- 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.d.ts.map +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +1 -1
- package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.d.ts +2 -0
- package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.android.js +2 -0
- package/dist/native/config/PlatformHelper.android.js.map +1 -1
- package/dist/native/config/PlatformHelper.d.ts +2 -0
- package/dist/native/config/PlatformHelper.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.d.ts +2 -0
- package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.ios.js +2 -0
- package/dist/native/config/PlatformHelper.ios.js.map +1 -1
- package/dist/native/config/PlatformHelper.js +2 -0
- package/dist/native/config/PlatformHelper.js.map +1 -1
- package/dist/native/config/PlatformHelper.web.d.ts +2 -0
- package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
- package/dist/native/config/PlatformHelper.web.js +3 -1
- 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 +3 -2
- package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerView.js +133 -69
- package/dist/recyclerview/RecyclerView.js.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts +41 -7
- package/dist/recyclerview/RecyclerViewContextProvider.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewContextProvider.js +6 -2
- package/dist/recyclerview/RecyclerViewContextProvider.js.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.d.ts +31 -7
- package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/RecyclerViewManager.js +154 -117
- package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/RecyclerViewProps.d.ts +1 -1
- package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
- package/dist/recyclerview/RenderStackManager.d.ts +86 -0
- package/dist/recyclerview/RenderStackManager.d.ts.map +1 -0
- package/dist/recyclerview/RenderStackManager.js +343 -0
- package/dist/recyclerview/RenderStackManager.js.map +1 -0
- package/dist/recyclerview/ViewHolder.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolder.js +8 -6
- package/dist/recyclerview/ViewHolder.js.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.d.ts +10 -4
- package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
- package/dist/recyclerview/ViewHolderCollection.js +26 -10
- package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.d.ts +2 -1
- package/dist/recyclerview/components/ScrollAnchor.d.ts.map +1 -1
- package/dist/recyclerview/components/ScrollAnchor.js +12 -9
- package/dist/recyclerview/components/ScrollAnchor.js.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.d.ts +2 -2
- package/dist/recyclerview/components/StickyHeaders.d.ts.map +1 -1
- package/dist/recyclerview/components/StickyHeaders.js +44 -45
- package/dist/recyclerview/components/StickyHeaders.js.map +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.d.ts.map +1 -1
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js +2 -2
- package/dist/recyclerview/helpers/ConsecutiveNumbers.js.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts +48 -2
- package/dist/recyclerview/helpers/EngagedIndicesTracker.d.ts.map +1 -1
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js +89 -19
- package/dist/recyclerview/helpers/EngagedIndicesTracker.js.map +1 -1
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts +11 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.js +42 -0
- package/dist/recyclerview/helpers/RenderTimeTracker.js.map +1 -0
- package/dist/recyclerview/helpers/VelocityTracker.d.ts +29 -0
- package/dist/recyclerview/helpers/VelocityTracker.d.ts.map +1 -0
- package/dist/recyclerview/helpers/VelocityTracker.js +70 -0
- package/dist/recyclerview/helpers/VelocityTracker.js.map +1 -0
- package/dist/recyclerview/hooks/useBoundDetection.d.ts +1 -3
- package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useBoundDetection.js +60 -28
- package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
- package/dist/recyclerview/hooks/useLayoutState.d.ts +3 -1
- package/dist/recyclerview/hooks/useLayoutState.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useLayoutState.js +6 -5
- package/dist/recyclerview/hooks/useLayoutState.js.map +1 -1
- package/dist/recyclerview/hooks/useMappingHelper.d.ts +9 -0
- package/dist/recyclerview/hooks/useMappingHelper.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useMappingHelper.js +19 -0
- package/dist/recyclerview/hooks/useMappingHelper.js.map +1 -0
- package/dist/recyclerview/hooks/useOnLoad.d.ts +2 -2
- package/dist/recyclerview/hooks/useOnLoad.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useOnLoad.js +9 -10
- package/dist/recyclerview/hooks/useOnLoad.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts +5 -49
- package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewController.js +343 -191
- package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts +2 -0
- package/dist/recyclerview/hooks/useRecyclerViewManager.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js +11 -1
- package/dist/recyclerview/hooks/useRecyclerViewManager.js.map +1 -1
- package/dist/recyclerview/hooks/useRecyclingState.d.ts +4 -2
- package/dist/recyclerview/hooks/useRecyclingState.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useRecyclingState.js +3 -4
- package/dist/recyclerview/hooks/useRecyclingState.js.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useSecondaryProps.js +15 -12
- package/dist/recyclerview/hooks/useSecondaryProps.js.map +1 -1
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts +15 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.d.ts.map +1 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js +63 -0
- package/dist/recyclerview/hooks/useUnmountAwareCallbacks.js.map +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts +0 -1
- package/dist/recyclerview/hooks/useUnmountFlag.d.ts.map +1 -1
- package/dist/recyclerview/hooks/useUnmountFlag.js +1 -0
- package/dist/recyclerview/hooks/useUnmountFlag.js.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts +18 -4
- package/dist/recyclerview/layout-managers/GridLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/GridLayoutManager.js +61 -25
- package/dist/recyclerview/layout-managers/GridLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts +36 -21
- package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LayoutManager.js +96 -28
- package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts +1 -2
- package/dist/recyclerview/layout-managers/LinearLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js +3 -3
- package/dist/recyclerview/layout-managers/LinearLayoutManager.js.map +1 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts +9 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.d.ts.map +1 -1
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js +30 -16
- package/dist/recyclerview/layout-managers/MasonryLayoutManager.js.map +1 -1
- package/dist/recyclerview/utils/adjustOffsetForRTL.js +1 -2
- package/dist/recyclerview/utils/adjustOffsetForRTL.js.map +1 -1
- package/dist/recyclerview/utils/componentUtils.d.ts +1 -1
- package/dist/recyclerview/utils/componentUtils.d.ts.map +1 -1
- package/dist/recyclerview/utils/componentUtils.js.map +1 -1
- package/dist/recyclerview/utils/findVisibleIndex.d.ts.map +1 -1
- package/dist/recyclerview/utils/findVisibleIndex.js +3 -5
- package/dist/recyclerview/utils/findVisibleIndex.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.d.ts +24 -28
- package/dist/recyclerview/utils/measureLayout.d.ts.map +1 -1
- package/dist/recyclerview/utils/measureLayout.js +36 -6
- package/dist/recyclerview/utils/measureLayout.js.map +1 -1
- package/dist/recyclerview/utils/measureLayout.web.d.ts +29 -0
- package/dist/recyclerview/utils/measureLayout.web.d.ts.map +1 -0
- package/dist/recyclerview/utils/measureLayout.web.js +87 -0
- package/dist/recyclerview/utils/measureLayout.web.js.map +1 -0
- package/dist/specs/AutoLayoutNativeComponent.d.ts +1 -2
- package/dist/specs/AutoLayoutNativeComponent.d.ts.map +1 -1
- package/dist/specs/CellContainerNativeComponent.d.ts +0 -1
- package/dist/specs/CellContainerNativeComponent.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/AverageWindow.js.map +1 -1
- package/dist/utils/ContentContainerUtils.d.ts.map +1 -1
- package/dist/utils/ContentContainerUtils.js.map +1 -1
- package/dist/viewability/ViewToken.d.ts +2 -2
- package/dist/viewability/ViewToken.d.ts.map +1 -1
- package/dist/viewability/ViewabilityHelper.js +1 -1
- package/dist/viewability/ViewabilityHelper.js.map +1 -1
- package/dist/viewability/ViewabilityManager.d.ts.map +1 -1
- package/dist/viewability/ViewabilityManager.js +11 -5
- package/dist/viewability/ViewabilityManager.js.map +1 -1
- package/jestSetup.js +30 -11
- package/package.json +4 -3
- package/src/AnimatedFlashList.ts +3 -2
- package/src/FlashList.tsx +25 -1
- package/src/FlashListProps.ts +42 -11
- package/src/FlashListRef.ts +320 -0
- package/src/MasonryFlashList.tsx +2 -2
- package/src/__tests__/ConsecutiveNumbers.test.ts +232 -0
- package/src/__tests__/GridLayoutManager.test.ts +113 -0
- package/src/__tests__/LayoutCommitObserver.test.tsx +60 -0
- package/src/__tests__/LinearLayoutManager.test.ts +227 -0
- package/src/__tests__/MasonryLayoutManager.test.ts +202 -0
- package/src/__tests__/RecyclerView.test.tsx +144 -0
- package/src/__tests__/RenderStackManager.test.ts +574 -0
- package/src/__tests__/findVisibleIndex.test.ts +369 -0
- package/src/__tests__/helpers/createLayoutManager.ts +141 -0
- package/src/__tests__/useUnmountAwareCallbacks.test.tsx +285 -0
- package/src/benchmark/useBenchmark.ts +0 -37
- package/src/benchmark/useFlatListBenchmark.ts +2 -2
- package/src/enableNewCore.ts +3 -1
- package/src/index.ts +14 -3
- package/src/native/config/PlatformHelper.android.ts +2 -0
- package/src/native/config/PlatformHelper.ios.ts +2 -0
- package/src/native/config/PlatformHelper.ts +2 -0
- package/src/native/config/PlatformHelper.web.ts +3 -1
- package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
- package/src/recyclerview/RecyclerView.tsx +178 -89
- package/src/recyclerview/RecyclerViewContextProvider.ts +53 -7
- package/src/recyclerview/RecyclerViewManager.ts +176 -97
- package/src/recyclerview/RecyclerViewProps.ts +2 -1
- package/src/recyclerview/RenderStackManager.ts +317 -0
- package/src/recyclerview/ViewHolder.tsx +13 -6
- package/src/recyclerview/ViewHolderCollection.tsx +45 -16
- package/src/recyclerview/components/ScrollAnchor.tsx +24 -11
- package/src/recyclerview/components/StickyHeaders.tsx +70 -58
- package/src/recyclerview/helpers/ConsecutiveNumbers.ts +2 -2
- package/src/recyclerview/helpers/EngagedIndicesTracker.ts +135 -25
- package/src/recyclerview/helpers/RenderTimeTracker.ts +42 -0
- package/src/recyclerview/helpers/VelocityTracker.ts +77 -0
- package/src/recyclerview/hooks/useBoundDetection.ts +74 -25
- package/src/recyclerview/hooks/useLayoutState.ts +15 -6
- package/src/recyclerview/hooks/useMappingHelper.ts +20 -0
- package/src/recyclerview/hooks/useOnLoad.ts +11 -10
- package/src/recyclerview/hooks/useRecyclerViewController.tsx +380 -241
- package/src/recyclerview/hooks/useRecyclerViewManager.ts +13 -1
- package/src/recyclerview/hooks/useRecyclingState.ts +11 -7
- package/src/recyclerview/hooks/useSecondaryProps.tsx +12 -7
- package/src/recyclerview/hooks/useUnmountAwareCallbacks.ts +73 -0
- package/src/recyclerview/hooks/useUnmountFlag.ts +1 -0
- package/src/recyclerview/layout-managers/GridLayoutManager.ts +68 -27
- package/src/recyclerview/layout-managers/LayoutManager.ts +116 -42
- package/src/recyclerview/layout-managers/LinearLayoutManager.ts +12 -8
- package/src/recyclerview/layout-managers/MasonryLayoutManager.ts +34 -13
- package/src/recyclerview/utils/componentUtils.ts +1 -1
- package/src/recyclerview/utils/findVisibleIndex.ts +1 -2
- package/src/recyclerview/utils/measureLayout.ts +41 -2
- package/src/recyclerview/utils/measureLayout.web.ts +102 -0
- package/src/viewability/ViewToken.ts +2 -2
- package/src/viewability/ViewabilityHelper.ts +1 -1
- package/src/viewability/ViewabilityManager.ts +16 -9
- package/dist/recyclerview/RecycleKeyManager.d.ts +0 -82
- package/dist/recyclerview/RecycleKeyManager.d.ts.map +0 -1
- package/dist/recyclerview/RecycleKeyManager.js +0 -135
- package/dist/recyclerview/RecycleKeyManager.js.map +0 -1
- package/src/recyclerview/RecycleKeyManager.ts +0 -185
|
@@ -13,11 +13,13 @@ import React, {
|
|
|
13
13
|
useEffect,
|
|
14
14
|
} from "react";
|
|
15
15
|
import { Animated, NativeScrollEvent } from "react-native";
|
|
16
|
+
|
|
16
17
|
import { FlashListProps } from "../..";
|
|
17
|
-
import { CompatAnimatedView } from "./CompatView";
|
|
18
18
|
import { RecyclerViewManager } from "../RecyclerViewManager";
|
|
19
19
|
import { ViewHolder } from "../ViewHolder";
|
|
20
20
|
|
|
21
|
+
import { CompatAnimatedView } from "./CompatView";
|
|
22
|
+
|
|
21
23
|
/**
|
|
22
24
|
* Props for the StickyHeaders component
|
|
23
25
|
* @template TItem - The type of items in the list
|
|
@@ -26,7 +28,7 @@ export interface StickyHeaderProps<TItem> {
|
|
|
26
28
|
/** Array of indices that should have sticky headers */
|
|
27
29
|
stickyHeaderIndices: number[];
|
|
28
30
|
/** The data array being rendered */
|
|
29
|
-
data:
|
|
31
|
+
data: ReadonlyArray<TItem>;
|
|
30
32
|
/** Animated value tracking scroll position */
|
|
31
33
|
scrollY: Animated.Value;
|
|
32
34
|
/** Function to render each item */
|
|
@@ -47,6 +49,11 @@ export interface StickyHeaderRef {
|
|
|
47
49
|
reportScrollEvent: (event: NativeScrollEvent) => void;
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
interface StickyHeaderState {
|
|
53
|
+
currentStickyIndex: number;
|
|
54
|
+
pushStartsAt: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
50
57
|
export const StickyHeaders = <TItem,>({
|
|
51
58
|
stickyHeaderIndices,
|
|
52
59
|
renderItem,
|
|
@@ -56,29 +63,35 @@ export const StickyHeaders = <TItem,>({
|
|
|
56
63
|
data,
|
|
57
64
|
extraData,
|
|
58
65
|
}: StickyHeaderProps<TItem>) => {
|
|
59
|
-
const [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
const [stickyHeaderState, setStickyHeaderState] = useState<StickyHeaderState>(
|
|
67
|
+
{
|
|
68
|
+
currentStickyIndex: -1,
|
|
69
|
+
pushStartsAt: Number.MAX_SAFE_INTEGER,
|
|
70
|
+
}
|
|
71
|
+
);
|
|
63
72
|
|
|
64
|
-
const { currentStickyIndex,
|
|
65
|
-
const hasLayout = recyclerViewManager.hasLayout();
|
|
73
|
+
const { currentStickyIndex, pushStartsAt } = stickyHeaderState;
|
|
66
74
|
|
|
67
|
-
//
|
|
75
|
+
// sort indices and memoize compute
|
|
68
76
|
const sortedIndices = useMemo(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
77
|
+
return [...stickyHeaderIndices].sort((first, second) => first - second);
|
|
78
|
+
}, [stickyHeaderIndices]);
|
|
79
|
+
|
|
80
|
+
const legthInvalid =
|
|
81
|
+
sortedIndices.length === 0 ||
|
|
82
|
+
recyclerViewManager.getDataLength() <=
|
|
83
|
+
sortedIndices[sortedIndices.length - 1];
|
|
74
84
|
|
|
75
85
|
const compute = useCallback(() => {
|
|
76
|
-
|
|
86
|
+
if (legthInvalid) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const adjustedScrollOffset = recyclerViewManager.getLastScrollOffset();
|
|
77
90
|
|
|
78
91
|
// Binary search for current sticky index
|
|
79
92
|
const currentIndexInArray = findCurrentStickyIndex(
|
|
80
93
|
sortedIndices,
|
|
81
|
-
|
|
94
|
+
adjustedScrollOffset,
|
|
82
95
|
(index) => recyclerViewManager.getLayout(index).y
|
|
83
96
|
);
|
|
84
97
|
|
|
@@ -89,16 +102,33 @@ export const StickyHeaders = <TItem,>({
|
|
|
89
102
|
newNextStickyIndex = -1;
|
|
90
103
|
}
|
|
91
104
|
|
|
105
|
+
// To make sure header offset is 0 in the interpolate compute
|
|
106
|
+
const newNextStickyY =
|
|
107
|
+
newNextStickyIndex === -1
|
|
108
|
+
? Number.MAX_SAFE_INTEGER
|
|
109
|
+
: (recyclerViewManager.tryGetLayout(newNextStickyIndex)?.y ?? 0) +
|
|
110
|
+
recyclerViewManager.firstItemOffset;
|
|
111
|
+
const newCurrentStickyHeight =
|
|
112
|
+
recyclerViewManager.tryGetLayout(newStickyIndex)?.height ?? 0;
|
|
113
|
+
|
|
114
|
+
const newPushStartsAt = newNextStickyY - newCurrentStickyHeight;
|
|
115
|
+
|
|
92
116
|
if (
|
|
93
117
|
newStickyIndex !== currentStickyIndex ||
|
|
94
|
-
|
|
118
|
+
newPushStartsAt !== pushStartsAt
|
|
95
119
|
) {
|
|
96
|
-
|
|
120
|
+
setStickyHeaderState({
|
|
97
121
|
currentStickyIndex: newStickyIndex,
|
|
98
|
-
|
|
122
|
+
pushStartsAt: newPushStartsAt,
|
|
99
123
|
});
|
|
100
124
|
}
|
|
101
|
-
}, [
|
|
125
|
+
}, [
|
|
126
|
+
legthInvalid,
|
|
127
|
+
recyclerViewManager,
|
|
128
|
+
sortedIndices,
|
|
129
|
+
currentStickyIndex,
|
|
130
|
+
pushStartsAt,
|
|
131
|
+
]);
|
|
102
132
|
|
|
103
133
|
useEffect(() => {
|
|
104
134
|
compute();
|
|
@@ -112,45 +142,24 @@ export const StickyHeaders = <TItem,>({
|
|
|
112
142
|
compute();
|
|
113
143
|
},
|
|
114
144
|
}),
|
|
115
|
-
[
|
|
116
|
-
stickyHeaderIndices,
|
|
117
|
-
recyclerViewManager,
|
|
118
|
-
currentStickyIndex,
|
|
119
|
-
nextStickyIndex,
|
|
120
|
-
]
|
|
145
|
+
[compute]
|
|
121
146
|
);
|
|
122
147
|
|
|
123
148
|
const refHolder = useRef(new Map()).current;
|
|
124
149
|
|
|
125
|
-
// Memoize translateY calculation
|
|
126
150
|
const translateY = useMemo(() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
inputRange: [0, Infinity],
|
|
130
|
-
outputRange: [0, 0],
|
|
131
|
-
extrapolate: "clamp",
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const currentLayout = recyclerViewManager.getLayout(currentStickyIndex);
|
|
136
|
-
const nextLayout = recyclerViewManager.getLayout(nextStickyIndex);
|
|
137
|
-
|
|
138
|
-
const pushStartsAt = nextLayout.y - currentLayout.height;
|
|
151
|
+
const currentStickyHeight =
|
|
152
|
+
recyclerViewManager.tryGetLayout(currentStickyIndex)?.height ?? 0;
|
|
139
153
|
|
|
140
154
|
return scrollY.interpolate({
|
|
141
|
-
inputRange: [
|
|
142
|
-
|
|
143
|
-
nextLayout.y + recyclerViewManager.firstItemOffset,
|
|
144
|
-
],
|
|
145
|
-
outputRange: [0, -currentLayout.height],
|
|
155
|
+
inputRange: [pushStartsAt, pushStartsAt + currentStickyHeight],
|
|
156
|
+
outputRange: [0, -currentStickyHeight],
|
|
146
157
|
extrapolate: "clamp",
|
|
147
158
|
});
|
|
148
|
-
}, [
|
|
159
|
+
}, [recyclerViewManager, currentStickyIndex, scrollY, pushStartsAt]);
|
|
149
160
|
|
|
150
161
|
// Memoize header content
|
|
151
162
|
const headerContent = useMemo(() => {
|
|
152
|
-
if (currentStickyIndex === -1) return null;
|
|
153
|
-
|
|
154
163
|
return (
|
|
155
164
|
<CompatAnimatedView
|
|
156
165
|
style={{
|
|
@@ -158,22 +167,25 @@ export const StickyHeaders = <TItem,>({
|
|
|
158
167
|
top: 0,
|
|
159
168
|
left: 0,
|
|
160
169
|
right: 0,
|
|
170
|
+
zIndex: 1,
|
|
161
171
|
transform: [{ translateY }],
|
|
162
172
|
}}
|
|
163
173
|
>
|
|
164
|
-
<
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
{currentStickyIndex !== -1 && currentStickyIndex < data.length ? (
|
|
175
|
+
<ViewHolder
|
|
176
|
+
index={currentStickyIndex}
|
|
177
|
+
item={data[currentStickyIndex]}
|
|
178
|
+
renderItem={renderItem}
|
|
179
|
+
layout={{ x: 0, y: 0, width: 0, height: 0 }}
|
|
180
|
+
refHolder={refHolder}
|
|
181
|
+
extraData={extraData}
|
|
182
|
+
trailingItem={null}
|
|
183
|
+
target="StickyHeader"
|
|
184
|
+
/>
|
|
185
|
+
) : null}
|
|
174
186
|
</CompatAnimatedView>
|
|
175
187
|
);
|
|
176
|
-
}, [currentStickyIndex, data, renderItem,
|
|
188
|
+
}, [translateY, currentStickyIndex, data, renderItem, refHolder, extraData]);
|
|
177
189
|
|
|
178
190
|
return headerContent;
|
|
179
191
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* A simple wrapper for consecutive integer arrays
|
|
2
|
+
* A simple wrapper for consecutive postive integer arrays
|
|
3
3
|
* Only stores start and end indices for faster computation as numbers are consecutive.
|
|
4
4
|
*/
|
|
5
5
|
export class ConsecutiveNumbers {
|
|
@@ -8,7 +8,7 @@ export class ConsecutiveNumbers {
|
|
|
8
8
|
public readonly endIndex: number
|
|
9
9
|
) {}
|
|
10
10
|
|
|
11
|
-
static readonly EMPTY = new ConsecutiveNumbers(
|
|
11
|
+
static readonly EMPTY = new ConsecutiveNumbers(-1, -2);
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Get the length of the array
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PlatformConfig } from "../../native/config/PlatformHelper";
|
|
2
2
|
import { RVLayoutManager } from "../layout-managers/LayoutManager";
|
|
3
3
|
|
|
4
|
+
import { ConsecutiveNumbers } from "./ConsecutiveNumbers";
|
|
5
|
+
|
|
4
6
|
export interface RVEngagedIndicesTracker {
|
|
5
7
|
// Current scroll offset of the list. Directly setting this won't trigger visible indices updates
|
|
6
8
|
scrollOffset: number;
|
|
7
9
|
// Total distance (in pixels) to pre-render items before and after the visible viewport
|
|
8
10
|
drawDistance: number;
|
|
11
|
+
// Whether to use offset projection to predict the next scroll offset
|
|
12
|
+
enableOffsetProjection: boolean;
|
|
13
|
+
// Average render time of the list
|
|
14
|
+
averageRenderTime: number;
|
|
9
15
|
|
|
10
16
|
/**
|
|
11
17
|
* Updates the scroll offset and calculates which items should be rendered (engaged indices).
|
|
@@ -19,8 +25,31 @@ export interface RVEngagedIndicesTracker {
|
|
|
19
25
|
velocity: Velocity | null | undefined,
|
|
20
26
|
layoutManager: RVLayoutManager
|
|
21
27
|
) => ConsecutiveNumbers | undefined;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Returns the currently engaged (rendered) indices.
|
|
31
|
+
* This includes both visible items and buffer items.
|
|
32
|
+
* @returns The last computed set of engaged indices
|
|
33
|
+
*/
|
|
22
34
|
getEngagedIndices: () => ConsecutiveNumbers;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Computes the visible indices in the viewport.
|
|
38
|
+
* @param layoutManager - Layout manager to fetch item positions and dimensions
|
|
39
|
+
* @returns Indices of items currently visible in the viewport
|
|
40
|
+
*/
|
|
23
41
|
computeVisibleIndices: (layoutManager: RVLayoutManager) => ConsecutiveNumbers;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Sets the scroll direction for velocity history tracking.
|
|
45
|
+
* @param scrollDirection - The direction of scrolling ("forward" or "backward")
|
|
46
|
+
*/
|
|
47
|
+
setScrollDirection: (scrollDirection: "forward" | "backward") => void;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resets the velocity history based on the current scroll direction.
|
|
51
|
+
*/
|
|
52
|
+
resetVelocityHistory: () => void;
|
|
24
53
|
}
|
|
25
54
|
|
|
26
55
|
export interface Velocity {
|
|
@@ -32,16 +61,26 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
32
61
|
// Current scroll position of the list
|
|
33
62
|
public scrollOffset = 0;
|
|
34
63
|
// Distance to pre-render items before and after the visible viewport (in pixels)
|
|
35
|
-
public drawDistance
|
|
64
|
+
public drawDistance = PlatformConfig.defaultDrawDistance;
|
|
65
|
+
|
|
66
|
+
// Whether to use offset projection to predict the next scroll offset
|
|
67
|
+
public enableOffsetProjection = true;
|
|
68
|
+
|
|
69
|
+
// Average render time of the list
|
|
70
|
+
public averageRenderTime = 16;
|
|
71
|
+
|
|
72
|
+
// Internal override to disable offset projection
|
|
73
|
+
private forceDisableOffsetProjection = false;
|
|
74
|
+
|
|
36
75
|
// Currently rendered item indices (including buffer items)
|
|
37
76
|
private engagedIndices = ConsecutiveNumbers.EMPTY;
|
|
38
77
|
|
|
39
78
|
// Buffer distribution multipliers for scroll direction optimization
|
|
40
|
-
private smallMultiplier = 0.
|
|
41
|
-
private largeMultiplier = 0.
|
|
79
|
+
private smallMultiplier = 0.3; // Used for buffer in the opposite direction of scroll
|
|
80
|
+
private largeMultiplier = 0.7; // Used for buffer in the direction of scroll
|
|
42
81
|
|
|
43
82
|
// Circular buffer to track recent scroll velocities for direction detection
|
|
44
|
-
private velocityHistory = [
|
|
83
|
+
private velocityHistory = [0, 0, 0, -0.1, -0.1];
|
|
45
84
|
private velocityIndex = 0;
|
|
46
85
|
|
|
47
86
|
/**
|
|
@@ -63,7 +102,21 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
63
102
|
// STEP 1: Determine the currently visible viewport
|
|
64
103
|
const windowSize = layoutManager.getWindowsSize();
|
|
65
104
|
const isHorizontal = layoutManager.isHorizontal();
|
|
66
|
-
|
|
105
|
+
|
|
106
|
+
// Update velocity history
|
|
107
|
+
if (velocity) {
|
|
108
|
+
this.updateVelocityHistory(isHorizontal ? velocity.x : velocity.y);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Determine scroll direction to optimize buffer distribution
|
|
112
|
+
const isScrollingBackward = this.isScrollingBackward();
|
|
113
|
+
const viewportStart =
|
|
114
|
+
this.enableOffsetProjection && !this.forceDisableOffsetProjection
|
|
115
|
+
? this.getProjectedScrollOffset(offset, this.averageRenderTime)
|
|
116
|
+
: offset;
|
|
117
|
+
|
|
118
|
+
// console.log("timeMs", this.averageRenderTime, offset, viewportStart);
|
|
119
|
+
|
|
67
120
|
const viewportSize = isHorizontal ? windowSize.width : windowSize.height;
|
|
68
121
|
const viewportEnd = viewportStart + viewportSize;
|
|
69
122
|
|
|
@@ -71,11 +124,6 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
71
124
|
// The total extra space where items will be pre-rendered
|
|
72
125
|
const totalBuffer = this.drawDistance * 2;
|
|
73
126
|
|
|
74
|
-
// Determine scroll direction to optimize buffer distribution
|
|
75
|
-
const isScrollingBackward = this.isScrollingBackward(
|
|
76
|
-
isHorizontal ? velocity?.x : velocity?.y
|
|
77
|
-
);
|
|
78
|
-
|
|
79
127
|
// Distribute more buffer in the direction of scrolling
|
|
80
128
|
// When scrolling forward: more buffer after viewport
|
|
81
129
|
// When scrolling backward: more buffer before viewport
|
|
@@ -86,8 +134,8 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
86
134
|
? this.smallMultiplier
|
|
87
135
|
: this.largeMultiplier;
|
|
88
136
|
|
|
89
|
-
|
|
90
|
-
|
|
137
|
+
const bufferBefore = Math.ceil(totalBuffer * beforeRatio);
|
|
138
|
+
const bufferAfter = Math.ceil(totalBuffer * afterRatio);
|
|
91
139
|
|
|
92
140
|
// STEP 3: Calculate the extended viewport (visible area + buffers)
|
|
93
141
|
// The start position with buffer (never less than 0)
|
|
@@ -119,9 +167,12 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
119
167
|
extendedStart,
|
|
120
168
|
extendedEnd
|
|
121
169
|
);
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
170
|
+
// console.log(
|
|
171
|
+
// "newEngagedIndices",
|
|
172
|
+
// newEngagedIndices,
|
|
173
|
+
// this.scrollOffset,
|
|
174
|
+
// viewportStart
|
|
175
|
+
// );
|
|
125
176
|
// Only return new indices if they've changed
|
|
126
177
|
const oldEngagedIndices = this.engagedIndices;
|
|
127
178
|
this.engagedIndices = newEngagedIndices;
|
|
@@ -131,22 +182,25 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
131
182
|
: newEngagedIndices;
|
|
132
183
|
}
|
|
133
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Updates the velocity history with a new velocity value.
|
|
187
|
+
* @param velocity - Current scroll velocity component (x or y)
|
|
188
|
+
*/
|
|
189
|
+
private updateVelocityHistory(velocity: number) {
|
|
190
|
+
this.velocityHistory[this.velocityIndex] = velocity;
|
|
191
|
+
this.velocityIndex = (this.velocityIndex + 1) % this.velocityHistory.length;
|
|
192
|
+
}
|
|
193
|
+
|
|
134
194
|
/**
|
|
135
195
|
* Determines scroll direction by analyzing recent velocity history.
|
|
136
196
|
* Uses a majority voting system on the last 5 velocity values.
|
|
137
|
-
* @param velocity - Current scroll velocity component (x or y)
|
|
138
197
|
* @returns true if scrolling backward (negative direction), false otherwise
|
|
139
198
|
*/
|
|
140
|
-
private isScrollingBackward(
|
|
141
|
-
//
|
|
142
|
-
if (velocity) {
|
|
143
|
-
this.velocityHistory[this.velocityIndex] = velocity;
|
|
144
|
-
this.velocityIndex =
|
|
145
|
-
(this.velocityIndex + 1) % this.velocityHistory.length;
|
|
146
|
-
}
|
|
147
|
-
//should decide based on whether we have more positive or negative values, use for loop
|
|
199
|
+
private isScrollingBackward(): boolean {
|
|
200
|
+
// should decide based on whether we have more positive or negative values, use for loop
|
|
148
201
|
let positiveCount = 0;
|
|
149
202
|
let negativeCount = 0;
|
|
203
|
+
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
|
150
204
|
for (let i = 0; i < this.velocityHistory.length; i++) {
|
|
151
205
|
if (this.velocityHistory[i] > 0) {
|
|
152
206
|
positiveCount++;
|
|
@@ -157,6 +211,40 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
157
211
|
return positiveCount < negativeCount;
|
|
158
212
|
}
|
|
159
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Calculates the median velocity based on velocity history
|
|
216
|
+
* Medina works better agains outliers
|
|
217
|
+
* @returns Median velocity over the recent history
|
|
218
|
+
*/
|
|
219
|
+
private getMedianVelocity(): number {
|
|
220
|
+
// Make a copy of velocity history and sort it
|
|
221
|
+
const sortedVelocities = [...this.velocityHistory].sort(
|
|
222
|
+
(valueA, valueB) => valueA - valueB
|
|
223
|
+
);
|
|
224
|
+
const length = sortedVelocities.length;
|
|
225
|
+
|
|
226
|
+
// If length is odd, return the middle element
|
|
227
|
+
if (length % 2 === 1) {
|
|
228
|
+
return sortedVelocities[Math.floor(length / 2)];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// If length is even, return the average of the two middle elements
|
|
232
|
+
const midIndex = length / 2;
|
|
233
|
+
return (sortedVelocities[midIndex - 1] + sortedVelocities[midIndex]) / 2;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Projects the next scroll offset based on median velocity
|
|
238
|
+
* @param timeMs Time in milliseconds to predict ahead
|
|
239
|
+
* @returns Projected scroll offset
|
|
240
|
+
*/
|
|
241
|
+
private getProjectedScrollOffset(offset: number, timeMs: number): number {
|
|
242
|
+
const medianVelocity = this.getMedianVelocity();
|
|
243
|
+
// Convert time from ms to seconds for velocity calculation
|
|
244
|
+
// Predict next position: current position + (velocity * time)
|
|
245
|
+
return offset + medianVelocity * timeMs;
|
|
246
|
+
}
|
|
247
|
+
|
|
160
248
|
/**
|
|
161
249
|
* Calculates which items are currently visible in the viewport.
|
|
162
250
|
* Unlike getEngagedIndices, this doesn't include buffer items.
|
|
@@ -188,4 +276,26 @@ export class RVEngagedIndicesTrackerImpl implements RVEngagedIndicesTracker {
|
|
|
188
276
|
getEngagedIndices(): ConsecutiveNumbers {
|
|
189
277
|
return this.engagedIndices;
|
|
190
278
|
}
|
|
279
|
+
|
|
280
|
+
setScrollDirection(scrollDirection: "forward" | "backward") {
|
|
281
|
+
if (scrollDirection === "forward") {
|
|
282
|
+
this.velocityHistory = [0, 0, 0, 0.1, 0.1];
|
|
283
|
+
this.velocityIndex = 0;
|
|
284
|
+
} else {
|
|
285
|
+
this.velocityHistory = [0, 0, 0, -0.1, -0.1];
|
|
286
|
+
this.velocityIndex = 0;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Resets the velocity history based on the current scroll direction.
|
|
292
|
+
* This ensures that the velocity history is always in sync with the current scroll direction.
|
|
293
|
+
*/
|
|
294
|
+
resetVelocityHistory() {
|
|
295
|
+
if (this.isScrollingBackward()) {
|
|
296
|
+
this.setScrollDirection("backward");
|
|
297
|
+
} else {
|
|
298
|
+
this.setScrollDirection("forward");
|
|
299
|
+
}
|
|
300
|
+
}
|
|
191
301
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { PlatformConfig } from "../../native/config/PlatformHelper";
|
|
2
|
+
import { AverageWindow } from "../../utils/AverageWindow";
|
|
3
|
+
|
|
4
|
+
export class RenderTimeTracker {
|
|
5
|
+
private renderTimeAvgWindow = new AverageWindow(5);
|
|
6
|
+
private lastTimerStartedAt = -1;
|
|
7
|
+
private maxRenderTime = 32; // TODO: Improve this even more
|
|
8
|
+
private defaultRenderTime = 16;
|
|
9
|
+
|
|
10
|
+
startTracking() {
|
|
11
|
+
if (!PlatformConfig.trackAverageRenderTimeForOffsetProjection) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (this.lastTimerStartedAt === -1) {
|
|
15
|
+
this.lastTimerStartedAt = Date.now();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
markRenderComplete() {
|
|
20
|
+
if (!PlatformConfig.trackAverageRenderTimeForOffsetProjection) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (this.lastTimerStartedAt !== -1) {
|
|
24
|
+
this.renderTimeAvgWindow.addValue(Date.now() - this.lastTimerStartedAt);
|
|
25
|
+
this.lastTimerStartedAt = -1;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getRawValue() {
|
|
30
|
+
return this.renderTimeAvgWindow.currentValue;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getAverageRenderTime() {
|
|
34
|
+
if (!PlatformConfig.trackAverageRenderTimeForOffsetProjection) {
|
|
35
|
+
return this.defaultRenderTime;
|
|
36
|
+
}
|
|
37
|
+
return Math.min(
|
|
38
|
+
this.maxRenderTime,
|
|
39
|
+
Math.max(Math.round(this.renderTimeAvgWindow.currentValue), 16)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks and calculates velocity for scroll/drag movements
|
|
3
|
+
* Used to determine momentum scrolling behavior
|
|
4
|
+
*/
|
|
5
|
+
export class VelocityTracker<T> {
|
|
6
|
+
/** Timestamp of the last velocity update */
|
|
7
|
+
private lastUpdateTime = Date.now();
|
|
8
|
+
/** Current velocity vector with x and y components */
|
|
9
|
+
private velocity = { x: 0, y: 0 };
|
|
10
|
+
|
|
11
|
+
/** Reference to the momentum end timeout */
|
|
12
|
+
private timeoutId: NodeJS.Timeout | null = null;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Calculates velocity based on position change over time
|
|
16
|
+
* @param newOffset Current position value
|
|
17
|
+
* @param oldOffset Previous position value
|
|
18
|
+
* @param isHorizontal Whether movement is horizontal (true) or vertical (false)
|
|
19
|
+
* @param isRTL Whether layout direction is right-to-left
|
|
20
|
+
* @param callback Function to call with velocity updates and momentum end signal
|
|
21
|
+
*/
|
|
22
|
+
computeVelocity(
|
|
23
|
+
newOffset: number,
|
|
24
|
+
oldOffset: number,
|
|
25
|
+
isHorizontal: boolean,
|
|
26
|
+
callback: (
|
|
27
|
+
velocity: { x: number; y: number },
|
|
28
|
+
isMomentumEnd: boolean
|
|
29
|
+
) => void
|
|
30
|
+
) {
|
|
31
|
+
// Clear any pending momentum end timeout
|
|
32
|
+
this.cleanUp();
|
|
33
|
+
// Calculate time since last update
|
|
34
|
+
const currentTime = Date.now();
|
|
35
|
+
const timeSinceLastUpdate = Math.max(1, currentTime - this.lastUpdateTime);
|
|
36
|
+
|
|
37
|
+
// Calculate velocity as distance/time
|
|
38
|
+
const newVelocity = (newOffset - oldOffset) / timeSinceLastUpdate;
|
|
39
|
+
|
|
40
|
+
// console.log(
|
|
41
|
+
// "newVelocity",
|
|
42
|
+
// newOffset,
|
|
43
|
+
// oldOffset,
|
|
44
|
+
// currentTime,
|
|
45
|
+
// this.lastUpdateTime,
|
|
46
|
+
// timeSinceLastUpdate,
|
|
47
|
+
// newVelocity
|
|
48
|
+
// );
|
|
49
|
+
this.lastUpdateTime = currentTime;
|
|
50
|
+
|
|
51
|
+
// Apply velocity to the correct axis
|
|
52
|
+
this.velocity.x = isHorizontal ? newVelocity : 0;
|
|
53
|
+
this.velocity.y = isHorizontal ? 0 : newVelocity;
|
|
54
|
+
|
|
55
|
+
// Trigger callback with current velocity
|
|
56
|
+
callback(this.velocity, false);
|
|
57
|
+
|
|
58
|
+
// Set timeout to signal momentum end after 100ms of no updates
|
|
59
|
+
this.timeoutId = setTimeout(() => {
|
|
60
|
+
this.cleanUp();
|
|
61
|
+
this.lastUpdateTime = Date.now();
|
|
62
|
+
this.velocity.x = 0;
|
|
63
|
+
this.velocity.y = 0;
|
|
64
|
+
callback(this.velocity, true);
|
|
65
|
+
}, 100);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Cleans up resources by clearing any pending timeout
|
|
70
|
+
*/
|
|
71
|
+
cleanUp() {
|
|
72
|
+
if (this.timeoutId !== null) {
|
|
73
|
+
clearTimeout(this.timeoutId);
|
|
74
|
+
this.timeoutId = null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|