@onekeyfe/react-native-pager-view 3.0.157-alpha.257 → 3.0.157-alpha.258

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 (33) hide show
  1. package/README.md +51 -4
  2. package/android/src/main/java/com/reactnativepagerview/CollapsiblePagerHost.kt +237 -43
  3. package/android/src/main/java/com/reactnativepagerview/NativeScrollerScrollAwayInsets.kt +15 -11
  4. package/android/src/main/java/com/reactnativepagerview/NativeScrollerView.kt +573 -0
  5. package/android/src/main/java/com/reactnativepagerview/NativeScrollerViewManager.kt +130 -0
  6. package/android/src/main/java/com/reactnativepagerview/PagerViewViewPackage.kt +1 -1
  7. package/android/src/main/jni/CMakeLists.txt +19 -0
  8. package/android/src/main/jni/pagerview.h +11 -0
  9. package/android/src/main/res/values/native_scroll_coordinator_ids.xml +1 -0
  10. package/android/src/test/java/com/reactnativepagerview/NativeScrollerScrollAwayInsetsTest.kt +32 -52
  11. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerComponentDescriptor.h +8 -0
  12. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerShadowNode.cpp +15 -0
  13. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerShadowNode.h +23 -0
  14. package/common/cpp/react/renderer/components/pagerview/RNCNativeScrollerState.h +33 -0
  15. package/docs/SPEC.md +267 -34
  16. package/ios/RNCCollapsiblePagerViewComponentView.mm +187 -1
  17. package/ios/RNCNativeScrollerComponentView.h +17 -0
  18. package/ios/RNCNativeScrollerComponentView.mm +479 -0
  19. package/ios/tests/RNCCollapsiblePagerPressCancellationTests.mm +346 -0
  20. package/ios/tests/RNCCollapsiblePagerPressCancellationWiringTests.mm +109 -0
  21. package/ios/tests/RNCNativeScrollerTests.mm +252 -0
  22. package/lib/module/CollapsiblePagerView.js +1 -1
  23. package/lib/module/NativeScroller.js +171 -11
  24. package/lib/module/NativeScrollerNativeComponent.ts +101 -0
  25. package/lib/typescript/src/CollapsiblePagerView.d.ts +2 -3
  26. package/lib/typescript/src/NativeScroller.d.ts +15 -7
  27. package/lib/typescript/src/NativeScrollerNativeComponent.d.ts +79 -0
  28. package/package.json +6 -3
  29. package/react-native-pager-view.podspec +2 -1
  30. package/react-native.config.js +15 -0
  31. package/src/CollapsiblePagerView.tsx +4 -4
  32. package/src/NativeScroller.tsx +291 -14
  33. package/src/NativeScrollerNativeComponent.ts +101 -0
@@ -0,0 +1,130 @@
1
+ package com.reactnativepagerview
2
+
3
+ import android.graphics.Color
4
+ import android.view.View
5
+ import com.facebook.react.bridge.ReadableArray
6
+ import com.facebook.react.module.annotations.ReactModule
7
+ import com.facebook.react.uimanager.ReactStylesDiffMap
8
+ import com.facebook.react.uimanager.StateWrapper
9
+ import com.facebook.react.uimanager.ThemedReactContext
10
+ import com.facebook.react.uimanager.ViewGroupManager
11
+ import com.facebook.react.uimanager.ViewManagerDelegate
12
+ import com.facebook.react.uimanager.annotations.ReactProp
13
+ import com.facebook.react.viewmanagers.RNCNativeScrollerManagerDelegate
14
+ import com.facebook.react.viewmanagers.RNCNativeScrollerManagerInterface
15
+
16
+ @ReactModule(name = NativeScrollerViewManager.NAME)
17
+ class NativeScrollerViewManager : ViewGroupManager<NativeScrollerView>(),
18
+ RNCNativeScrollerManagerInterface<NativeScrollerView> {
19
+ private val delegate: ViewManagerDelegate<NativeScrollerView> = RNCNativeScrollerManagerDelegate(this)
20
+ override fun getDelegate() = delegate
21
+ override fun getName() = NAME
22
+ override fun createViewInstance(context: ThemedReactContext) = NativeScrollerView(context)
23
+ override fun needsCustomLayoutForChildren() = false
24
+ override fun addView(parent: NativeScrollerView, child: View, index: Int) = parent.addReactChild(child, index)
25
+ override fun getChildCount(parent: NativeScrollerView) = parent.reactChildCount()
26
+ override fun getChildAt(parent: NativeScrollerView, index: Int) = parent.reactChildAt(index)
27
+ override fun removeViewAt(parent: NativeScrollerView, index: Int) {
28
+ require(index == 0)
29
+ parent.removeReactChild()
30
+ }
31
+ override fun removeAllViews(parent: NativeScrollerView) = parent.removeReactChild()
32
+ override fun onDropViewInstance(view: NativeScrollerView) {
33
+ view.viewport.stopMotion()
34
+ view.setFabricState(null)
35
+ super.onDropViewInstance(view)
36
+ }
37
+ override fun updateState(view: NativeScrollerView, props: ReactStylesDiffMap, stateWrapper: StateWrapper): Any? {
38
+ view.setFabricState(stateWrapper)
39
+ return null
40
+ }
41
+ override fun onAfterUpdateTransaction(view: NativeScrollerView) {
42
+ super.onAfterUpdateTransaction(view)
43
+ view.scheduleLayout()
44
+ }
45
+
46
+ @ReactProp(name = "contentWidth")
47
+ override fun setContentWidth(view: NativeScrollerView, value: Double) = view.setContentSize(width = view.dip(value))
48
+ @ReactProp(name = "contentHeight")
49
+ override fun setContentHeight(view: NativeScrollerView, value: Double) = view.setContentSize(height = view.dip(value))
50
+ @ReactProp(name = "scrollEnabled", defaultBoolean = true)
51
+ override fun setScrollEnabled(view: NativeScrollerView, value: Boolean) = view.setScrollEnabled(value)
52
+ @ReactProp(name = "nestedScrollEnabled", defaultBoolean = true)
53
+ override fun setNestedScrollEnabled(view: NativeScrollerView, value: Boolean) {
54
+ if (!value) view.viewport.stopMotion()
55
+ view.viewport.isNestedScrollingEnabled = value
56
+ }
57
+ @ReactProp(name = "showsVerticalScrollIndicator", defaultBoolean = true)
58
+ override fun setShowsVerticalScrollIndicator(view: NativeScrollerView, value: Boolean) {
59
+ view.viewport.isVerticalScrollBarEnabled = value
60
+ }
61
+ @ReactProp(name = "showsHorizontalScrollIndicator")
62
+ override fun setShowsHorizontalScrollIndicator(view: NativeScrollerView, value: Boolean) {
63
+ view.viewport.isHorizontalScrollBarEnabled = value
64
+ }
65
+ // UIKit-only properties: Android keeps the platform NestedScrollView fling/edge policy.
66
+ @ReactProp(name = "bounces", defaultBoolean = true)
67
+ override fun setBounces(view: NativeScrollerView, value: Boolean) = Unit
68
+ @ReactProp(name = "alwaysBounceVertical", defaultBoolean = true)
69
+ override fun setAlwaysBounceVertical(view: NativeScrollerView, value: Boolean) = Unit
70
+ @ReactProp(name = "decelerationRate", defaultDouble = 0.998)
71
+ override fun setDecelerationRate(view: NativeScrollerView, value: Double) = Unit
72
+ @ReactProp(name = "keyboardDismissMode")
73
+ override fun setKeyboardDismissMode(view: NativeScrollerView, value: String?) {
74
+ view.keyboardDismissMode = value ?: "none"
75
+ }
76
+ @ReactProp(name = "keyboardShouldPersistTaps")
77
+ override fun setKeyboardShouldPersistTaps(view: NativeScrollerView, value: String?) {
78
+ // The JS responder wrapper owns never/handled/always and TextInput exceptions.
79
+ view.keyboardShouldPersistTaps = value ?: "never"
80
+ }
81
+ @ReactProp(name = "scrollEventThrottle")
82
+ override fun setScrollEventThrottle(view: NativeScrollerView, value: Double) {
83
+ view.scrollEventThrottle = value.coerceAtLeast(0.0)
84
+ }
85
+ @ReactProp(name = "contentInsetTop")
86
+ override fun setContentInsetTop(view: NativeScrollerView, value: Double) { view.insetTop = view.dip(value).coerceAtLeast(0) }
87
+ @ReactProp(name = "contentInsetRight")
88
+ override fun setContentInsetRight(view: NativeScrollerView, value: Double) { view.insetRight = view.dip(value).coerceAtLeast(0) }
89
+ @ReactProp(name = "contentInsetBottom")
90
+ override fun setContentInsetBottom(view: NativeScrollerView, value: Double) { view.insetBottom = view.dip(value).coerceAtLeast(0) }
91
+ @ReactProp(name = "contentInsetLeft")
92
+ override fun setContentInsetLeft(view: NativeScrollerView, value: Double) { view.insetLeft = view.dip(value).coerceAtLeast(0) }
93
+ @ReactProp(name = "refreshEnabled")
94
+ override fun setRefreshEnabled(view: NativeScrollerView, value: Boolean) { view.refreshEnabled = value }
95
+ @ReactProp(name = "refreshing")
96
+ override fun setRefreshing(view: NativeScrollerView, value: Boolean) = view.setRefreshing(value)
97
+ @ReactProp(name = "refreshTintColor", customType = "Color")
98
+ override fun setRefreshTintColor(view: NativeScrollerView, value: Int?) {
99
+ // Android's refreshColors determines the native arc; tintColor is iOS-only.
100
+ }
101
+ @ReactProp(name = "refreshColors", customType = "ColorArray")
102
+ override fun setRefreshColors(view: NativeScrollerView, value: ReadableArray?) {
103
+ view.setRefreshColors(if (value == null) intArrayOf(Color.GRAY) else IntArray(value.size()) { value.getInt(it) })
104
+ }
105
+ @ReactProp(name = "refreshProgressBackgroundColor", customType = "Color")
106
+ override fun setRefreshProgressBackgroundColor(view: NativeScrollerView, value: Int?) =
107
+ view.setRefreshBackground(value ?: Color.WHITE)
108
+ @ReactProp(name = "refreshProgressViewOffset")
109
+ override fun setRefreshProgressViewOffset(view: NativeScrollerView, value: Double) = view.setRefreshOffset(view.dip(value))
110
+ @ReactProp(name = "refreshTitle")
111
+ override fun setRefreshTitle(view: NativeScrollerView, value: String?) = Unit
112
+ @ReactProp(name = "refreshTitleColor", customType = "Color")
113
+ override fun setRefreshTitleColor(view: NativeScrollerView, value: Int?) = Unit
114
+ @ReactProp(name = "refreshSize")
115
+ override fun setRefreshSize(view: NativeScrollerView, value: String?) = view.setRefreshSize(value)
116
+
117
+ override fun receiveCommand(view: NativeScrollerView, commandId: String, args: ReadableArray?) =
118
+ delegate.receiveCommand(view, commandId, args)
119
+ override fun setRefreshState(view: NativeScrollerView, refreshing: Boolean) = view.setRefreshing(refreshing)
120
+ override fun scrollTo(view: NativeScrollerView, x: Double, y: Double, animated: Boolean) =
121
+ view.scrollToPosition(view.dip(x), view.dip(y), animated)
122
+ override fun scrollToEnd(view: NativeScrollerView, animated: Boolean) = view.scrollToEnd(animated)
123
+ override fun flashScrollIndicators(view: NativeScrollerView) { view.viewport.flashIndicators() }
124
+
125
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Map<String, String>> =
126
+ listOf("Scroll", "ScrollBeginDrag", "ScrollEndDrag", "MomentumScrollBegin", "MomentumScrollEnd", "Refresh", "ContentViewportChange")
127
+ .associate { "top$it" to mapOf("registrationName" to "on$it") }.toMutableMap()
128
+
129
+ companion object { const val NAME = "RNCNativeScroller" }
130
+ }
@@ -12,6 +12,6 @@ class PagerViewPackage : ReactPackage {
12
12
  }
13
13
 
14
14
  override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
15
- return listOf(PagerViewViewManager(), CollapsiblePagerViewManager())
15
+ return listOf(PagerViewViewManager(), CollapsiblePagerViewManager(), NativeScrollerViewManager())
16
16
  }
17
17
  }
@@ -0,0 +1,19 @@
1
+ cmake_minimum_required(VERSION 3.13)
2
+
3
+ set(PAGER_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
4
+ set(PAGER_GENERATED ${PAGER_ROOT}/android/build/generated/source/codegen/jni)
5
+ set(PAGER_COMMON ${PAGER_ROOT}/common/cpp)
6
+ file(GLOB PAGER_GENERATED_SOURCES CONFIGURE_DEPENDS
7
+ ${PAGER_GENERATED}/*.cpp
8
+ ${PAGER_GENERATED}/react/renderer/components/pagerview/*.cpp)
9
+
10
+ add_library(react_codegen_pagerview OBJECT
11
+ ${PAGER_GENERATED_SOURCES}
12
+ ${PAGER_COMMON}/react/renderer/components/pagerview/RNCNativeScrollerShadowNode.cpp)
13
+ target_include_directories(react_codegen_pagerview PUBLIC
14
+ ${CMAKE_CURRENT_SOURCE_DIR}
15
+ ${PAGER_COMMON}
16
+ ${PAGER_GENERATED}
17
+ ${PAGER_GENERATED}/react/renderer/components/pagerview)
18
+ target_link_libraries(react_codegen_pagerview fbjni jsi reactnative)
19
+ target_compile_reactnative_options(react_codegen_pagerview PRIVATE)
@@ -0,0 +1,11 @@
1
+ #pragma once
2
+
3
+ #include <ReactCommon/JavaTurboModule.h>
4
+ #include <ReactCommon/TurboModule.h>
5
+ #include <jsi/jsi.h>
6
+ #include <react/renderer/components/pagerview/RNCNativeScrollerComponentDescriptor.h>
7
+
8
+ namespace facebook::react {
9
+ JSI_EXPORT std::shared_ptr<TurboModule> pagerview_ModuleProvider(
10
+ const std::string &moduleName, const JavaTurboModule::InitParams &params);
11
+ } // namespace facebook::react
@@ -1,4 +1,5 @@
1
1
  <resources>
2
2
  <item name="onekey_native_scroll_coordinator_consumed_offsets" type="id" />
3
3
  <item name="onekey_native_scroll_coordinator_offset_listener" type="id" />
4
+ <item name="onekey_native_scroll_coordinator_refresh_inset" type="id" />
4
5
  </resources>
@@ -37,59 +37,39 @@ fun main() {
37
37
 
38
38
  val firstOwner = Any()
39
39
  val secondOwner = Any()
40
- val translation = NativeScrollerRefreshTranslation(7.5f)
41
- check(translation.isEmpty)
42
- var current = translation.update(7.5f, firstOwner, 230f)
43
- check(current == 237.5f)
44
- check(!translation.isEmpty)
45
- current = translation.update(current, firstOwner, 230f)
46
- check(current == 237.5f)
47
- current = translation.update(current, firstOwner, 358f)
48
- check(current == 365.5f)
49
- current = translation.update(current, secondOwner, 64f)
50
- check(current == 429.5f)
51
- current = translation.update(current, firstOwner, null)
52
- check(current == 71.5f)
53
- check(!translation.isEmpty)
54
- current = translation.update(current, secondOwner, null)
55
- check(current == 7.5f)
56
- check(translation.isEmpty)
40
+ val alpha = NativeRefreshForegroundAlpha(0.75f)
41
+ check(alpha.isEmpty)
42
+ var current = alpha.update(0.75f, firstOwner, acquire = true)
43
+ check(current == 0f && alpha.drawingAlpha == 0.75f && !alpha.isEmpty)
44
+ current = alpha.update(current, firstOwner, acquire = true)
45
+ check(current == 0f && alpha.drawingAlpha == 0.75f)
46
+ current = alpha.update(current, secondOwner, acquire = true)
47
+ current = alpha.update(current, firstOwner, acquire = false)
48
+ check(current == 0f && !alpha.isEmpty)
49
+ current = alpha.update(current, secondOwner, acquire = false)
50
+ check(current == 0.75f && alpha.isEmpty)
57
51
 
58
- // Reversing release order must restore the same original translation.
59
- current = translation.update(current, firstOwner, 230f)
60
- current = translation.update(current, secondOwner, 64f)
61
- current = translation.update(current, secondOwner, null)
62
- check(current == 237.5f)
63
- current = translation.update(current, firstOwner, null)
64
- check(current == 7.5f)
65
- check(translation.isEmpty)
52
+ current = alpha.update(current, firstOwner, acquire = true)
53
+ current = alpha.update(current, secondOwner, acquire = true)
54
+ current = alpha.update(current, secondOwner, acquire = false)
55
+ check(current == 0f)
56
+ current = alpha.update(current, firstOwner, acquire = false)
57
+ check(current == 0.75f && alpha.isEmpty)
66
58
 
67
- // A caller's absolute translation update replaces the baseline, not its inset.
68
- current = translation.update(current, firstOwner, 230f)
69
- check(current == 237.5f)
70
- current = translation.update(-12.5f, firstOwner, 230f)
71
- check(current == 217.5f)
72
- current = translation.update(current, secondOwner, 64f)
73
- check(current == 281.5f)
74
- current = translation.update(current, firstOwner, null)
75
- check(current == 51.5f)
76
- current = translation.update(current, secondOwner, null)
77
- check(current == -12.5f)
78
- check(translation.isEmpty)
59
+ current = alpha.update(current, firstOwner, acquire = true)
60
+ current = alpha.update(0.4f, firstOwner, acquire = true)
61
+ check(current == 0f && alpha.drawingAlpha == 0.4f)
62
+ current = alpha.update(current, firstOwner, acquire = false)
63
+ check(current == 0.4f && alpha.isEmpty)
79
64
 
80
- // Zero is a real owned contribution; only null releases ownership.
81
- current = translation.update(current, firstOwner, 0f)
82
- check(current == -12.5f)
83
- check(!translation.isEmpty)
84
- current = translation.update(current, secondOwner, 0f)
85
- current = translation.update(current, firstOwner, null)
86
- check(current == -12.5f)
87
- check(!translation.isEmpty)
88
- current = translation.update(current, secondOwner, null)
89
- check(current == -12.5f)
90
- check(translation.isEmpty)
91
- current = translation.update(9f, firstOwner, null)
92
- check(current == 9f)
93
- check(translation.isEmpty)
94
- println("NativeScroller refresh translation: repeat, resize, nested release orders, external baseline, zero contribution, and final restoration passed")
65
+ val transparent = NativeRefreshForegroundAlpha(0f)
66
+ check(transparent.update(0f, firstOwner, acquire = true) == 0f)
67
+ check(!transparent.isEmpty && transparent.drawingAlpha == 0f)
68
+ check(transparent.update(0f, firstOwner, acquire = false) == 0f && transparent.isEmpty)
69
+ // RN caller offset is already in top; an absent coordinator inset is zero.
70
+ check(nativeRefreshForegroundTop(37, 0f) == 37f)
71
+ // A list publishes the sum of both actual ancestor insets; subtract it once.
72
+ check(nativeRefreshForegroundTop(37 + 230 + 64, 294f) == 37f)
73
+ check(nativeRefreshForegroundTop(-40 + 294, 294f) == -40f)
74
+ println("Refresh foreground policy: repeat, owner transfer/release, external alpha, transparent baseline, caller offset, and combined nested inset passed")
95
75
  }
@@ -0,0 +1,8 @@
1
+ #pragma once
2
+
3
+ #include <react/renderer/components/pagerview/RNCNativeScrollerShadowNode.h>
4
+ #include <react/renderer/core/ConcreteComponentDescriptor.h>
5
+
6
+ namespace facebook::react {
7
+ using RNCNativeScrollerComponentDescriptor = ConcreteComponentDescriptor<RNCNativeScrollerShadowNode>;
8
+ } // namespace facebook::react
@@ -0,0 +1,15 @@
1
+ #include <react/renderer/components/pagerview/RNCNativeScrollerShadowNode.h>
2
+
3
+ namespace facebook::react {
4
+
5
+ const char RNCNativeScrollerComponentName[] = "RNCNativeScroller";
6
+
7
+ Point RNCNativeScrollerShadowNode::getContentOriginOffset(bool includeTransform) const {
8
+ const auto state = getStateData();
9
+ const auto origin = state.contentOrigin;
10
+ const auto transform = includeTransform ? getTransform() : Transform::Identity();
11
+ const auto result = transform * Vector{origin.x, origin.y, 0.0f, 1.0f};
12
+ return {result.x + state.ancestorOffset.x, result.y + state.ancestorOffset.y};
13
+ }
14
+
15
+ } // namespace facebook::react
@@ -0,0 +1,23 @@
1
+ #pragma once
2
+
3
+ #include <jsi/jsi.h>
4
+ #include <react/renderer/components/pagerview/EventEmitters.h>
5
+ #include <react/renderer/components/pagerview/Props.h>
6
+ #include <react/renderer/components/pagerview/RNCNativeScrollerState.h>
7
+ #include <react/renderer/components/view/ConcreteViewShadowNode.h>
8
+
9
+ namespace facebook::react {
10
+
11
+ JSI_EXPORT extern const char RNCNativeScrollerComponentName[];
12
+
13
+ class JSI_EXPORT RNCNativeScrollerShadowNode final
14
+ : public ConcreteViewShadowNode<RNCNativeScrollerComponentName,
15
+ RNCNativeScrollerProps,
16
+ RNCNativeScrollerEventEmitter,
17
+ RNCNativeScrollerState> {
18
+ public:
19
+ using ConcreteViewShadowNode::ConcreteViewShadowNode;
20
+ Point getContentOriginOffset(bool includeTransform) const override;
21
+ };
22
+
23
+ } // namespace facebook::react
@@ -0,0 +1,33 @@
1
+ #pragma once
2
+
3
+ #include <react/renderer/graphics/Point.h>
4
+ #ifdef RN_SERIALIZABLE_STATE
5
+ #include <folly/dynamic.h>
6
+ #endif
7
+
8
+ namespace facebook::react {
9
+
10
+ // Local content displacement and ancestor translation have different transform spaces.
11
+ class RNCNativeScrollerState final {
12
+ public:
13
+ Point contentOrigin{};
14
+ Point ancestorOffset{};
15
+ RNCNativeScrollerState() = default;
16
+ explicit RNCNativeScrollerState(Point origin) : contentOrigin(origin) {}
17
+
18
+ #ifdef RN_SERIALIZABLE_STATE
19
+ RNCNativeScrollerState(const RNCNativeScrollerState &, folly::dynamic data)
20
+ : contentOrigin({static_cast<Float>(data["contentOriginX"].getDouble()),
21
+ static_cast<Float>(data["contentOriginY"].getDouble())}),
22
+ ancestorOffset({static_cast<Float>(data.getDefault("ancestorOffsetX", 0.0).getDouble()),
23
+ static_cast<Float>(data.getDefault("ancestorOffsetY", 0.0).getDouble())}) {}
24
+
25
+ folly::dynamic getDynamic() const {
26
+ return folly::dynamic::object("contentOriginX", contentOrigin.x)
27
+ ("contentOriginY", contentOrigin.y)
28
+ ("ancestorOffsetX", ancestorOffset.x)("ancestorOffsetY", ancestorOffset.y);
29
+ }
30
+ #endif
31
+ };
32
+
33
+ } // namespace facebook::react