@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.
Files changed (304) hide show
  1. package/README.md +27 -97
  2. package/dist/AnimatedFlashList.js +2 -2
  3. package/dist/AnimatedFlashList.js.map +1 -1
  4. package/dist/FlashList.d.ts +1 -167
  5. package/dist/FlashList.d.ts.map +1 -1
  6. package/dist/FlashList.js +3 -595
  7. package/dist/FlashList.js.map +1 -1
  8. package/dist/FlashListProps.d.ts +7 -63
  9. package/dist/FlashListProps.d.ts.map +1 -1
  10. package/dist/FlashListProps.js.map +1 -1
  11. package/dist/__tests__/LayoutCommitObserver.test.d.ts +2 -0
  12. package/dist/__tests__/LayoutCommitObserver.test.d.ts.map +1 -0
  13. package/dist/__tests__/LayoutCommitObserver.test.js +35 -0
  14. package/dist/__tests__/LayoutCommitObserver.test.js.map +1 -0
  15. package/dist/__tests__/ViewabilityHelper.test.js +3 -4
  16. package/dist/__tests__/ViewabilityHelper.test.js.map +1 -1
  17. package/dist/benchmark/JSFPSMonitor.d.ts.map +1 -1
  18. package/dist/benchmark/JSFPSMonitor.js +2 -1
  19. package/dist/benchmark/JSFPSMonitor.js.map +1 -1
  20. package/dist/benchmark/useBenchmark.d.ts +2 -4
  21. package/dist/benchmark/useBenchmark.d.ts.map +1 -1
  22. package/dist/benchmark/useBenchmark.js +12 -49
  23. package/dist/benchmark/useBenchmark.js.map +1 -1
  24. package/dist/benchmark/useFlatListBenchmark.d.ts.map +1 -1
  25. package/dist/benchmark/useFlatListBenchmark.js +2 -1
  26. package/dist/benchmark/useFlatListBenchmark.js.map +1 -1
  27. package/dist/errors/ErrorMessages.d.ts +16 -0
  28. package/dist/errors/ErrorMessages.d.ts.map +1 -0
  29. package/dist/errors/ErrorMessages.js +19 -0
  30. package/dist/errors/ErrorMessages.js.map +1 -0
  31. package/dist/errors/WarningMessages.d.ts +4 -0
  32. package/dist/errors/WarningMessages.d.ts.map +1 -0
  33. package/dist/errors/WarningMessages.js +7 -0
  34. package/dist/errors/WarningMessages.js.map +1 -0
  35. package/dist/index.d.ts +4 -9
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +9 -29
  38. package/dist/index.js.map +1 -1
  39. package/dist/isNewArch.d.ts +2 -0
  40. package/dist/isNewArch.d.ts.map +1 -0
  41. package/dist/isNewArch.js +25 -0
  42. package/dist/isNewArch.js.map +1 -0
  43. package/dist/native/config/PlatformHelper.android.d.ts +1 -22
  44. package/dist/native/config/PlatformHelper.android.d.ts.map +1 -1
  45. package/dist/native/config/PlatformHelper.android.js +1 -16
  46. package/dist/native/config/PlatformHelper.android.js.map +1 -1
  47. package/dist/native/config/PlatformHelper.d.ts +1 -22
  48. package/dist/native/config/PlatformHelper.d.ts.map +1 -1
  49. package/dist/native/config/PlatformHelper.ios.d.ts +1 -22
  50. package/dist/native/config/PlatformHelper.ios.d.ts.map +1 -1
  51. package/dist/native/config/PlatformHelper.ios.js +1 -15
  52. package/dist/native/config/PlatformHelper.ios.js.map +1 -1
  53. package/dist/native/config/PlatformHelper.js +1 -16
  54. package/dist/native/config/PlatformHelper.js.map +1 -1
  55. package/dist/native/config/PlatformHelper.web.d.ts +1 -23
  56. package/dist/native/config/PlatformHelper.web.d.ts.map +1 -1
  57. package/dist/native/config/PlatformHelper.web.js +1 -18
  58. package/dist/native/config/PlatformHelper.web.js.map +1 -1
  59. package/dist/recyclerview/LayoutCommitObserver.d.ts +12 -0
  60. package/dist/recyclerview/LayoutCommitObserver.d.ts.map +1 -0
  61. package/dist/recyclerview/LayoutCommitObserver.js +62 -0
  62. package/dist/recyclerview/LayoutCommitObserver.js.map +1 -0
  63. package/dist/recyclerview/RecyclerView.d.ts.map +1 -1
  64. package/dist/recyclerview/RecyclerView.js +20 -9
  65. package/dist/recyclerview/RecyclerView.js.map +1 -1
  66. package/dist/recyclerview/RecyclerViewManager.d.ts +4 -1
  67. package/dist/recyclerview/RecyclerViewManager.d.ts.map +1 -1
  68. package/dist/recyclerview/RecyclerViewManager.js +43 -34
  69. package/dist/recyclerview/RecyclerViewManager.js.map +1 -1
  70. package/dist/recyclerview/RecyclerViewProps.d.ts +1 -8
  71. package/dist/recyclerview/RecyclerViewProps.d.ts.map +1 -1
  72. package/dist/recyclerview/ViewHolderCollection.d.ts +6 -2
  73. package/dist/recyclerview/ViewHolderCollection.d.ts.map +1 -1
  74. package/dist/recyclerview/ViewHolderCollection.js +3 -1
  75. package/dist/recyclerview/ViewHolderCollection.js.map +1 -1
  76. package/dist/recyclerview/hooks/useBoundDetection.d.ts.map +1 -1
  77. package/dist/recyclerview/hooks/useBoundDetection.js +38 -7
  78. package/dist/recyclerview/hooks/useBoundDetection.js.map +1 -1
  79. package/dist/recyclerview/hooks/useRecyclerViewController.d.ts.map +1 -1
  80. package/dist/recyclerview/hooks/useRecyclerViewController.js +16 -9
  81. package/dist/recyclerview/hooks/useRecyclerViewController.js.map +1 -1
  82. package/dist/recyclerview/layout-managers/LayoutManager.d.ts.map +1 -1
  83. package/dist/recyclerview/layout-managers/LayoutManager.js +2 -1
  84. package/dist/recyclerview/layout-managers/LayoutManager.js.map +1 -1
  85. package/dist/recyclerview/viewability/ViewToken.d.ts.map +1 -0
  86. package/dist/recyclerview/viewability/ViewToken.js.map +1 -0
  87. package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.d.ts +2 -2
  88. package/dist/recyclerview/viewability/ViewabilityHelper.d.ts.map +1 -0
  89. package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.js +2 -4
  90. package/dist/{viewability → recyclerview/viewability}/ViewabilityHelper.js.map +1 -1
  91. package/dist/{viewability → recyclerview/viewability}/ViewabilityManager.d.ts +3 -3
  92. package/dist/recyclerview/viewability/ViewabilityManager.d.ts.map +1 -0
  93. package/dist/{viewability → recyclerview/viewability}/ViewabilityManager.js +16 -16
  94. package/dist/recyclerview/viewability/ViewabilityManager.js.map +1 -0
  95. package/dist/tsconfig.tsbuildinfo +1 -1
  96. package/package.json +3 -14
  97. package/src/AnimatedFlashList.ts +2 -2
  98. package/src/FlashList.ts +1 -0
  99. package/src/FlashListProps.ts +8 -79
  100. package/src/__tests__/LayoutCommitObserver.test.tsx +60 -0
  101. package/src/__tests__/ViewabilityHelper.test.ts +13 -14
  102. package/src/benchmark/JSFPSMonitor.ts +3 -3
  103. package/src/benchmark/useBenchmark.ts +12 -77
  104. package/src/benchmark/useFlatListBenchmark.ts +3 -1
  105. package/src/errors/ErrorMessages.ts +26 -0
  106. package/src/errors/WarningMessages.ts +4 -0
  107. package/src/index.ts +11 -43
  108. package/src/isNewArch.ts +25 -0
  109. package/src/native/config/PlatformHelper.android.ts +1 -25
  110. package/src/native/config/PlatformHelper.ios.ts +1 -24
  111. package/src/native/config/PlatformHelper.ts +1 -25
  112. package/src/native/config/PlatformHelper.web.ts +1 -30
  113. package/src/recyclerview/LayoutCommitObserver.tsx +74 -0
  114. package/src/recyclerview/RecyclerView.tsx +25 -12
  115. package/src/recyclerview/RecyclerViewManager.ts +40 -40
  116. package/src/recyclerview/RecyclerViewProps.ts +1 -11
  117. package/src/recyclerview/ViewHolderCollection.tsx +9 -2
  118. package/src/recyclerview/hooks/useBoundDetection.ts +48 -6
  119. package/src/recyclerview/hooks/useRecyclerViewController.tsx +19 -14
  120. package/src/recyclerview/layout-managers/LayoutManager.ts +2 -1
  121. package/src/{viewability → recyclerview/viewability}/ViewabilityHelper.ts +8 -9
  122. package/src/{viewability → recyclerview/viewability}/ViewabilityManager.ts +18 -20
  123. package/RNFlashList.podspec +0 -37
  124. package/android/build.gradle +0 -89
  125. package/android/src/main/AndroidManifest.xml +0 -3
  126. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutShadow.kt +0 -105
  127. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutView.kt +0 -158
  128. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/AutoLayoutViewManager.kt +0 -70
  129. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/BlankAreaEvent.kt +0 -29
  130. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainer.java +0 -16
  131. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerImpl.kt +0 -16
  132. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/CellContainerManager.kt +0 -34
  133. package/android/src/main/kotlin/com/shopify/reactnative/flash_list/FlashListPackage.kt +0 -19
  134. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerDelegate.java +0 -47
  135. package/android/src/paper/java/com/facebook/react/viewmanagers/AutoLayoutViewManagerInterface.java +0 -21
  136. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerDelegate.java +0 -32
  137. package/android/src/paper/java/com/facebook/react/viewmanagers/CellContainerManagerInterface.java +0 -16
  138. package/android/src/test/java/com/shopify/reactnative/flash_list/AutoLayoutShadowTest.kt +0 -147
  139. package/android/src/test/java/com/shopify/reactnative/flash_list/models/Rect.kt +0 -61
  140. package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestCollection.kt +0 -6
  141. package/android/src/test/java/com/shopify/reactnative/flash_list/models/TestDataModel.kt +0 -8
  142. package/android/src/test/resources/LayoutTestData.json +0 -788
  143. package/dist/GridLayoutProviderWithProps.d.ts +0 -42
  144. package/dist/GridLayoutProviderWithProps.d.ts.map +0 -1
  145. package/dist/GridLayoutProviderWithProps.js +0 -114
  146. package/dist/GridLayoutProviderWithProps.js.map +0 -1
  147. package/dist/MasonryFlashList.d.ts +0 -51
  148. package/dist/MasonryFlashList.d.ts.map +0 -1
  149. package/dist/MasonryFlashList.js +0 -252
  150. package/dist/MasonryFlashList.js.map +0 -1
  151. package/dist/PureComponentWrapper.d.ts +0 -22
  152. package/dist/PureComponentWrapper.d.ts.map +0 -1
  153. package/dist/PureComponentWrapper.js +0 -37
  154. package/dist/PureComponentWrapper.js.map +0 -1
  155. package/dist/__tests__/ContentContainerUtils.test.d.ts +0 -2
  156. package/dist/__tests__/ContentContainerUtils.test.d.ts.map +0 -1
  157. package/dist/__tests__/ContentContainerUtils.test.js +0 -85
  158. package/dist/__tests__/ContentContainerUtils.test.js.map +0 -1
  159. package/dist/__tests__/FlashList.test.d.ts +0 -2
  160. package/dist/__tests__/FlashList.test.d.ts.map +0 -1
  161. package/dist/__tests__/FlashList.test.js +0 -902
  162. package/dist/__tests__/FlashList.test.js.map +0 -1
  163. package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts +0 -2
  164. package/dist/__tests__/GridLayoutProviderWithProps.test.d.ts.map +0 -1
  165. package/dist/__tests__/GridLayoutProviderWithProps.test.js +0 -143
  166. package/dist/__tests__/GridLayoutProviderWithProps.test.js.map +0 -1
  167. package/dist/__tests__/MasonryFlashList.test.d.ts +0 -2
  168. package/dist/__tests__/MasonryFlashList.test.d.ts.map +0 -1
  169. package/dist/__tests__/MasonryFlashList.test.js +0 -254
  170. package/dist/__tests__/MasonryFlashList.test.js.map +0 -1
  171. package/dist/__tests__/PlatformHelper.web.test.d.ts +0 -2
  172. package/dist/__tests__/PlatformHelper.web.test.d.ts.map +0 -1
  173. package/dist/__tests__/PlatformHelper.web.test.js +0 -33
  174. package/dist/__tests__/PlatformHelper.web.test.js.map +0 -1
  175. package/dist/__tests__/helpers/mountFlashList.d.ts +0 -19
  176. package/dist/__tests__/helpers/mountFlashList.d.ts.map +0 -1
  177. package/dist/__tests__/helpers/mountFlashList.js +0 -44
  178. package/dist/__tests__/helpers/mountFlashList.js.map +0 -1
  179. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts +0 -18
  180. package/dist/__tests__/helpers/mountMasonryFlashList.d.ts.map +0 -1
  181. package/dist/__tests__/helpers/mountMasonryFlashList.js +0 -49
  182. package/dist/__tests__/helpers/mountMasonryFlashList.js.map +0 -1
  183. package/dist/__tests__/useBlankAreaTracker.test.d.ts +0 -2
  184. package/dist/__tests__/useBlankAreaTracker.test.d.ts.map +0 -1
  185. package/dist/__tests__/useBlankAreaTracker.test.js +0 -179
  186. package/dist/__tests__/useBlankAreaTracker.test.js.map +0 -1
  187. package/dist/benchmark/useBlankAreaTracker.d.ts +0 -34
  188. package/dist/benchmark/useBlankAreaTracker.d.ts.map +0 -1
  189. package/dist/benchmark/useBlankAreaTracker.js +0 -66
  190. package/dist/benchmark/useBlankAreaTracker.js.map +0 -1
  191. package/dist/enableNewCore.d.ts +0 -3
  192. package/dist/enableNewCore.d.ts.map +0 -1
  193. package/dist/enableNewCore.js +0 -25
  194. package/dist/enableNewCore.js.map +0 -1
  195. package/dist/errors/CustomError.d.ts +0 -8
  196. package/dist/errors/CustomError.d.ts.map +0 -1
  197. package/dist/errors/CustomError.js +0 -14
  198. package/dist/errors/CustomError.js.map +0 -1
  199. package/dist/errors/ExceptionList.d.ts +0 -24
  200. package/dist/errors/ExceptionList.d.ts.map +0 -1
  201. package/dist/errors/ExceptionList.js +0 -26
  202. package/dist/errors/ExceptionList.js.map +0 -1
  203. package/dist/errors/Warnings.d.ts +0 -9
  204. package/dist/errors/Warnings.d.ts.map +0 -1
  205. package/dist/errors/Warnings.js +0 -13
  206. package/dist/errors/Warnings.js.map +0 -1
  207. package/dist/native/auto-layout/AutoLayoutView.d.ts +0 -22
  208. package/dist/native/auto-layout/AutoLayoutView.d.ts.map +0 -1
  209. package/dist/native/auto-layout/AutoLayoutView.js +0 -48
  210. package/dist/native/auto-layout/AutoLayoutView.js.map +0 -1
  211. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts +0 -4
  212. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.d.ts.map +0 -1
  213. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js +0 -6
  214. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.android.js.map +0 -1
  215. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts +0 -5
  216. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.d.ts.map +0 -1
  217. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts +0 -4
  218. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.d.ts.map +0 -1
  219. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js +0 -6
  220. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.ios.js.map +0 -1
  221. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js +0 -6
  222. package/dist/native/auto-layout/AutoLayoutViewNativeComponent.js.map +0 -1
  223. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts +0 -16
  224. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.d.ts.map +0 -1
  225. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js +0 -3
  226. package/dist/native/auto-layout/AutoLayoutViewNativeComponentProps.js.map +0 -1
  227. package/dist/native/cell-container/CellContainer.android.d.ts +0 -6
  228. package/dist/native/cell-container/CellContainer.android.d.ts.map +0 -1
  229. package/dist/native/cell-container/CellContainer.android.js +0 -9
  230. package/dist/native/cell-container/CellContainer.android.js.map +0 -1
  231. package/dist/native/cell-container/CellContainer.d.ts +0 -8
  232. package/dist/native/cell-container/CellContainer.d.ts.map +0 -1
  233. package/dist/native/cell-container/CellContainer.ios.d.ts +0 -6
  234. package/dist/native/cell-container/CellContainer.ios.d.ts.map +0 -1
  235. package/dist/native/cell-container/CellContainer.ios.js +0 -9
  236. package/dist/native/cell-container/CellContainer.ios.js.map +0 -1
  237. package/dist/native/cell-container/CellContainer.js +0 -11
  238. package/dist/native/cell-container/CellContainer.js.map +0 -1
  239. package/dist/native/cell-container/CellContainer.web.d.ts +0 -7
  240. package/dist/native/cell-container/CellContainer.web.d.ts.map +0 -1
  241. package/dist/native/cell-container/CellContainer.web.js +0 -13
  242. package/dist/native/cell-container/CellContainer.web.js.map +0 -1
  243. package/dist/specs/AutoLayoutNativeComponent.d.ts +0 -18
  244. package/dist/specs/AutoLayoutNativeComponent.d.ts.map +0 -1
  245. package/dist/specs/AutoLayoutNativeComponent.js +0 -6
  246. package/dist/specs/AutoLayoutNativeComponent.js.map +0 -1
  247. package/dist/specs/CellContainerNativeComponent.d.ts +0 -8
  248. package/dist/specs/CellContainerNativeComponent.d.ts.map +0 -1
  249. package/dist/specs/CellContainerNativeComponent.js +0 -6
  250. package/dist/specs/CellContainerNativeComponent.js.map +0 -1
  251. package/dist/utils/ContentContainerUtils.d.ts +0 -27
  252. package/dist/utils/ContentContainerUtils.d.ts.map +0 -1
  253. package/dist/utils/ContentContainerUtils.js +0 -48
  254. package/dist/utils/ContentContainerUtils.js.map +0 -1
  255. package/dist/viewability/ViewToken.d.ts.map +0 -1
  256. package/dist/viewability/ViewToken.js.map +0 -1
  257. package/dist/viewability/ViewabilityHelper.d.ts.map +0 -1
  258. package/dist/viewability/ViewabilityManager.d.ts.map +0 -1
  259. package/dist/viewability/ViewabilityManager.js.map +0 -1
  260. package/ios/RNFlashList.xcodeproj/project.pbxproj +0 -3
  261. package/ios/RNFlashList.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -4
  262. package/ios/Sources/AutoLayoutView.swift +0 -294
  263. package/ios/Sources/AutoLayoutViewComponentView.h +0 -16
  264. package/ios/Sources/AutoLayoutViewComponentView.mm +0 -90
  265. package/ios/Sources/AutoLayoutViewManager.mm +0 -14
  266. package/ios/Sources/AutoLayoutViewManager.swift +0 -12
  267. package/ios/Sources/CellContainerComponentView.h +0 -18
  268. package/ios/Sources/CellContainerComponentView.mm +0 -62
  269. package/ios/Sources/CellContainerManager.mm +0 -8
  270. package/ios/Sources/CellContainerManager.swift +0 -12
  271. package/ios/Sources/FlatListPro-Bridging-Header.h +0 -11
  272. package/ios/Tests/AutoLayoutViewTests.swift +0 -113
  273. package/src/FlashList.tsx +0 -953
  274. package/src/GridLayoutProviderWithProps.ts +0 -180
  275. package/src/MasonryFlashList.tsx +0 -476
  276. package/src/PureComponentWrapper.tsx +0 -42
  277. package/src/__tests__/ContentContainerUtils.test.ts +0 -130
  278. package/src/__tests__/FlashList.test.tsx +0 -1001
  279. package/src/__tests__/GridLayoutProviderWithProps.test.ts +0 -179
  280. package/src/__tests__/MasonryFlashList.test.ts +0 -292
  281. package/src/__tests__/PlatformHelper.web.test.ts +0 -45
  282. package/src/__tests__/helpers/mountFlashList.tsx +0 -62
  283. package/src/__tests__/helpers/mountMasonryFlashList.tsx +0 -70
  284. package/src/__tests__/useBlankAreaTracker.test.tsx +0 -206
  285. package/src/benchmark/useBlankAreaTracker.ts +0 -117
  286. package/src/enableNewCore.ts +0 -24
  287. package/src/errors/CustomError.ts +0 -10
  288. package/src/errors/ExceptionList.ts +0 -28
  289. package/src/errors/Warnings.ts +0 -15
  290. package/src/native/auto-layout/AutoLayoutView.tsx +0 -73
  291. package/src/native/auto-layout/AutoLayoutViewNativeComponent.android.ts +0 -7
  292. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ios.ts +0 -7
  293. package/src/native/auto-layout/AutoLayoutViewNativeComponent.ts +0 -7
  294. package/src/native/auto-layout/AutoLayoutViewNativeComponentProps.ts +0 -17
  295. package/src/native/cell-container/CellContainer.android.ts +0 -7
  296. package/src/native/cell-container/CellContainer.ios.ts +0 -7
  297. package/src/native/cell-container/CellContainer.tsx +0 -14
  298. package/src/native/cell-container/CellContainer.web.tsx +0 -9
  299. package/src/specs/AutoLayoutNativeComponent.ts +0 -24
  300. package/src/specs/CellContainerNativeComponent.ts +0 -9
  301. package/src/utils/ContentContainerUtils.ts +0 -92
  302. /package/dist/{viewability → recyclerview/viewability}/ViewToken.d.ts +0 -0
  303. /package/dist/{viewability → recyclerview/viewability}/ViewToken.js +0 -0
  304. /package/src/{viewability → recyclerview/viewability}/ViewToken.ts +0 -0
@@ -21,6 +21,7 @@ import { adjustOffsetForRTL } from "../utils/adjustOffsetForRTL";
21
21
  import { RVLayout } from "../layout-managers/LayoutManager";
22
22
  import { ScrollAnchorRef } from "../components/ScrollAnchor";
23
23
  import { PlatformConfig } from "../../native/config/PlatformHelper";
24
+ import { WarningMessages } from "../../errors/WarningMessages";
24
25
 
25
26
  import { useUnmountFlag } from "./useUnmountFlag";
26
27
  import { useUnmountAwareTimeout } from "./useUnmountAwareCallbacks";
@@ -90,10 +91,9 @@ export function useRecyclerViewController<T>(
90
91
  );
91
92
 
92
93
  const computeFirstVisibleIndexForOffsetCorrection = useCallback(() => {
93
- const { data, keyExtractor } = recyclerViewManager.props;
94
94
  if (
95
95
  recyclerViewManager.getIsFirstLayoutComplete() &&
96
- keyExtractor &&
96
+ recyclerViewManager.hasStableDataKeys() &&
97
97
  recyclerViewManager.getDataLength() > 0 &&
98
98
  recyclerViewManager.shouldMaintainVisibleContentPosition()
99
99
  ) {
@@ -103,10 +103,8 @@ export function useRecyclerViewController<T>(
103
103
  recyclerViewManager.computeVisibleIndices().startIndex
104
104
  );
105
105
  if (firstVisibleIndex !== undefined && firstVisibleIndex >= 0) {
106
- firstVisibleItemKey.current = keyExtractor(
107
- data![firstVisibleIndex],
108
- firstVisibleIndex
109
- );
106
+ firstVisibleItemKey.current =
107
+ recyclerViewManager.getDataKey(firstVisibleIndex);
110
108
  firstVisibleItemLayout.current = {
111
109
  ...recyclerViewManager.getLayout(firstVisibleIndex),
112
110
  };
@@ -120,7 +118,7 @@ export function useRecyclerViewController<T>(
120
118
  * the user's current view position when new messages are added.
121
119
  */
122
120
  const applyOffsetCorrection = useCallback(() => {
123
- const { horizontal, data, keyExtractor } = recyclerViewManager.props;
121
+ const { horizontal, data } = recyclerViewManager.props;
124
122
 
125
123
  // Execute all pending callbacks from previous scroll offset updates
126
124
  // This ensures any scroll operations that were waiting for render are completed
@@ -132,7 +130,7 @@ export function useRecyclerViewController<T>(
132
130
 
133
131
  if (
134
132
  recyclerViewManager.getIsFirstLayoutComplete() &&
135
- keyExtractor &&
133
+ recyclerViewManager.hasStableDataKeys() &&
136
134
  currentDataLength > 0 &&
137
135
  recyclerViewManager.shouldMaintainVisibleContentPosition()
138
136
  ) {
@@ -144,13 +142,14 @@ export function useRecyclerViewController<T>(
144
142
  .getEngagedIndices()
145
143
  .findValue(
146
144
  (index) =>
147
- keyExtractor?.(data![index], index) ===
145
+ recyclerViewManager.getDataKey(index) ===
148
146
  firstVisibleItemKey.current
149
147
  ) ??
150
148
  (hasDataChanged
151
149
  ? data?.findIndex(
152
150
  (item, index) =>
153
- keyExtractor?.(item, index) === firstVisibleItemKey.current
151
+ recyclerViewManager.getDataKey(index) ===
152
+ firstVisibleItemKey.current
154
153
  )
155
154
  : undefined);
156
155
 
@@ -281,10 +280,13 @@ export function useRecyclerViewController<T>(
281
280
  scrollToEnd: async ({ animated }: ScrollToEdgeParams = {}) => {
282
281
  const { data } = recyclerViewManager.props;
283
282
  if (data && data.length > 0) {
284
- await handlerMethods.scrollToIndex({
285
- index: data.length - 1,
286
- animated,
287
- });
283
+ const lastIndex = data.length - 1;
284
+ if (!recyclerViewManager.getEngagedIndices().includes(lastIndex)) {
285
+ await handlerMethods.scrollToIndex({
286
+ index: lastIndex,
287
+ animated,
288
+ });
289
+ }
288
290
  }
289
291
  setTimeout(() => {
290
292
  scrollViewRef.current!.scrollToEnd({ animated });
@@ -547,6 +549,9 @@ export function useRecyclerViewController<T>(
547
549
  * Disables item recycling in preparation for layout animations.
548
550
  */
549
551
  prepareForLayoutAnimationRender: () => {
552
+ if (!recyclerViewManager.props.keyExtractor) {
553
+ console.warn(WarningMessages.keyExtractorNotDefinedForAnimation);
554
+ }
550
555
  recyclerViewManager.animationOptimizationsEnabled = true;
551
556
  },
552
557
  };
@@ -7,6 +7,7 @@ import {
7
7
  findLastVisibleIndex,
8
8
  } from "../utils/findVisibleIndex";
9
9
  import { areDimensionsNotEqual } from "../utils/measureLayout";
10
+ import { ErrorMessages } from "../../errors/ErrorMessages";
10
11
 
11
12
  /**
12
13
  * Base abstract class for layout managers in the recycler view system.
@@ -224,7 +225,7 @@ export abstract class RVLayoutManager {
224
225
  */
225
226
  getLayout(index: number): RVLayout {
226
227
  if (index >= this.layouts.length) {
227
- throw new Error("index out of bounds, not enough layouts");
228
+ throw new Error(ErrorMessages.indexOutOfBounds);
228
229
  }
229
230
  let layout = this.layouts[index];
230
231
  if (!layout) {
@@ -1,8 +1,7 @@
1
1
  import { ViewabilityConfig } from "react-native";
2
- import { Dimension, Layout } from "recyclerlistview";
3
2
 
4
- import CustomError from "../errors/CustomError";
5
- import ExceptionList from "../errors/ExceptionList";
3
+ import { RVDimension, RVLayout } from "../layout-managers/LayoutManager";
4
+ import { ErrorMessages } from "../../errors/ErrorMessages";
6
5
 
7
6
  /**
8
7
  * Helper class for computing viewable items based on the passed `viewabilityConfig`.
@@ -48,8 +47,8 @@ class ViewabilityHelper {
48
47
  public updateViewableItems(
49
48
  horizontal: boolean,
50
49
  scrollOffset: number,
51
- listSize: Dimension,
52
- getLayout: (index: number) => Layout | undefined,
50
+ listSize: RVDimension,
51
+ getLayout: (index: number) => RVLayout | undefined,
53
52
  viewableIndices?: number[]
54
53
  ) {
55
54
  if (viewableIndices !== undefined) {
@@ -61,8 +60,8 @@ class ViewabilityHelper {
61
60
  this.viewabilityConfig?.viewAreaCoveragePercentThreshold !== null &&
62
61
  this.viewabilityConfig?.viewAreaCoveragePercentThreshold !== undefined
63
62
  ) {
64
- throw new CustomError(
65
- ExceptionList.multipleViewabilityThresholdTypesNotSupported
63
+ throw new Error(
64
+ ErrorMessages.multipleViewabilityThresholdTypesNotSupported
66
65
  );
67
66
  }
68
67
  if (
@@ -126,10 +125,10 @@ class ViewabilityHelper {
126
125
  index: number,
127
126
  horizontal: boolean,
128
127
  scrollOffset: number,
129
- listSize: Dimension,
128
+ listSize: RVDimension,
130
129
  viewAreaCoveragePercentThreshold: number | null | undefined,
131
130
  itemVisiblePercentThreshold: number | null | undefined,
132
- getLayout: (index: number) => Layout | undefined
131
+ getLayout: (index: number) => RVLayout | undefined
133
132
  ) {
134
133
  const itemLayout = getLayout(index);
135
134
  if (itemLayout === undefined) {
@@ -1,6 +1,6 @@
1
1
  import { ViewabilityConfig } from "react-native";
2
2
 
3
- import FlashList from "../FlashList";
3
+ import { RecyclerViewManager } from "../RecyclerViewManager";
4
4
 
5
5
  import ViewabilityHelper from "./ViewabilityHelper";
6
6
  import ViewToken from "./ViewToken";
@@ -9,31 +9,31 @@ import ViewToken from "./ViewToken";
9
9
  * Manager for viewability tracking. It holds multiple viewability callback pairs and keeps them updated.
10
10
  */
11
11
  export default class ViewabilityManager<T> {
12
- private flashListRef: FlashList<T>;
12
+ private rvManager: RecyclerViewManager<T>;
13
13
  private viewabilityHelpers: ViewabilityHelper[] = [];
14
14
  private hasInteracted = false;
15
15
 
16
- constructor(flashListRef: FlashList<T>) {
17
- this.flashListRef = flashListRef;
16
+ constructor(rvManager: RecyclerViewManager<T>) {
17
+ this.rvManager = rvManager;
18
18
  if (
19
- flashListRef.props.onViewableItemsChanged !== null &&
20
- flashListRef.props.onViewableItemsChanged !== undefined
19
+ rvManager.props.onViewableItemsChanged !== null &&
20
+ rvManager.props.onViewableItemsChanged !== undefined
21
21
  ) {
22
22
  this.viewabilityHelpers.push(
23
23
  this.createViewabilityHelper(
24
- flashListRef.props.viewabilityConfig,
24
+ rvManager.props.viewabilityConfig,
25
25
  (info) => {
26
- flashListRef.props.onViewableItemsChanged?.(info);
26
+ rvManager.props.onViewableItemsChanged?.(info);
27
27
  }
28
28
  )
29
29
  );
30
30
  }
31
- (flashListRef.props.viewabilityConfigCallbackPairs ?? []).forEach(
31
+ (rvManager.props.viewabilityConfigCallbackPairs ?? []).forEach(
32
32
  (pair, index) => {
33
33
  this.viewabilityHelpers.push(
34
34
  this.createViewabilityHelper(pair.viewabilityConfig, (info) => {
35
35
  const callback =
36
- flashListRef.props.viewabilityConfigCallbackPairs?.[index]
36
+ rvManager.props.viewabilityConfigCallbackPairs?.[index]
37
37
  ?.onViewableItemsChanged;
38
38
  callback?.(info);
39
39
  })
@@ -71,21 +71,19 @@ export default class ViewabilityManager<T> {
71
71
  };
72
72
 
73
73
  public updateViewableItems = (newViewableIndices?: number[]) => {
74
- const listSize =
75
- this.flashListRef.getWindowSize() ??
76
- this.flashListRef.props.estimatedListSize;
74
+ const listSize = this.rvManager.getWindowSize();
77
75
  if (listSize === undefined || !this.shouldListenToVisibleIndices) {
78
76
  return;
79
77
  }
80
78
  const scrollOffset =
81
- (this.flashListRef.getAbsoluteLastScrollOffset() ?? 0) -
82
- this.flashListRef.firstItemOffset;
79
+ (this.rvManager.getAbsoluteLastScrollOffset() ?? 0) -
80
+ this.rvManager.firstItemOffset;
83
81
  this.viewabilityHelpers.forEach((viewabilityHelper) => {
84
82
  viewabilityHelper.updateViewableItems(
85
- this.flashListRef.props.horizontal ?? false,
83
+ this.rvManager.props.horizontal ?? false,
86
84
  scrollOffset,
87
85
  listSize,
88
- (index: number) => this.flashListRef.getLayout(index),
86
+ (index: number) => this.rvManager.getLayout(index),
89
87
  newViewableIndices
90
88
  );
91
89
  });
@@ -117,11 +115,11 @@ export default class ViewabilityManager<T> {
117
115
  index: number,
118
116
  isViewable: boolean
119
117
  ) => {
120
- const item = this.flashListRef.props.data![index];
118
+ const item = this.rvManager.props.data![index];
121
119
  const key =
122
- item === undefined || this.flashListRef.props.keyExtractor === undefined
120
+ item === undefined || this.rvManager.props.keyExtractor === undefined
123
121
  ? index.toString()
124
- : this.flashListRef.props.keyExtractor(item, index);
122
+ : this.rvManager.props.keyExtractor(item, index);
125
123
  return {
126
124
  index,
127
125
  isViewable,
@@ -1,37 +0,0 @@
1
- require 'json'
2
-
3
- package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
- new_arch_enabled = ENV['RCT_NEW_ARCH_ENABLED']
5
-
6
- Pod::Spec.new do |s|
7
- s.name = 'RNFlashList'
8
- s.version = package['version']
9
- s.summary = package['description']
10
- s.homepage = package['homepage']
11
- s.license = package['license']
12
- s.author = package['author']
13
- s.platforms = { :ios => '11.0', :tvos => '12.0' }
14
- s.source = { git: 'https://github.com/shopify/flash-list.git', tag: "v#{s.version}" }
15
- s.source_files = 'ios/Sources/**/*'
16
- s.requires_arc = true
17
- s.swift_version = '5.0'
18
-
19
- if new_arch_enabled
20
- s.pod_target_xcconfig = {
21
- 'OTHER_SWIFT_FLAGS' => '-D RCT_NEW_ARCH_ENABLED',
22
- }
23
- end
24
-
25
- # install_modules_dependencies is available since RN 0.71
26
- if respond_to?(:install_modules_dependencies, true)
27
- install_modules_dependencies(s)
28
- else
29
- s.dependency "React-Core"
30
- end
31
-
32
- # Tests spec
33
- s.test_spec 'Tests' do |test_spec|
34
- test_spec.source_files = 'ios/Tests/**/*'
35
- test_spec.framework = 'XCTest'
36
- end
37
- end
@@ -1,89 +0,0 @@
1
- def isNewArchitectureEnabled() {
2
- return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
3
- }
4
-
5
- apply plugin: 'com.android.library'
6
-
7
- apply plugin: 'kotlin-android'
8
-
9
- if (isNewArchitectureEnabled()) {
10
- apply plugin: 'com.facebook.react'
11
- }
12
-
13
- def _ext = rootProject.ext
14
-
15
- def _reactNativeVersion = _ext.has('reactNative') ? _ext.reactNative : '+'
16
- def _compileSdkVersion = _ext.has('compileSdkVersion') ? _ext.compileSdkVersion : 30
17
- def _buildToolsVersion = _ext.has('buildToolsVersion') ? _ext.buildToolsVersion : '30.0.2'
18
- def _minSdkVersion = _ext.has('minSdkVersion') ? _ext.minSdkVersion : 21
19
- def _targetSdkVersion = _ext.has('targetSdkVersion') ? _ext.targetSdkVersion : 30
20
- def _junitVersion = _ext.has('junitVersion') ? _ext.junitVersion : '4.13.2'
21
- def _mockitoVersion = _ext.has('mockitoVersion') ? _ext.mockitoVersion : '3.2.0'
22
- def _androidTestRunnerVersion = _ext.has('androidTestRunnerVersion') ? _ext.androidTestRunnerVersion : '1.1.0'
23
-
24
- buildscript {
25
- // buildscript is evaluated before any other task is executed, so this must be defined here
26
- ext._kotlinVersion = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get('kotlinVersion') : '1.8.10'
27
-
28
- repositories {
29
- mavenCentral()
30
- }
31
-
32
- dependencies {
33
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${_kotlinVersion}")
34
- }
35
- }
36
-
37
- android {
38
- compileSdkVersion _compileSdkVersion
39
- buildToolsVersion _buildToolsVersion
40
-
41
- // Conditional for compatibility with AGP <4.2.
42
- if (project.android.hasProperty("namespace")) {
43
- namespace = "com.shopify.reactnative.flash_list"
44
- }
45
-
46
- compileOptions {
47
- sourceCompatibility JavaVersion.VERSION_1_8
48
- targetCompatibility JavaVersion.VERSION_1_8
49
- }
50
-
51
- sourceSets {
52
- main.java.srcDirs += 'src/main/kotlin'
53
- debug.java.srcDirs += 'src/debug/kotlin'
54
- test.java.srcDirs += 'src/test/kotlin'
55
- androidTest.java.srcDirs += 'src/androidTest/kotlin'
56
-
57
- if (!isNewArchitectureEnabled()) {
58
- main.java.srcDirs += ['src/paper/java']
59
- }
60
- }
61
-
62
- defaultConfig {
63
- minSdkVersion _minSdkVersion
64
- targetSdkVersion _targetSdkVersion
65
- buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
66
- versionCode 1
67
- versionName "1.0"
68
- testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
69
- }
70
-
71
- lintOptions {
72
- abortOnError false
73
- }
74
-
75
- testOptions {
76
- unitTests.returnDefaultValues = true
77
- }
78
- }
79
-
80
- dependencies {
81
- compileOnly "com.facebook.react:react-native:${_reactNativeVersion}"
82
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${_kotlinVersion}"
83
- testImplementation "junit:junit:${_junitVersion}"
84
- testImplementation "org.mockito.kotlin:mockito-kotlin:${_mockitoVersion}"
85
- testImplementation "org.mockito:mockito-inline:${_mockitoVersion}"
86
- testImplementation 'com.google.code.gson:gson:2.8.9'
87
- androidTestImplementation("androidx.test:runner:${_androidTestRunnerVersion}")
88
- androidTestImplementation("androidx.test:rules:${_androidTestRunnerVersion}")
89
- }
@@ -1,3 +0,0 @@
1
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
- package="com.shopify.reactnative.flash_list">
3
- </manifest>
@@ -1,105 +0,0 @@
1
- package com.shopify.reactnative.flash_list
2
-
3
- class AutoLayoutShadow {
4
- var horizontal: Boolean = false
5
- var scrollOffset: Int = 0
6
- var offsetFromStart: Int = 0
7
- var windowSize: Int = 0
8
- var renderOffset = 0
9
-
10
- var blankOffsetAtStart = 0 // Tracks blank area from the top
11
- var blankOffsetAtEnd = 0 // Tracks blank area from the bottom
12
-
13
- var lastMaxBoundOverall = 0 // Tracks where the last pixel is drawn in the overall
14
-
15
- private var lastMaxBound = 0 // Tracks where the last pixel is drawn in the visible window
16
- private var lastMinBound = 0 // Tracks where first pixel is drawn in the visible window
17
-
18
- /** Checks for overlaps or gaps between adjacent items and then applies a correction (Only Grid layouts with varying spans)
19
- * Performance: RecyclerListView renders very small number of views and this is not going to trigger multiple layouts on Android side. Not expecting any major perf issue. */
20
- fun clearGapsAndOverlaps(sortedItems: Array<CellContainer>) {
21
- var maxBound = 0
22
- var minBound = Int.MAX_VALUE
23
- var maxBoundNeighbour = 0
24
- lastMaxBoundOverall = 0
25
- for (i in 0 until sortedItems.size - 1) {
26
- val cell = sortedItems[i]
27
- val neighbour = sortedItems[i + 1]
28
- // Only apply correction if the next cell is consecutive.
29
- val isNeighbourConsecutive = neighbour.index == cell.index + 1
30
- if (isWithinBounds(cell) || isWithinBounds(neighbour)) {
31
- if (!horizontal) {
32
- maxBound = kotlin.math.max(maxBound, cell.bottom);
33
- minBound = kotlin.math.min(minBound, cell.top);
34
- maxBoundNeighbour = maxBound
35
- if (isNeighbourConsecutive) {
36
- if (cell.left < neighbour.left) {
37
- if (cell.right != neighbour.left) {
38
- neighbour.right = cell.right + neighbour.width
39
- neighbour.left = cell.right
40
- }
41
- if (cell.top != neighbour.top) {
42
- neighbour.bottom = cell.top + neighbour.height
43
- neighbour.top = cell.top
44
- }
45
- } else {
46
- neighbour.bottom = maxBound + neighbour.height
47
- neighbour.top = maxBound
48
- }
49
- }
50
- if (isWithinBounds(neighbour)) {
51
- maxBoundNeighbour = kotlin.math.max(maxBound, neighbour.bottom)
52
- }
53
- } else {
54
- maxBound = kotlin.math.max(maxBound, cell.right);
55
- minBound = kotlin.math.min(minBound, cell.left);
56
- maxBoundNeighbour = maxBound
57
- if (isNeighbourConsecutive) {
58
- if (cell.top < neighbour.top) {
59
- if (cell.bottom != neighbour.top) {
60
- neighbour.bottom = cell.bottom + neighbour.height
61
- neighbour.top = cell.bottom
62
- }
63
- if (cell.left != neighbour.left) {
64
- neighbour.right = cell.left + neighbour.width
65
- neighbour.left = cell.left
66
- }
67
- } else {
68
- neighbour.right = maxBound + neighbour.width
69
- neighbour.left = maxBound
70
- }
71
- }
72
- if (isWithinBounds(neighbour)) {
73
- maxBoundNeighbour = kotlin.math.max(maxBound, neighbour.right)
74
- }
75
- }
76
- }
77
- lastMaxBoundOverall = kotlin.math.max(lastMaxBoundOverall, if (horizontal) cell.right else cell.bottom)
78
- lastMaxBoundOverall = kotlin.math.max(lastMaxBoundOverall, if (horizontal) neighbour.right else neighbour.bottom)
79
- }
80
- lastMaxBound = maxBoundNeighbour
81
- lastMinBound = minBound
82
- }
83
-
84
- /** Offset provided by react can be one frame behind the real one, it's important that this method is called with offset taken directly from
85
- * scrollview object */
86
- fun computeBlankFromGivenOffset(actualScrollOffset: Int, distanceFromWindowStart: Int, distanceFromWindowEnd: Int): Int {
87
- val actualScrollOffset = actualScrollOffset - offsetFromStart;
88
- blankOffsetAtStart = lastMinBound - actualScrollOffset - distanceFromWindowStart
89
- blankOffsetAtEnd = actualScrollOffset + windowSize - renderOffset - lastMaxBound - distanceFromWindowEnd
90
- return kotlin.math.max(blankOffsetAtStart, blankOffsetAtEnd)
91
- }
92
-
93
- /** It's important to avoid correcting views outside the render window. An item that isn't being recycled might still remain in the view tree. If views outside get considered then gaps between
94
- * unused items will cause algorithm to fail.*/
95
- private fun isWithinBounds(cell: CellContainer): Boolean {
96
- val scrollOffset = scrollOffset - offsetFromStart;
97
- return if (!horizontal) {
98
- (cell.top >= (scrollOffset - renderOffset) || cell.bottom >= (scrollOffset - renderOffset)) &&
99
- (cell.top <= scrollOffset + windowSize || cell.bottom <= scrollOffset + windowSize)
100
- } else {
101
- (cell.left >= (scrollOffset - renderOffset) || cell.right >= (scrollOffset - renderOffset)) &&
102
- (cell.left <= scrollOffset + windowSize || cell.right <= scrollOffset + windowSize)
103
- }
104
- }
105
- }
@@ -1,158 +0,0 @@
1
- package com.shopify.reactnative.flash_list
2
-
3
- import android.content.Context
4
- import android.graphics.Canvas
5
- import android.util.DisplayMetrics
6
- import android.util.Log
7
- import android.view.View
8
- import android.view.ViewGroup
9
- import android.widget.HorizontalScrollView
10
- import android.widget.ScrollView
11
- import com.facebook.react.bridge.Arguments
12
- import com.facebook.react.bridge.ReactContext
13
- import com.facebook.react.bridge.WritableMap
14
- import com.facebook.react.uimanager.UIManagerHelper
15
- import com.facebook.react.uimanager.events.EventDispatcher
16
- import com.facebook.react.uimanager.events.RCTEventEmitter
17
- import com.facebook.react.views.view.ReactViewGroup
18
-
19
-
20
- /** Container for all RecyclerListView children. This will automatically remove all gaps and overlaps for GridLayouts with flexible spans.
21
- * Note: This cannot work for masonry layouts i.e, pinterest like layout */
22
- class AutoLayoutView(context: Context) : ReactViewGroup(context) {
23
- val alShadow = AutoLayoutShadow()
24
- var enableInstrumentation = false
25
- var disableAutoLayout = false
26
-
27
- var pixelDensity = 1.0;
28
-
29
- /** Overriding draw instead of onLayout. RecyclerListView uses absolute positions for each and every item which means that changes in child layouts may not trigger onLayout on this container. The same layout
30
- * can still cause views to overlap. Therefore, it makes sense to override draw to do correction. */
31
- override fun dispatchDraw(canvas: Canvas) {
32
- fixLayout()
33
- fixFooter()
34
- super.dispatchDraw(canvas)
35
-
36
- val parentScrollView = getParentScrollView()
37
- if (enableInstrumentation && parentScrollView != null) {
38
- /** Since we need to call this method with scrollOffset on the UI thread and not with the one react has we're querying parent's parent
39
- directly which will be a ScrollView. If it isn't reported values will be incorrect but the component will not break.
40
- RecyclerListView is expected not to change the hierarchy of children. */
41
-
42
- val scrollContainerSize = if (alShadow.horizontal) parentScrollView.width else parentScrollView.height
43
-
44
- val scrollOffset = if (alShadow.horizontal) parentScrollView.scrollX else parentScrollView.scrollY
45
-
46
- val startOffset = if (alShadow.horizontal) left else top
47
- val endOffset = if (alShadow.horizontal) right else bottom
48
-
49
- val distanceFromWindowStart = kotlin.math.max(startOffset - scrollOffset, 0)
50
- val distanceFromWindowEnd = kotlin.math.max(scrollOffset + scrollContainerSize - endOffset, 0)
51
-
52
- alShadow.computeBlankFromGivenOffset(scrollOffset, distanceFromWindowStart, distanceFromWindowEnd)
53
- emitBlankAreaEvent()
54
- }
55
- }
56
-
57
- /** Sorts views by index and then invokes clearGaps which does the correction.
58
- * Performance: Sort is needed. Given relatively low number of views in RecyclerListView render tree this should be a non issue.*/
59
- private fun fixLayout() {
60
- if (childCount > 1 && !disableAutoLayout) {
61
- val positionSortedViews: Array<CellContainer> = Array(childCount) {
62
- val child = getChildAt(it)
63
- if (child is CellContainer) {
64
- child
65
- } else {
66
- throw IllegalStateException("CellRendererComponent outer view should always be CellContainer. Learn more here: https://shopify.github.io/flash-list/docs/usage#cellrenderercomponent.")
67
- }
68
- }
69
- positionSortedViews.sortBy { it.index }
70
- alShadow.offsetFromStart = if (alShadow.horizontal) left else top
71
- alShadow.clearGapsAndOverlaps(positionSortedViews)
72
- }
73
- }
74
-
75
- /** Fixes footer position along with rest of the items */
76
- private fun fixFooter() {
77
- val parentScrollView = getParentScrollView()
78
- if (disableAutoLayout || parentScrollView == null) {
79
- return
80
- }
81
- val isAutoLayoutEndVisible = if (alShadow.horizontal) right <= parentScrollView.width else bottom <= parentScrollView.height
82
- if (!isAutoLayoutEndVisible) {
83
- return
84
- }
85
- val autoLayoutParent = parent as? View
86
- val footer = getFooter();
87
- val diff = getFooterDiff()
88
- if (diff == 0 || footer == null || autoLayoutParent == null) {
89
- return
90
- }
91
-
92
- if (alShadow.horizontal) {
93
- footer.offsetLeftAndRight(diff)
94
- right += diff
95
- autoLayoutParent.right += diff
96
- } else {
97
- footer.offsetTopAndBottom(diff)
98
- bottom += diff
99
- autoLayoutParent.bottom += diff
100
- }
101
- }
102
-
103
- private fun getFooterDiff(): Int {
104
- if (childCount == 0) {
105
- alShadow.lastMaxBoundOverall = 0
106
- } else if (childCount == 1) {
107
- val firstChild = getChildAt(0)
108
- alShadow.lastMaxBoundOverall = if (alShadow.horizontal) {
109
- firstChild.right
110
- } else {
111
- firstChild.bottom
112
- }
113
- }
114
- val autoLayoutEnd = if (alShadow.horizontal) right - left else bottom - top
115
- return alShadow.lastMaxBoundOverall - autoLayoutEnd
116
- }
117
-
118
- private fun getFooter(): View? {
119
- return (parent as? ViewGroup)?.let {
120
- for (i in 0 until it.childCount) {
121
- val view = it.getChildAt(i)
122
- if (view is CellContainer && view.index == -1) {
123
- return@let view
124
- }
125
- }
126
- return@let null
127
- }
128
- }
129
-
130
- private fun getParentScrollView(): View? {
131
- var autoLayoutParent = parent;
132
- while (autoLayoutParent != null) {
133
- if (autoLayoutParent is ScrollView || autoLayoutParent is HorizontalScrollView) {
134
- return autoLayoutParent as View
135
- }
136
- autoLayoutParent = autoLayoutParent.parent;
137
- }
138
- return null
139
- }
140
-
141
-
142
- private fun emitBlankAreaEvent() {
143
- val eventDispatcher: EventDispatcher? =
144
- UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id)
145
-
146
- if (eventDispatcher != null) {
147
- val surfaceId = UIManagerHelper.getSurfaceId(context as ReactContext)
148
- eventDispatcher.dispatchEvent(
149
- BlankAreaEvent(
150
- surfaceId,
151
- viewTag = id,
152
- offsetStart = alShadow.blankOffsetAtStart / pixelDensity,
153
- offsetEnd = alShadow.blankOffsetAtEnd / pixelDensity
154
- )
155
- )
156
- }
157
- }
158
- }