@lodev09/react-native-true-sheet 4.0.0-beta.1 → 4.0.0-beta.10
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 +25 -4
- package/android/build.gradle +22 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +24 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +211 -182
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +14 -19
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +106 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayViewManager.kt +45 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetStateUpdater.kt +18 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +82 -39
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +275 -88
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +26 -1
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +75 -3
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +56 -34
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +137 -0
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +1 -1
- package/android/src/main/java/com/lodev09/truesheet/utils/TouchEventDeduper.kt +31 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +0 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +54 -29
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +6 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +6 -4
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +7 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +46 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewComponentDescriptor.h +21 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.cpp +17 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetOverlayViewShadowNode.h +36 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +4 -35
- package/ios/TrueSheetContainerView.h +14 -7
- package/ios/TrueSheetContainerView.mm +10 -7
- package/ios/TrueSheetContentView.h +31 -15
- package/ios/TrueSheetContentView.mm +133 -179
- package/ios/TrueSheetFooterView.h +6 -0
- package/ios/TrueSheetFooterView.mm +48 -2
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +7 -16
- package/ios/TrueSheetOverlayView.h +32 -0
- package/ios/TrueSheetOverlayView.mm +161 -0
- package/ios/TrueSheetView.mm +171 -29
- package/ios/TrueSheetViewController.h +10 -0
- package/ios/TrueSheetViewController.mm +256 -74
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetOverlayContainerView.h +31 -0
- package/ios/core/TrueSheetOverlayContainerView.mm +35 -0
- package/ios/events/TrueSheetLifecycleEvents.h +2 -0
- package/ios/events/TrueSheetLifecycleEvents.mm +8 -0
- package/ios/tvos/TrueSheetStubs.mm +12 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.h +1 -0
- package/ios/utils/UIView+ScrollEdgeInteraction.mm +24 -2
- package/lib/module/TrueSheet.js +149 -34
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +122 -53
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetOverlay.js +30 -0
- package/lib/module/TrueSheetOverlay.js.map +1 -0
- package/lib/module/TrueSheetOverlay.web.js +35 -0
- package/lib/module/TrueSheetOverlay.web.js.map +1 -0
- package/lib/module/TrueSheetPeek.web.js +3 -3
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +10 -0
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigation.js +31 -21
- package/lib/module/mocks/navigation.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js +21 -0
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -0
- package/lib/module/mocks/reanimated.js +1 -1
- package/lib/module/mocks/reanimated.js.map +1 -1
- package/lib/module/navigation/{TrueSheetView.js → TrueSheetNavigatorContent.js} +14 -12
- package/lib/module/navigation/TrueSheetNavigatorContent.js.map +1 -0
- package/lib/module/navigation/actions.js +50 -0
- package/lib/module/navigation/actions.js.map +1 -0
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/{TrueSheetRouter.js → createTrueSheetRouter.js} +11 -24
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/base-types.js +2 -0
- package/lib/module/navigation/expo-router/base-types.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +50 -0
- package/lib/module/navigation/expo-router/index.js.map +1 -0
- package/lib/module/navigation/expo-router/types.js +4 -0
- package/lib/module/navigation/expo-router/types.js.map +1 -0
- package/lib/module/navigation/index.js +43 -2
- package/lib/module/navigation/index.js.map +1 -1
- package/lib/module/navigation/navigator.js +10 -0
- package/lib/module/navigation/navigator.js.map +1 -0
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/ReanimatedTrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/TrueSheetScreen.js +2 -2
- package/lib/module/navigation/screen/TrueSheetScreen.js.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +5 -4
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js +1 -1
- package/lib/module/navigation/useTrueSheetNavigation.js.map +1 -1
- package/lib/module/web/dom.js +10 -0
- package/lib/module/web/dom.js.map +1 -0
- package/lib/module/web/vaul/constants.js +4 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +10 -4
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +35 -2
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +6 -0
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +72 -1
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetOverlay.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts +8 -0
- package/lib/typescript/src/TrueSheetOverlay.web.d.ts.map +1 -0
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetOverlayViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts +4 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/index.d.ts +4 -0
- package/lib/typescript/src/mocks/index.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigation.d.ts +5 -1
- package/lib/typescript/src/mocks/navigation.d.ts.map +1 -1
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts +22 -0
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -0
- package/lib/typescript/src/mocks/reanimated.d.ts.map +1 -1
- package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts +5 -0
- package/lib/typescript/src/navigation/TrueSheetNavigatorContent.d.ts.map +1 -0
- package/lib/typescript/src/navigation/actions.d.ts +71 -0
- package/lib/typescript/src/navigation/actions.d.ts.map +1 -0
- package/lib/typescript/src/navigation/base-types.d.ts +9 -0
- package/lib/typescript/src/navigation/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts +3 -0
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts +8 -0
- package/lib/typescript/src/navigation/expo-router/base-types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +37 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts +44 -0
- package/lib/typescript/src/navigation/expo-router/types.d.ts.map +1 -0
- package/lib/typescript/src/navigation/index.d.ts +42 -3
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/navigator.d.ts +7 -0
- package/lib/typescript/src/navigation/navigator.d.ts.map +1 -0
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts +1 -1
- package/lib/typescript/src/navigation/screen/ReanimatedTrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts +1 -1
- package/lib/typescript/src/navigation/screen/TrueSheetScreen.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/types.d.ts +3 -4
- package/lib/typescript/src/navigation/screen/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +5 -6
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +65 -5
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts +1 -1
- package/lib/typescript/src/navigation/useTrueSheetNavigation.d.ts.map +1 -1
- package/lib/typescript/src/web/dom.d.ts +7 -0
- package/lib/typescript/src/web/dom.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +1 -0
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +7 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/package.json +32 -9
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +184 -46
- package/src/TrueSheet.types.ts +77 -1
- package/src/TrueSheet.web.tsx +135 -64
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +4 -3
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +5 -0
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +7 -0
- package/src/mocks/navigation.ts +32 -25
- package/src/mocks/navigationExpoRouter.ts +41 -0
- package/src/mocks/reanimated.ts +8 -9
- package/src/navigation/{TrueSheetView.tsx → TrueSheetNavigatorContent.tsx} +24 -17
- package/src/navigation/actions.ts +78 -0
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +194 -0
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/index.ts +90 -0
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +68 -2
- package/src/navigation/navigator.ts +18 -0
- package/src/navigation/screen/ReanimatedTrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/TrueSheetScreen.tsx +2 -2
- package/src/navigation/screen/types.ts +4 -6
- package/src/navigation/screen/useSheetScreenState.ts +10 -15
- package/src/navigation/types.ts +99 -16
- package/src/navigation/useTrueSheetNavigation.ts +1 -1
- package/src/web/dom.ts +9 -0
- package/src/web/vaul/constants.ts +4 -0
- package/src/web/vaul/context.ts +1 -0
- package/src/web/vaul/helpers.ts +13 -6
- package/src/web/vaul/index.tsx +46 -1
- package/lib/module/navigation/TrueSheetRouter.js.map +0 -1
- package/lib/module/navigation/TrueSheetView.js.map +0 -1
- package/lib/module/navigation/createTrueSheetNavigator.js +0 -63
- package/lib/module/navigation/createTrueSheetNavigator.js.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts +0 -57
- package/lib/typescript/src/navigation/TrueSheetRouter.d.ts.map +0 -1
- package/lib/typescript/src/navigation/TrueSheetView.d.ts +0 -10
- package/lib/typescript/src/navigation/TrueSheetView.d.ts.map +0 -1
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts +0 -35
- package/lib/typescript/src/navigation/createTrueSheetNavigator.d.ts.map +0 -1
- package/src/navigation/TrueSheetRouter.ts +0 -234
- package/src/navigation/createTrueSheetNavigator.tsx +0 -93
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
package com.lodev09.truesheet
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
|
+
import android.os.Build
|
|
4
5
|
import android.text.Editable
|
|
5
6
|
import android.text.TextWatcher
|
|
6
7
|
import android.view.View
|
|
7
8
|
import android.view.ViewGroup
|
|
9
|
+
import android.view.ViewTreeObserver
|
|
8
10
|
import android.widget.EditText
|
|
9
|
-
import android.widget.ScrollView
|
|
10
|
-
import androidx.core.widget.NestedScrollView
|
|
11
11
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
12
|
-
import com.facebook.react.bridge.WritableNativeMap
|
|
13
12
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
14
|
-
import com.facebook.react.uimanager.StateWrapper
|
|
15
13
|
import com.facebook.react.uimanager.ThemedReactContext
|
|
16
14
|
import com.facebook.react.views.view.ReactViewGroup
|
|
17
15
|
import com.lodev09.truesheet.core.TrueSheetKeyboardObserver
|
|
18
16
|
import com.lodev09.truesheet.core.TrueSheetKeyboardObserverDelegate
|
|
19
17
|
import com.lodev09.truesheet.utils.isDescendantOf
|
|
20
|
-
import com.lodev09.truesheet.utils.smoothScrollBy
|
|
21
18
|
import com.lodev09.truesheet.utils.smoothScrollTo
|
|
22
19
|
|
|
23
|
-
data class ScrollableOptions(
|
|
20
|
+
data class ScrollableOptions(
|
|
21
|
+
val keyboardScrollOffset: Float = 0f,
|
|
22
|
+
val keyboardOffset: Float = 0f,
|
|
23
|
+
val scrollingExpandsSheet: Boolean = true,
|
|
24
|
+
val contentInsetAdjustment: Boolean = true
|
|
25
|
+
)
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* Delegate interface for content view size changes
|
|
@@ -32,10 +34,19 @@ interface TrueSheetContentViewDelegate {
|
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* Keyboard occlusion adjustment below the content — positive for an absolute
|
|
35
|
-
* footer
|
|
36
|
-
* negative for a relative footer sitting behind the keyboard shielding
|
|
37
|
+
* footer floating over the viewport's bottom edge (extends the caret reveal),
|
|
38
|
+
* negative for a relative footer sitting behind the keyboard shielding that
|
|
39
|
+
* much of its overlap (reduces the keyboard padding).
|
|
37
40
|
*/
|
|
38
41
|
val footerKeyboardOcclusion: Int
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* A relative footer sits below the content and absorbs the bottom safe-area
|
|
45
|
+
* inset — the scrollable doesn't reach the sheet's bottom edge, so no
|
|
46
|
+
* content inset is applied (mirrors iOS, where UIKit resolves this
|
|
47
|
+
* geometrically via the scroll view's safe area).
|
|
48
|
+
*/
|
|
49
|
+
val hasRelativeFooter: Boolean
|
|
39
50
|
}
|
|
40
51
|
|
|
41
52
|
/**
|
|
@@ -45,44 +56,42 @@ interface TrueSheetContentViewDelegate {
|
|
|
45
56
|
@SuppressLint("ViewConstructor")
|
|
46
57
|
class TrueSheetContentView(private val reactContext: ThemedReactContext) : ReactViewGroup(reactContext) {
|
|
47
58
|
var delegate: TrueSheetContentViewDelegate? = null
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
private var lastWidth = 0
|
|
51
|
-
private var lastHeight = 0
|
|
52
|
-
|
|
53
|
-
private var pinnedScrollView: ViewGroup? = null
|
|
54
|
-
private var observedScrollChild: View? = null
|
|
55
|
-
private var originalScrollViewPaddingBottom: Int = 0
|
|
56
|
-
private var bottomInset: Int = 0
|
|
57
|
-
private var scrollableBounded = false
|
|
58
|
-
private var isReportPending = false
|
|
59
|
-
|
|
60
|
-
// Content growth is invisible to layout once the viewport is bounded, so track
|
|
61
|
-
// the scroll content size directly to keep the auto detent height in sync.
|
|
62
|
-
private val scrollChildLayoutListener =
|
|
63
|
-
View.OnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
|
|
64
|
-
if (bottom - top != oldBottom - oldTop) {
|
|
65
|
-
reportSizeIfChanged()
|
|
66
|
-
}
|
|
67
|
-
}
|
|
59
|
+
|
|
60
|
+
private var detectedScrollView: ViewGroup? = null
|
|
68
61
|
|
|
69
62
|
/**
|
|
70
|
-
* Content height
|
|
71
|
-
*
|
|
72
|
-
* Falls back to the view height
|
|
63
|
+
* Content height measured unconstrained by the shadow node — the height the
|
|
64
|
+
* content wants regardless of container bounds (see
|
|
65
|
+
* TrueSheetContentViewShadowNode). Falls back to the view height before the
|
|
66
|
+
* first state update.
|
|
73
67
|
*/
|
|
74
68
|
val naturalHeight: Int
|
|
75
|
-
get()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
69
|
+
get() = if (lastNaturalHeight > 0) lastNaturalHeight else height
|
|
70
|
+
|
|
71
|
+
private var lastNaturalHeight = 0
|
|
72
|
+
|
|
73
|
+
fun updateNaturalHeight(heightDp: Double) {
|
|
74
|
+
val heightPx = heightDp.toFloat().dpToPx().toInt()
|
|
75
|
+
if (heightPx == lastNaturalHeight) return
|
|
76
|
+
lastNaturalHeight = heightPx
|
|
77
|
+
delegate?.contentViewDidChangeSize(width, heightPx)
|
|
78
|
+
}
|
|
84
79
|
|
|
85
80
|
private var keyboardScrollOffset: Float = 0f
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Adjustment added to the keyboard bottom inset applied to the detected
|
|
84
|
+
* scrollable — negative values reduce the inset (e.g. to cancel out safe-area
|
|
85
|
+
* padding already baked into the content's paddingBottom).
|
|
86
|
+
*/
|
|
87
|
+
private var keyboardOffset: Float = 0f
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* How much of keyboardOffset actually landed in the applied inset — the
|
|
91
|
+
* caret reveal compensates by this so it still targets the real keyboard edge.
|
|
92
|
+
*/
|
|
93
|
+
private var appliedKeyboardOffset = 0
|
|
94
|
+
|
|
86
95
|
private var keyboardObserver: TrueSheetKeyboardObserver? = null
|
|
87
96
|
|
|
88
97
|
private var watchedEditText: EditText? = null
|
|
@@ -92,125 +101,103 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
92
101
|
set(value) {
|
|
93
102
|
field = value
|
|
94
103
|
keyboardScrollOffset = value?.keyboardScrollOffset?.dpToPx() ?: 0f
|
|
104
|
+
keyboardOffset = value?.keyboardOffset?.dpToPx() ?: 0f
|
|
105
|
+
updateContentInset()
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
109
|
+
* Bottom safe-area inset applied to the scrollable's content padding while
|
|
110
|
+
* the content can scroll — Android counterpart of iOS's
|
|
111
|
+
* `contentInsetAdjustmentBehavior="automatic"`. Already zero when the
|
|
112
|
+
* sheet's `insetAdjustment` is `'never'`.
|
|
101
113
|
*/
|
|
102
|
-
var
|
|
114
|
+
var bottomInset: Int = 0
|
|
103
115
|
set(value) {
|
|
104
116
|
if (field == value) return
|
|
105
117
|
field = value
|
|
106
|
-
|
|
107
|
-
setScrollableBounded(value)
|
|
108
|
-
}
|
|
118
|
+
updateContentInset()
|
|
109
119
|
}
|
|
110
120
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
121
|
+
private var baseBottomInset = 0
|
|
122
|
+
private var keyboardBottomInset = 0
|
|
123
|
+
|
|
124
|
+
private val scrollableLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
|
|
125
|
+
updateContentInset()
|
|
126
|
+
clampScrollPosition()
|
|
114
127
|
}
|
|
115
128
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
checkScrollViewChanged()
|
|
129
|
+
private val scrollContentLayoutListener = View.OnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
|
130
|
+
updateContentInset()
|
|
119
131
|
}
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
133
|
+
override fun onAttachedToWindow() {
|
|
134
|
+
super.onAttachedToWindow()
|
|
135
|
+
viewTreeObserver.addOnGlobalLayoutListener(scrollableLayoutListener)
|
|
125
136
|
}
|
|
126
137
|
|
|
127
|
-
override fun
|
|
128
|
-
|
|
129
|
-
|
|
138
|
+
override fun onDetachedFromWindow() {
|
|
139
|
+
viewTreeObserver.removeOnGlobalLayoutListener(scrollableLayoutListener)
|
|
140
|
+
super.onDetachedFromWindow()
|
|
130
141
|
}
|
|
131
142
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
post {
|
|
142
|
-
isReportPending = false
|
|
143
|
-
reportSizeNow()
|
|
144
|
-
}
|
|
145
|
-
return
|
|
143
|
+
/**
|
|
144
|
+
* React tag of the user-provided scrollable (see the `scrollableRef` prop).
|
|
145
|
+
* Setting a new handle clears the currently resolved ScrollView.
|
|
146
|
+
*/
|
|
147
|
+
var scrollableHandle: Int = -1
|
|
148
|
+
set(value) {
|
|
149
|
+
if (field == value) return
|
|
150
|
+
field = value
|
|
151
|
+
clearScrollable()
|
|
146
152
|
}
|
|
147
153
|
|
|
148
|
-
|
|
154
|
+
override fun addView(child: View?, index: Int) {
|
|
155
|
+
super.addView(child, index)
|
|
156
|
+
checkScrollViewChanged()
|
|
149
157
|
}
|
|
150
158
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
lastWidth = width
|
|
155
|
-
lastHeight = newHeight
|
|
156
|
-
delegate?.contentViewDidChangeSize(width, newHeight)
|
|
157
|
-
}
|
|
159
|
+
override fun removeViewAt(index: Int) {
|
|
160
|
+
super.removeViewAt(index)
|
|
161
|
+
checkScrollViewChanged()
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
* for auto detents — otherwise content lays out naturally like a regular view.
|
|
164
|
-
*/
|
|
165
|
-
private fun setScrollableBounded(bounded: Boolean) {
|
|
166
|
-
if (scrollableBounded == bounded) return
|
|
167
|
-
scrollableBounded = bounded
|
|
168
|
-
|
|
169
|
-
stateWrapper?.let {
|
|
170
|
-
val newState = WritableNativeMap()
|
|
171
|
-
newState.putBoolean("scrollableBounded", bounded)
|
|
172
|
-
it.updateState(newState)
|
|
164
|
+
private fun checkScrollViewChanged() {
|
|
165
|
+
if (detectedScrollView == null || detectedScrollView?.isDescendantOf(this) == false) {
|
|
166
|
+
delegate?.contentViewScrollViewDidChange()
|
|
173
167
|
}
|
|
174
168
|
}
|
|
175
169
|
|
|
176
|
-
fun setupScrollable(
|
|
177
|
-
// Check if
|
|
178
|
-
if (
|
|
170
|
+
fun setupScrollable() {
|
|
171
|
+
// Check if the detected scroll view is still valid (still in view hierarchy)
|
|
172
|
+
if (detectedScrollView != null && detectedScrollView?.isDescendantOf(this) == false) {
|
|
179
173
|
clearScrollable()
|
|
180
174
|
}
|
|
181
175
|
|
|
182
|
-
|
|
183
|
-
if (pinnedScrollView != null && this.bottomInset == bottomInset) {
|
|
176
|
+
if (detectedScrollView != null) {
|
|
184
177
|
return
|
|
185
178
|
}
|
|
186
179
|
|
|
187
|
-
val scrollView = findScrollView(
|
|
180
|
+
val scrollView = findScrollView() ?: return
|
|
188
181
|
|
|
189
|
-
|
|
190
|
-
if (pinnedScrollView == null) {
|
|
191
|
-
originalScrollViewPaddingBottom = scrollView.paddingBottom
|
|
192
|
-
pinnedScrollView = scrollView
|
|
182
|
+
detectedScrollView = scrollView
|
|
193
183
|
|
|
194
|
-
|
|
195
|
-
|
|
184
|
+
scrollView.isNestedScrollingEnabled = true
|
|
185
|
+
(scrollView.parent as? SwipeRefreshLayout)?.isNestedScrollingEnabled = false
|
|
196
186
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
}
|
|
187
|
+
scrollView.setOnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
|
188
|
+
if (scrollY != oldScrollY) {
|
|
189
|
+
delegate?.contentViewDidScroll()
|
|
201
190
|
}
|
|
202
|
-
|
|
203
|
-
scrollView.getChildAt(0)?.let { child ->
|
|
204
|
-
observedScrollChild = child
|
|
205
|
-
child.addOnLayoutChangeListener(scrollChildLayoutListener)
|
|
206
|
-
}
|
|
207
|
-
setScrollableBounded(hasAutoDetent)
|
|
208
|
-
reportSizeIfChanged()
|
|
209
191
|
}
|
|
210
192
|
|
|
211
|
-
|
|
193
|
+
// Restore the inset before ReactScrollView's listener clamps the offset.
|
|
194
|
+
scrollView.getChildAt(0)?.let { child ->
|
|
195
|
+
if (scrollView is View.OnLayoutChangeListener) child.removeOnLayoutChangeListener(scrollView)
|
|
196
|
+
child.addOnLayoutChangeListener(scrollContentLayoutListener)
|
|
197
|
+
if (scrollView is View.OnLayoutChangeListener) child.addOnLayoutChangeListener(scrollView)
|
|
198
|
+
}
|
|
212
199
|
|
|
213
|
-
|
|
200
|
+
updateContentInset()
|
|
214
201
|
|
|
215
202
|
// If keyboard is currently showing, re-apply the keyboard inset to the new ScrollView
|
|
216
203
|
val keyboardHeight = keyboardObserver?.currentHeight ?: 0
|
|
@@ -219,51 +206,64 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
219
206
|
}
|
|
220
207
|
}
|
|
221
208
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
209
|
+
/**
|
|
210
|
+
* Re-applies the base content inset — the bottom safe-area inset while the
|
|
211
|
+
* content can scroll, no relative footer absorbs it, and
|
|
212
|
+
* `contentInsetAdjustmentBehavior` isn't disabled.
|
|
213
|
+
*/
|
|
214
|
+
fun updateContentInset() {
|
|
215
|
+
val scrollView = detectedScrollView ?: return
|
|
216
|
+
|
|
217
|
+
val enabled = scrollableOptions?.contentInsetAdjustment ?: true
|
|
218
|
+
baseBottomInset = if (enabled && delegate?.hasRelativeFooter != true && canScrollContent(scrollView)) {
|
|
219
|
+
bottomInset
|
|
220
|
+
} else {
|
|
221
|
+
0
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
applyBottomInset()
|
|
231
225
|
}
|
|
232
226
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
setScrollViewPaddingBottom(originalScrollViewPaddingBottom)
|
|
238
|
-
observedScrollChild?.removeOnLayoutChangeListener(scrollChildLayoutListener)
|
|
239
|
-
observedScrollChild = null
|
|
240
|
-
setScrollableBounded(false)
|
|
241
|
-
pinnedScrollView = null
|
|
242
|
-
originalScrollViewPaddingBottom = 0
|
|
243
|
-
bottomInset = 0
|
|
244
|
-
reportSizeIfChanged()
|
|
227
|
+
// Fabric's measured height excludes the native inset, avoiding feedback.
|
|
228
|
+
private fun canScrollContent(scrollView: ViewGroup): Boolean {
|
|
229
|
+
val child = scrollView.getChildAt(0) ?: return false
|
|
230
|
+
return child.measuredHeight > scrollView.height - scrollView.paddingTop - scrollView.paddingBottom
|
|
245
231
|
}
|
|
246
232
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
233
|
+
// The keyboard covers the safe-area region, so the larger inset wins over a sum
|
|
234
|
+
private fun applyBottomInset() {
|
|
235
|
+
setScrollContentInset(maxOf(baseBottomInset, keyboardBottomInset))
|
|
250
236
|
}
|
|
251
237
|
|
|
252
|
-
private fun
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
238
|
+
private fun setScrollContentInset(inset: Int) {
|
|
239
|
+
val scrollView = detectedScrollView ?: return
|
|
240
|
+
val child = scrollView.getChildAt(0) ?: return
|
|
241
|
+
scrollView.clipToPadding = false
|
|
242
|
+
// ScrollView's canScrollVertically ignores bottom padding. Extend the
|
|
243
|
+
// content bounds instead, keeping Fabric's measured height as the baseline.
|
|
244
|
+
child.bottom = child.top + child.measuredHeight + inset
|
|
245
|
+
}
|
|
256
246
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
247
|
+
fun clearScrollable() {
|
|
248
|
+
detectedScrollView?.setOnScrollChangeListener(null as View.OnScrollChangeListener?)
|
|
249
|
+
detectedScrollView?.getChildAt(0)?.removeOnLayoutChangeListener(scrollContentLayoutListener)
|
|
250
|
+
detectedScrollView?.isNestedScrollingEnabled = false
|
|
251
|
+
(detectedScrollView?.parent as? SwipeRefreshLayout)?.isNestedScrollingEnabled = true
|
|
252
|
+
setScrollContentInset(0)
|
|
253
|
+
detectedScrollView = null
|
|
254
|
+
baseBottomInset = 0
|
|
255
|
+
keyboardBottomInset = 0
|
|
256
|
+
appliedKeyboardOffset = 0
|
|
257
|
+
}
|
|
265
258
|
|
|
266
|
-
|
|
259
|
+
/**
|
|
260
|
+
* Resolves the user-provided `scrollableHandle` within the content subtree —
|
|
261
|
+
* React tags are view ids on Android.
|
|
262
|
+
*/
|
|
263
|
+
fun findScrollView(): ViewGroup? {
|
|
264
|
+
if (detectedScrollView != null) return detectedScrollView
|
|
265
|
+
if (scrollableHandle <= 0) return null
|
|
266
|
+
return findViewById<View>(scrollableHandle) as? ViewGroup
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
// ==================== Keyboard Handling ====================
|
|
@@ -273,8 +273,19 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
273
273
|
|
|
274
274
|
keyboardObserver = TrueSheetKeyboardObserver(this, reactContext).apply {
|
|
275
275
|
delegate = object : TrueSheetKeyboardObserverDelegate {
|
|
276
|
-
|
|
276
|
+
// Drive the inset per keyboard animation frame so the content tracks
|
|
277
|
+
// the keyboard edge instead of jumping to the final inset up front.
|
|
278
|
+
// On hide, the shrinking inset gradually clamps the scroll position
|
|
279
|
+
// back in sync with the keyboard.
|
|
280
|
+
override fun keyboardDidChangeHeight(height: Int) {
|
|
277
281
|
updateScrollViewInsetForKeyboard(height)
|
|
282
|
+
|
|
283
|
+
// Follow the caret frame-by-frame — only API 30+ delivers
|
|
284
|
+
// incremental heights; legacy fires once after the keyboard is
|
|
285
|
+
// already up, where keyboardDidShow's smooth reveal takes over
|
|
286
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !isHiding) {
|
|
287
|
+
scrollToFocusedInput(smooth = false)
|
|
288
|
+
}
|
|
278
289
|
}
|
|
279
290
|
|
|
280
291
|
override fun keyboardDidShow(height: Int) {
|
|
@@ -284,7 +295,6 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
284
295
|
|
|
285
296
|
override fun keyboardWillHide() {
|
|
286
297
|
detachCaretListener()
|
|
287
|
-
updateScrollViewInsetForKeyboard(0)
|
|
288
298
|
}
|
|
289
299
|
|
|
290
300
|
override fun focusDidChange(newFocus: View) {
|
|
@@ -329,30 +339,37 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
329
339
|
}
|
|
330
340
|
|
|
331
341
|
private fun updateScrollViewInsetForKeyboard(keyboardHeight: Int) {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
//
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
342
|
+
// A relative footer stays behind the keyboard below the content, so its
|
|
343
|
+
// height shields that much of the keyboard's overlap. An absolute footer
|
|
344
|
+
// floats within the viewport — its clearance is the content padding's job
|
|
345
|
+
// (the caret reveal accounts for it, see scrollToFocusedInput).
|
|
346
|
+
keyboardBottomInset = if (keyboardHeight > 0) {
|
|
347
|
+
val baseInset = maxOf(0, keyboardHeight + minOf(0, delegate?.footerKeyboardOcclusion ?: 0))
|
|
348
|
+
val adjustedInset = maxOf(0, baseInset + keyboardOffset.toInt())
|
|
349
|
+
appliedKeyboardOffset = adjustedInset - baseInset
|
|
350
|
+
adjustedInset
|
|
340
351
|
} else {
|
|
341
|
-
|
|
352
|
+
appliedKeyboardOffset = 0
|
|
353
|
+
0
|
|
342
354
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
scrollView.post { nudgeScrollView() }
|
|
355
|
+
applyBottomInset()
|
|
356
|
+
clampScrollPosition()
|
|
346
357
|
}
|
|
347
358
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
359
|
+
// Content bounds changes don't re-clamp the scroll position until the next layout
|
|
360
|
+
// pass — clamp synchronously so the content follows the shrinking inset on
|
|
361
|
+
// every keyboard frame instead of snapping afterwards
|
|
362
|
+
private fun clampScrollPosition() {
|
|
363
|
+
val scrollView = detectedScrollView ?: return
|
|
364
|
+
val child = scrollView.getChildAt(0) ?: return
|
|
365
|
+
val maxScrollY = maxOf(0, child.height - (scrollView.height - scrollView.paddingTop - scrollView.paddingBottom))
|
|
366
|
+
if (scrollView.scrollY > maxScrollY) {
|
|
367
|
+
scrollView.scrollTo(scrollView.scrollX, maxScrollY)
|
|
368
|
+
}
|
|
352
369
|
}
|
|
353
370
|
|
|
354
|
-
private fun scrollToFocusedInput() {
|
|
355
|
-
val scrollView =
|
|
371
|
+
private fun scrollToFocusedInput(smooth: Boolean = true) {
|
|
372
|
+
val scrollView = detectedScrollView ?: findScrollView() ?: return
|
|
356
373
|
val focusedView = findFocus() ?: return
|
|
357
374
|
|
|
358
375
|
val focusedLocation = IntArray(2)
|
|
@@ -379,17 +396,29 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
|
|
|
379
396
|
caretBottom = viewTop + focusedView.height
|
|
380
397
|
}
|
|
381
398
|
|
|
399
|
+
// An absolute footer floats over the viewport's bottom edge — extend the
|
|
400
|
+
// caret target so it clears the footer, not just the keyboard.
|
|
401
|
+
val footerOcclusion = maxOf(0, delegate?.footerKeyboardOcclusion ?: 0)
|
|
402
|
+
|
|
382
403
|
val offset = keyboardScrollOffset.toInt()
|
|
383
|
-
val visibleHeight = scrollView.height - scrollView.paddingBottom
|
|
404
|
+
val visibleHeight = scrollView.height - scrollView.paddingBottom - maxOf(baseBottomInset, keyboardBottomInset) + appliedKeyboardOffset
|
|
384
405
|
val visibleTop = scrollView.scrollY
|
|
385
406
|
val visibleBottom = scrollView.scrollY + visibleHeight
|
|
386
407
|
|
|
387
|
-
when {
|
|
388
|
-
caretBottom + offset > visibleBottom ->
|
|
389
|
-
|
|
408
|
+
val targetY = when {
|
|
409
|
+
caretBottom + offset + footerOcclusion > visibleBottom ->
|
|
410
|
+
caretBottom + offset + footerOcclusion - visibleHeight
|
|
390
411
|
|
|
391
412
|
caretTop - offset < visibleTop ->
|
|
392
|
-
|
|
413
|
+
(caretTop - offset).coerceAtLeast(0)
|
|
414
|
+
|
|
415
|
+
else -> return
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (smooth) {
|
|
419
|
+
scrollView.smoothScrollTo(0, targetY)
|
|
420
|
+
} else {
|
|
421
|
+
scrollView.scrollTo(0, targetY)
|
|
393
422
|
}
|
|
394
423
|
}
|
|
395
424
|
|
|
@@ -20,7 +20,11 @@ class TrueSheetContentViewManager : ViewGroupManager<TrueSheetContentView>() {
|
|
|
20
20
|
override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetContentView = TrueSheetContentView(reactContext)
|
|
21
21
|
|
|
22
22
|
override fun updateState(view: TrueSheetContentView, props: ReactStylesDiffMap?, stateWrapper: StateWrapper?): Any? {
|
|
23
|
-
|
|
23
|
+
stateWrapper?.stateData?.let { data ->
|
|
24
|
+
if (data.hasKey("naturalHeight")) {
|
|
25
|
+
view.updateNaturalHeight(data.getDouble("naturalHeight"))
|
|
26
|
+
}
|
|
27
|
+
}
|
|
24
28
|
return null
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -15,6 +15,7 @@ import com.facebook.react.uimanager.ThemedReactContext
|
|
|
15
15
|
import com.facebook.react.uimanager.events.EventDispatcher
|
|
16
16
|
import com.facebook.react.views.view.ReactViewGroup
|
|
17
17
|
import com.lodev09.truesheet.core.TrueSheetCoordinatorLayout
|
|
18
|
+
import com.lodev09.truesheet.utils.TouchEventDeduper
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Delegate interface for footer view size changes and event dispatching
|
|
@@ -44,25 +45,17 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
44
45
|
|
|
45
46
|
private var lastWidth = 0
|
|
46
47
|
private var lastHeight = 0
|
|
47
|
-
private var bottomInset = 0
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
* above the keyboard, so the inset would leave a gap.
|
|
52
|
-
*/
|
|
53
|
-
var keyboardVisible = false
|
|
54
|
-
set(value) {
|
|
55
|
-
if (field == value) return
|
|
56
|
-
field = value
|
|
57
|
-
pushBottomInsetState()
|
|
58
|
-
}
|
|
49
|
+
var bottomInset = 0
|
|
50
|
+
private set
|
|
59
51
|
|
|
60
52
|
/**
|
|
61
53
|
* Height the footer occupies above the keyboard — its layout height minus
|
|
62
|
-
* the safe-area inset
|
|
54
|
+
* the safe-area inset, which rides below the keyboard's top edge while the
|
|
55
|
+
* keyboard is open (see positionFooter).
|
|
63
56
|
*/
|
|
64
57
|
val keyboardOcclusionHeight: Int
|
|
65
|
-
get() = maxOf(0, height -
|
|
58
|
+
get() = maxOf(0, height - bottomInset)
|
|
66
59
|
|
|
67
60
|
/**
|
|
68
61
|
* Tells the shadow node to pad the footer's bottom edge with the sheet's
|
|
@@ -72,12 +65,9 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
72
65
|
fun setBottomInset(inset: Int) {
|
|
73
66
|
if (bottomInset == inset) return
|
|
74
67
|
bottomInset = inset
|
|
75
|
-
pushBottomInsetState()
|
|
76
|
-
}
|
|
77
68
|
|
|
78
|
-
private fun pushBottomInsetState() {
|
|
79
69
|
val sw = stateWrapper ?: return
|
|
80
|
-
val insetDp =
|
|
70
|
+
val insetDp = bottomInset.toFloat().pxToDp()
|
|
81
71
|
|
|
82
72
|
// Synchronous update — the footer must be padded before detents are
|
|
83
73
|
// configured, otherwise the auto detent is set up an inset short
|
|
@@ -91,6 +81,7 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
91
81
|
|
|
92
82
|
private val jsTouchDispatcher = JSTouchDispatcher(this)
|
|
93
83
|
private var jsPointerDispatcher: JSPointerDispatcher? = null
|
|
84
|
+
private val touchDeduper = TouchEventDeduper()
|
|
94
85
|
|
|
95
86
|
init {
|
|
96
87
|
jsPointerDispatcher = JSPointerDispatcher(this)
|
|
@@ -110,7 +101,9 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
110
101
|
|
|
111
102
|
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
|
112
103
|
eventDispatcher?.let { dispatcher ->
|
|
113
|
-
|
|
104
|
+
if (touchDeduper.shouldDispatch(event)) {
|
|
105
|
+
jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
|
|
106
|
+
}
|
|
114
107
|
jsPointerDispatcher?.handleMotionEvent(event, dispatcher, true)
|
|
115
108
|
}
|
|
116
109
|
return super.onInterceptTouchEvent(event)
|
|
@@ -128,7 +121,9 @@ class TrueSheetFooterView(private val reactContext: ThemedReactContext) :
|
|
|
128
121
|
}
|
|
129
122
|
|
|
130
123
|
eventDispatcher?.let { dispatcher ->
|
|
131
|
-
|
|
124
|
+
if (touchDeduper.shouldDispatch(event)) {
|
|
125
|
+
jsTouchDispatcher.handleTouchEvent(event, dispatcher, reactContext)
|
|
126
|
+
}
|
|
132
127
|
jsPointerDispatcher?.handleMotionEvent(event, dispatcher, false)
|
|
133
128
|
}
|
|
134
129
|
super.onTouchEvent(event)
|