@lodev09/react-native-true-sheet 4.0.0-beta.3 → 4.0.0-beta.30
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 +28 -5
- package/android/build.gradle +23 -1
- package/android/proguard-rules.pro +3 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +50 -16
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +303 -184
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentViewManager.kt +5 -1
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +38 -109
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetModule.kt +13 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetOverlayView.kt +127 -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 +29 -3
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +234 -66
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +491 -186
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +64 -10
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensEventObserver.kt +31 -14
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetBehavior.kt +135 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetBottomSheetView.kt +23 -23
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetCoordinatorLayout.kt +130 -6
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDetentCalculator.kt +104 -39
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetDimView.kt +14 -17
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetGrabberView.kt +2 -4
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetOverlayRootView.kt +148 -0
- package/android/src/main/java/com/lodev09/truesheet/core/TrueSheetStackManager.kt +33 -40
- package/android/src/main/java/com/lodev09/truesheet/events/TrueSheetLifecycleEvents.kt +15 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ColorUtils.kt +19 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/KeyboardUtils.kt +15 -2
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +0 -12
- package/android/src/main/java/com/lodev09/truesheet/utils/ViewUtils.kt +19 -7
- package/android/src/main/jni/TrueSheetSpec.h +1 -0
- package/android/src/main/jni/TrueSheetStateUpdater.cpp +37 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewComponentDescriptor.h +1 -9
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.cpp +114 -30
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewShadowNode.h +30 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.cpp +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetContentViewState.h +9 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.cpp +14 -3
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewShadowNode.h +5 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetFooterViewState.h +10 -6
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.cpp +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetInsets.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetLayoutUtils.h +43 -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 +33 -0
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.cpp +7 -40
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h +3 -7
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.cpp +3 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/TrueSheetViewState.h +4 -5
- package/ios/TrueSheetContainerView.h +23 -7
- package/ios/TrueSheetContainerView.mm +45 -25
- package/ios/TrueSheetContentView.h +44 -15
- package/ios/TrueSheetContentView.mm +221 -190
- package/ios/TrueSheetFooterView.mm +133 -28
- package/ios/TrueSheetModule.h +2 -7
- package/ios/TrueSheetModule.mm +18 -18
- package/ios/TrueSheetOverlayView.h +42 -0
- package/ios/TrueSheetOverlayView.mm +175 -0
- package/ios/TrueSheetView.h +2 -0
- package/ios/TrueSheetView.mm +268 -52
- package/ios/TrueSheetViewController.h +36 -3
- package/ios/TrueSheetViewController.mm +797 -102
- package/ios/core/RNScreensEventObserver.mm +31 -28
- package/ios/core/TrueSheetBlurView.h +0 -2
- package/ios/core/TrueSheetBlurView.mm +3 -36
- package/ios/core/TrueSheetDetentCalculator.h +18 -1
- package/ios/core/TrueSheetDetentCalculator.mm +44 -9
- package/ios/core/TrueSheetDimView.h +27 -0
- package/ios/core/TrueSheetDimView.mm +41 -0
- package/ios/core/TrueSheetGrabberView.mm +13 -3
- package/ios/core/TrueSheetKeyboardObserver.h +7 -0
- package/ios/core/TrueSheetKeyboardObserver.mm +107 -15
- 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 +222 -54
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/TrueSheet.web.js +364 -275
- package/lib/module/TrueSheet.web.js.map +1 -1
- package/lib/module/TrueSheetBackground.js +15 -0
- package/lib/module/TrueSheetBackground.js.map +1 -0
- 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 +20 -15
- package/lib/module/TrueSheetPeek.web.js.map +1 -1
- package/lib/module/TrueSheetProvider.web.js +13 -9
- package/lib/module/TrueSheetProvider.web.js.map +1 -1
- package/lib/module/detentBackgrounds.js +21 -0
- package/lib/module/detentBackgrounds.js.map +1 -0
- package/lib/module/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/lib/module/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/lib/module/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mocks/index.js +18 -2
- package/lib/module/mocks/index.js.map +1 -1
- package/lib/module/mocks/navigationExpoRouter.js.map +1 -1
- package/lib/module/navigation/base-types.js +2 -0
- package/lib/module/navigation/base-types.js.map +1 -0
- package/lib/module/navigation/createTrueSheetRouter.js +158 -100
- package/lib/module/navigation/createTrueSheetRouter.js.map +1 -1
- 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/extendTrueSheetRouter.js +71 -0
- package/lib/module/navigation/expo-router/extendTrueSheetRouter.js.map +1 -0
- package/lib/module/navigation/expo-router/index.js +18 -7
- package/lib/module/navigation/expo-router/index.js.map +1 -1
- 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.map +1 -1
- package/lib/module/navigation/screen/useSheetScreenState.js +1 -0
- package/lib/module/navigation/screen/useSheetScreenState.js.map +1 -1
- package/lib/module/scrollable.js +28 -0
- package/lib/module/scrollable.js.map +1 -0
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/keyboard.js +69 -0
- package/lib/module/web/keyboard.js.map +1 -0
- package/lib/module/web/layout.js +168 -0
- package/lib/module/web/layout.js.map +1 -0
- package/lib/module/web/vaul/constants.js +9 -0
- package/lib/module/web/vaul/constants.js.map +1 -1
- package/lib/module/web/vaul/context.js +4 -0
- package/lib/module/web/vaul/context.js.map +1 -1
- package/lib/module/web/vaul/helpers.js +1 -0
- package/lib/module/web/vaul/helpers.js.map +1 -1
- package/lib/module/web/vaul/index.js +83 -21
- package/lib/module/web/vaul/index.js.map +1 -1
- package/lib/module/web/vaul/use-snap-points.js +57 -28
- package/lib/module/web/vaul/use-snap-points.js.map +1 -1
- package/lib/typescript/src/TrueSheet.d.ts +18 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +209 -35
- 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/TrueSheetBackground.d.ts +3 -0
- package/lib/typescript/src/TrueSheetBackground.d.ts.map +1 -0
- 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 +8 -4
- package/lib/typescript/src/TrueSheetPeek.web.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts +5 -1
- package/lib/typescript/src/TrueSheetProvider.web.d.ts.map +1 -1
- package/lib/typescript/src/detentBackgrounds.d.ts +10 -0
- package/lib/typescript/src/detentBackgrounds.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.d.ts +2 -3
- package/lib/typescript/src/fabric/TrueSheetFooterViewNativeComponent.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 +76 -65
- 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/navigationExpoRouter.d.ts +3 -3
- package/lib/typescript/src/mocks/navigationExpoRouter.d.ts.map +1 -1
- 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 +36 -10
- package/lib/typescript/src/navigation/createTrueSheetRouter.d.ts.map +1 -1
- 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/extendTrueSheetRouter.d.ts +33 -0
- package/lib/typescript/src/navigation/expo-router/extendTrueSheetRouter.d.ts.map +1 -0
- package/lib/typescript/src/navigation/expo-router/index.d.ts +9 -6
- package/lib/typescript/src/navigation/expo-router/index.d.ts.map +1 -1
- 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 +3 -4
- package/lib/typescript/src/navigation/index.d.ts.map +1 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts +2 -1
- package/lib/typescript/src/navigation/screen/useSheetScreenState.d.ts.map +1 -1
- package/lib/typescript/src/navigation/types.d.ts +43 -6
- package/lib/typescript/src/navigation/types.d.ts.map +1 -1
- package/lib/typescript/src/scrollable.d.ts +2 -0
- package/lib/typescript/src/scrollable.d.ts.map +1 -0
- package/lib/typescript/src/web/constants.d.ts +1 -1
- package/lib/typescript/src/web/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/keyboard.d.ts +15 -0
- package/lib/typescript/src/web/keyboard.d.ts.map +1 -0
- package/lib/typescript/src/web/layout.d.ts +20 -0
- package/lib/typescript/src/web/layout.d.ts.map +1 -0
- package/lib/typescript/src/web/vaul/constants.d.ts +3 -0
- package/lib/typescript/src/web/vaul/constants.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/context.d.ts +5 -1
- package/lib/typescript/src/web/vaul/context.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/helpers.d.ts +1 -0
- package/lib/typescript/src/web/vaul/helpers.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/index.d.ts +20 -1
- package/lib/typescript/src/web/vaul/index.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/types.d.ts +9 -0
- package/lib/typescript/src/web/vaul/types.d.ts.map +1 -1
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts +6 -4
- package/lib/typescript/src/web/vaul/use-snap-points.d.ts.map +1 -1
- package/package.json +18 -8
- package/react-native.config.js +1 -0
- package/src/TrueSheet.tsx +257 -62
- package/src/TrueSheet.types.ts +225 -35
- package/src/TrueSheet.web.tsx +445 -333
- package/src/TrueSheetBackground.tsx +17 -0
- package/src/TrueSheetOverlay.tsx +24 -0
- package/src/TrueSheetOverlay.web.tsx +33 -0
- package/src/TrueSheetPeek.web.tsx +25 -23
- package/src/TrueSheetProvider.web.tsx +22 -13
- package/src/detentBackgrounds.ts +24 -0
- package/src/fabric/TrueSheetContentViewNativeComponent.ts +1 -1
- package/src/fabric/TrueSheetFooterViewNativeComponent.ts +2 -3
- package/src/fabric/TrueSheetOverlayViewNativeComponent.ts +12 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +89 -73
- package/src/index.ts +1 -0
- package/src/mocks/index.ts +17 -2
- package/src/mocks/navigationExpoRouter.ts +6 -5
- package/src/navigation/base-types.ts +20 -0
- package/src/navigation/createTrueSheetRouter.ts +220 -144
- package/src/navigation/expo-router/base-types.ts +18 -0
- package/src/navigation/expo-router/extendTrueSheetRouter.ts +99 -0
- package/src/navigation/expo-router/index.ts +41 -30
- package/src/navigation/expo-router/types.ts +116 -0
- package/src/navigation/index.ts +6 -7
- package/src/navigation/screen/useSheetScreenState.ts +2 -0
- package/src/navigation/types.ts +81 -23
- package/src/scrollable.ts +25 -0
- package/src/web/constants.ts +1 -1
- package/src/web/keyboard.ts +79 -0
- package/src/web/layout.ts +196 -0
- package/src/web/vaul/constants.ts +9 -0
- package/src/web/vaul/context.ts +7 -1
- package/src/web/vaul/helpers.ts +5 -0
- package/src/web/vaul/index.tsx +113 -16
- package/src/web/vaul/types.ts +10 -0
- package/src/web/vaul/use-snap-points.ts +86 -33
|
@@ -10,9 +10,11 @@ import android.view.ViewGroup
|
|
|
10
10
|
import android.widget.EditText
|
|
11
11
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
|
12
12
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
|
13
|
+
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
13
14
|
import com.facebook.react.uimanager.PointerEvents
|
|
14
15
|
import com.facebook.react.uimanager.ReactPointerEventsView
|
|
15
16
|
import com.facebook.react.uimanager.TouchTargetHelper
|
|
17
|
+
import com.lodev09.truesheet.utils.KeyboardUtils
|
|
16
18
|
import com.lodev09.truesheet.utils.isDescendantOf
|
|
17
19
|
|
|
18
20
|
interface TrueSheetCoordinatorLayoutDelegate {
|
|
@@ -20,6 +22,15 @@ interface TrueSheetCoordinatorLayoutDelegate {
|
|
|
20
22
|
fun coordinatorLayoutDidChangeConfiguration()
|
|
21
23
|
fun findScrollView(): ViewGroup?
|
|
22
24
|
fun findSheetView(): TrueSheetBottomSheetView?
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A downward pull the sheet couldn't follow ended; `overdragPx` is the travel it
|
|
28
|
+
* didn't follow, `keyboardWasVisible` whether the keyboard was up when it began.
|
|
29
|
+
*/
|
|
30
|
+
fun coordinatorLayoutDidPullDown(overdragPx: Int, keyboardWasVisible: Boolean)
|
|
31
|
+
|
|
32
|
+
// A touch that began inside the sheet ended, after the behavior handled the release
|
|
33
|
+
fun coordinatorLayoutDidEndTouch()
|
|
23
34
|
}
|
|
24
35
|
|
|
25
36
|
/**
|
|
@@ -57,13 +68,40 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
57
68
|
private var streamGestureClaimed = false
|
|
58
69
|
|
|
59
70
|
// Whether the sheet owns vertical drags for this stream: the touch target is inside
|
|
60
|
-
// the sheet but outside the
|
|
71
|
+
// the sheet but outside the detected scrollable (e.g. a header overlaying it), with
|
|
61
72
|
// nothing vertically scrollable along its chain. Such targets consume the stream
|
|
62
73
|
// natively (no nested scroll), and BottomSheetBehavior won't intercept because the
|
|
63
74
|
// scrollable's bounds still contain the point (touchingScrollingChild) — intercept
|
|
64
75
|
// manually.
|
|
65
76
|
private var streamSheetDraggable = false
|
|
66
77
|
private var streamDraggableEditText = false
|
|
78
|
+
private var streamScrollsIndependently = false
|
|
79
|
+
|
|
80
|
+
// Pull-down tracking. BottomSheetBehavior gives no callback when a downward drag
|
|
81
|
+
// is clamped by `isHideable = false` — the sheet stays put (or the scrollable
|
|
82
|
+
// overscrolls) and no state change fires. Accumulate the downward finger travel
|
|
83
|
+
// neither the sheet nor a scroller under the finger followed and report it on
|
|
84
|
+
// release so the controller can surface a blocked dismiss attempt. Like iOS, a
|
|
85
|
+
// pull that began on a scroller that could scroll up stays a scroll, even past
|
|
86
|
+
// its top.
|
|
87
|
+
private var pullTracking = false
|
|
88
|
+
private var pullStartX = 0f
|
|
89
|
+
private var pullStartY = 0f
|
|
90
|
+
private var pullLastY = 0f
|
|
91
|
+
private var pullOverdrag = 0f
|
|
92
|
+
private var pullKeyboardVisible = false
|
|
93
|
+
private var pullScrollers: List<View> = emptyList()
|
|
94
|
+
private var pullBeganScrolled = false
|
|
95
|
+
|
|
96
|
+
// A touch that began inside the sheet is still down
|
|
97
|
+
val isTouchingSheet: Boolean
|
|
98
|
+
get() = pullTracking
|
|
99
|
+
|
|
100
|
+
// Set while the sheet presents, from present() (keyboard wait included) until the
|
|
101
|
+
// present finishes or a dismiss starts. A stream that begins meanwhile is swallowed
|
|
102
|
+
// whole so nothing below takes it, like the iOS presentation transition.
|
|
103
|
+
var blocksTouches = false
|
|
104
|
+
private var streamBlocked = false
|
|
67
105
|
|
|
68
106
|
init {
|
|
69
107
|
layoutParams = LayoutParams(
|
|
@@ -94,6 +132,68 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
94
132
|
override val pointerEvents: PointerEvents
|
|
95
133
|
get() = PointerEvents.BOX_NONE
|
|
96
134
|
|
|
135
|
+
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
|
|
136
|
+
if (ev.actionMasked == MotionEvent.ACTION_DOWN) streamBlocked = blocksTouches
|
|
137
|
+
if (streamBlocked) {
|
|
138
|
+
if (ev.actionMasked == MotionEvent.ACTION_UP || ev.actionMasked == MotionEvent.ACTION_CANCEL) {
|
|
139
|
+
streamBlocked = false
|
|
140
|
+
}
|
|
141
|
+
return true
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
when (ev.actionMasked) {
|
|
145
|
+
MotionEvent.ACTION_DOWN -> {
|
|
146
|
+
val sheet = delegate?.findSheetView()
|
|
147
|
+
pullTracking = sheet != null && isTouchInside(sheet, ev)
|
|
148
|
+
pullStartX = ev.rawX
|
|
149
|
+
pullStartY = ev.rawY
|
|
150
|
+
pullLastY = ev.rawY
|
|
151
|
+
pullOverdrag = 0f
|
|
152
|
+
pullKeyboardVisible = pullTracking && KeyboardUtils.isKeyboardVisible(this)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
MotionEvent.ACTION_MOVE -> if (pullTracking) {
|
|
156
|
+
val sheet = delegate?.findSheetView()
|
|
157
|
+
val topBefore = sheet?.top
|
|
158
|
+
val handled = super.dispatchTouchEvent(ev)
|
|
159
|
+
val step = ev.rawY - pullLastY
|
|
160
|
+
pullLastY = ev.rawY
|
|
161
|
+
// Finger moved down but the sheet stayed put and nothing under the finger
|
|
162
|
+
// scrolled — the pull was clamped
|
|
163
|
+
if (!pullBeganScrolled &&
|
|
164
|
+
step > 0 &&
|
|
165
|
+
sheet != null &&
|
|
166
|
+
sheet.top == topBefore &&
|
|
167
|
+
pullScrollers.none { it.canScrollVertically(-1) }
|
|
168
|
+
) {
|
|
169
|
+
pullOverdrag += step
|
|
170
|
+
}
|
|
171
|
+
return handled
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
MotionEvent.ACTION_UP -> if (pullTracking) {
|
|
175
|
+
pullTracking = false
|
|
176
|
+
val dx = kotlin.math.abs(ev.rawX - pullStartX)
|
|
177
|
+
val dy = ev.rawY - pullStartY
|
|
178
|
+
// Let the behavior settle first so the controller sees the resting position.
|
|
179
|
+
val handled = super.dispatchTouchEvent(ev)
|
|
180
|
+
if (dy > dx && pullOverdrag > PULL_DOWN_THRESHOLD_DP.dpToPx()) {
|
|
181
|
+
delegate?.coordinatorLayoutDidPullDown(pullOverdrag.toInt(), pullKeyboardVisible)
|
|
182
|
+
}
|
|
183
|
+
delegate?.coordinatorLayoutDidEndTouch()
|
|
184
|
+
return handled
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
MotionEvent.ACTION_CANCEL -> if (pullTracking) {
|
|
188
|
+
pullTracking = false
|
|
189
|
+
val handled = super.dispatchTouchEvent(ev)
|
|
190
|
+
delegate?.coordinatorLayoutDidEndTouch()
|
|
191
|
+
return handled
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return super.dispatchTouchEvent(ev)
|
|
195
|
+
}
|
|
196
|
+
|
|
97
197
|
/**
|
|
98
198
|
* Clears stale `nestedScrollingChildRef` from BottomSheetBehavior.
|
|
99
199
|
*
|
|
@@ -127,19 +227,29 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
127
227
|
|
|
128
228
|
/**
|
|
129
229
|
* Resolves the stream's touch target (respecting zIndex and pointerEvents) and
|
|
130
|
-
* decides whether the sheet may drag from it — inside the sheet, outside the
|
|
131
|
-
* scrollable, and nothing along the target's chain scrolls vertically.
|
|
230
|
+
* decides whether the sheet may drag from it — inside the sheet, outside the detected
|
|
231
|
+
* scrollable, and nothing along the target's chain scrolls vertically. Also collects
|
|
232
|
+
* the chain's vertical scrollers for pull-down tracking.
|
|
132
233
|
*/
|
|
133
234
|
private fun updateStreamTargetFlags(ev: MotionEvent) {
|
|
134
235
|
streamSheetDraggable = false
|
|
135
236
|
streamDraggableEditText = false
|
|
237
|
+
streamScrollsIndependently = false
|
|
238
|
+
pullScrollers = emptyList()
|
|
239
|
+
pullBeganScrolled = false
|
|
136
240
|
|
|
137
241
|
val sheet = delegate?.findSheetView() ?: return
|
|
138
242
|
val target = TouchTargetHelper.findTargetPathAndCoordinatesForTouch(ev.x, ev.y, this, FloatArray(2))
|
|
139
243
|
.firstNotNullOfOrNull { it.getView() } ?: return
|
|
140
244
|
if (target !== sheet && !target.isDescendantOf(sheet)) return
|
|
141
245
|
|
|
142
|
-
|
|
246
|
+
pullScrollers = generateSequence(target) { it.parent as? View }
|
|
247
|
+
.takeWhile { it !== this }
|
|
248
|
+
.filter { it.canScrollVertically(1) || it.canScrollVertically(-1) }
|
|
249
|
+
.toList()
|
|
250
|
+
pullBeganScrolled = pullScrollers.any { it.canScrollVertically(-1) }
|
|
251
|
+
|
|
252
|
+
// A detected scrollable that can scroll (or hosts pull-to-refresh) owns its
|
|
143
253
|
// touches — nested scrolling drags the sheet. When it can't scroll (e.g.
|
|
144
254
|
// the sheet is fully expanded and the content fits) it eats the gesture
|
|
145
255
|
// instead, so fall through and let the sheet drag from it — an EditText
|
|
@@ -152,7 +262,10 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
152
262
|
|
|
153
263
|
var view: View? = target
|
|
154
264
|
while (view != null && view !== this) {
|
|
155
|
-
if (view.canScrollVertically(1) || view.canScrollVertically(-1))
|
|
265
|
+
if (view.canScrollVertically(1) || view.canScrollVertically(-1)) {
|
|
266
|
+
streamScrollsIndependently = !view.isNestedScrollingEnabled
|
|
267
|
+
return
|
|
268
|
+
}
|
|
156
269
|
view = view.parent as? View
|
|
157
270
|
}
|
|
158
271
|
|
|
@@ -160,6 +273,14 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
160
273
|
streamDraggableEditText = target is EditText
|
|
161
274
|
}
|
|
162
275
|
|
|
276
|
+
private fun isTouchInside(view: View, ev: MotionEvent): Boolean {
|
|
277
|
+
val loc = IntArray(2)
|
|
278
|
+
view.getLocationOnScreen(loc)
|
|
279
|
+
val x = ev.rawX.toInt()
|
|
280
|
+
val y = ev.rawY.toInt()
|
|
281
|
+
return x >= loc[0] && x <= loc[0] + view.width && y >= loc[1] && y <= loc[1] + view.height
|
|
282
|
+
}
|
|
283
|
+
|
|
163
284
|
private fun findDescendantViewAt(view: View, rawX: Int, rawY: Int, predicate: (View) -> Boolean): View? {
|
|
164
285
|
val loc = IntArray(2)
|
|
165
286
|
view.getLocationOnScreen(loc)
|
|
@@ -174,7 +295,7 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
174
295
|
}
|
|
175
296
|
|
|
176
297
|
/**
|
|
177
|
-
* Called by descendant RootView
|
|
298
|
+
* Called by the descendant RootView (controller) when a child
|
|
178
299
|
* starts a native gesture — e.g. an RNGH handler activated or a scrollable began
|
|
179
300
|
* scrolling. Yields sheet interception for the rest of the touch stream.
|
|
180
301
|
*/
|
|
@@ -226,6 +347,8 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
226
347
|
return false
|
|
227
348
|
}
|
|
228
349
|
|
|
350
|
+
if (streamScrollsIndependently) return false
|
|
351
|
+
|
|
229
352
|
if (streamGestureClaimed) {
|
|
230
353
|
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
|
|
231
354
|
streamGestureClaimed = false
|
|
@@ -299,5 +422,6 @@ class TrueSheetCoordinatorLayout(context: Context) :
|
|
|
299
422
|
companion object {
|
|
300
423
|
private const val GESTURE_HANDLER_ROOT_VIEW_CLASS = "com.swmansion.gesturehandler.react.RNGestureHandlerRootView"
|
|
301
424
|
private const val GESTURE_CLAIM_SLOP_FACTOR = 3
|
|
425
|
+
private const val PULL_DOWN_THRESHOLD_DP = 24f
|
|
302
426
|
}
|
|
303
427
|
}
|
|
@@ -18,11 +18,27 @@ interface TrueSheetDetentCalculatorDelegate {
|
|
|
18
18
|
val absoluteHeader: Boolean
|
|
19
19
|
val footerHeight: Int
|
|
20
20
|
val absoluteFooter: Boolean
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* True while the plugged scrollable is padded by the absolute footer's
|
|
24
|
+
* height (see ScrollableOptions.footerInsetAdjustment) — the footer then
|
|
25
|
+
* counts toward the auto detent like a relative one, so the content ends
|
|
26
|
+
* above it.
|
|
27
|
+
*/
|
|
28
|
+
val footerInsetAdjustment: Boolean
|
|
29
|
+
val footerAvoidsKeyboard: Boolean
|
|
21
30
|
val peekContentHeight: Int
|
|
22
31
|
val contentBottomInset: Int
|
|
23
32
|
val maxContentHeight: Int?
|
|
24
33
|
val keyboardInset: Int
|
|
25
34
|
val topInset: Int
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* True while the keyboard holds the sheet up: the collapsed stop then sits at
|
|
38
|
+
* the keyboard-free first detent (the "floor") so a drag-down dismisses the
|
|
39
|
+
* keyboard before it can dismiss the sheet.
|
|
40
|
+
*/
|
|
41
|
+
val hasKeyboardFloor: Boolean
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
/**
|
|
@@ -44,6 +60,15 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
44
60
|
private val maxContentHeight: Int? get() = delegate?.maxContentHeight
|
|
45
61
|
private val keyboardInset: Int get() = delegate?.keyboardInset ?: 0
|
|
46
62
|
private val topInset: Int get() = delegate?.topInset ?: 0
|
|
63
|
+
private val hasKeyboardFloor: Boolean get() = delegate?.hasKeyboardFloor == true
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* An absolute footer floats over the content and contributes no height to
|
|
67
|
+
* the auto detent — unless it pads the scrollable, then the content ends
|
|
68
|
+
* above it like a relative footer.
|
|
69
|
+
*/
|
|
70
|
+
private val footerInAuto: Boolean
|
|
71
|
+
get() = delegate?.absoluteFooter == false || delegate?.footerInsetAdjustment == true
|
|
47
72
|
|
|
48
73
|
/**
|
|
49
74
|
* Height for auto (-1.0) detents: content + header + footer height.
|
|
@@ -52,14 +77,14 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
52
77
|
private val autoDetentHeight: Int
|
|
53
78
|
get() = contentHeight +
|
|
54
79
|
(if (delegate?.absoluteHeader == true) 0 else headerHeight) +
|
|
55
|
-
(if (
|
|
80
|
+
(if (footerInAuto) footerHeight else 0)
|
|
56
81
|
|
|
57
82
|
/**
|
|
58
|
-
* Bottom inset for auto detents. A
|
|
59
|
-
* edge, so it absorbs the inset instead of adding it
|
|
83
|
+
* Bottom inset for auto detents. A footer counted in the auto height owns
|
|
84
|
+
* the sheet's bottom edge, so it absorbs the inset instead of adding it.
|
|
60
85
|
*/
|
|
61
86
|
private val autoDetentBottomInset: Int
|
|
62
|
-
get() = if (footerHeight > 0 &&
|
|
87
|
+
get() = if (footerHeight > 0 && footerInAuto) 0 else contentBottomInset
|
|
63
88
|
|
|
64
89
|
/**
|
|
65
90
|
* Bottom inset for peek detents. An absolute footer counts toward the peek
|
|
@@ -97,11 +122,37 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
97
122
|
(detent * screenHeight).toInt() + contentBottomInset
|
|
98
123
|
}
|
|
99
124
|
|
|
100
|
-
val
|
|
125
|
+
val keyboardHeight = if (includeKeyboard) keyboardInset else 0
|
|
126
|
+
val footerKeyboardOverlap = if (detent == -1.0 &&
|
|
127
|
+
delegate?.absoluteFooter == true &&
|
|
128
|
+
footerInAuto &&
|
|
129
|
+
delegate?.footerAvoidsKeyboard == false
|
|
130
|
+
) {
|
|
131
|
+
minOf(keyboardHeight, maxOf(0, footerHeight - contentBottomInset))
|
|
132
|
+
} else {
|
|
133
|
+
0
|
|
134
|
+
}
|
|
135
|
+
val height = baseHeight + keyboardHeight - footerKeyboardOverlap
|
|
101
136
|
val maxAllowedHeight = screenHeight + contentBottomInset
|
|
102
137
|
return maxContentHeight?.let { minOf(height, it, maxAllowedHeight) } ?: minOf(height, maxAllowedHeight)
|
|
103
138
|
}
|
|
104
139
|
|
|
140
|
+
fun getBackgroundIndex(sheetTop: Int, displayedIndex: Int): Int {
|
|
141
|
+
if (detents.isEmpty()) return -1
|
|
142
|
+
|
|
143
|
+
val height = getVisibleSheetHeight(sheetTop)
|
|
144
|
+
var nextIndex = displayedIndex.coerceIn(0, detents.size - 1)
|
|
145
|
+
var distance = kotlin.math.abs(height - getVisibleSheetHeight(getSheetTopForDetentIndex(nextIndex)))
|
|
146
|
+
for (index in detents.indices) {
|
|
147
|
+
val nextDistance = kotlin.math.abs(height - getVisibleSheetHeight(getSheetTopForDetentIndex(index)))
|
|
148
|
+
if (nextDistance < distance) {
|
|
149
|
+
nextIndex = index
|
|
150
|
+
distance = nextDistance
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return nextIndex
|
|
154
|
+
}
|
|
155
|
+
|
|
105
156
|
/**
|
|
106
157
|
* Get the expected sheet top position for a detent index.
|
|
107
158
|
*/
|
|
@@ -110,12 +161,31 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
110
161
|
RNLog.w(reactContext, "TrueSheet: Detent index ($index) is out of bounds (0..${detents.size - 1})")
|
|
111
162
|
return realScreenHeight
|
|
112
163
|
}
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
164
|
+
// With a keyboard floor only the last detent stays keyboard-shifted — it's
|
|
165
|
+
// the keyboard-expanded resting position; the stops below it are keyboard-free
|
|
166
|
+
val isKeyboardFreeStop = hasKeyboardFloor && index != detents.size - 1
|
|
167
|
+
return getSheetTop(detents[index], includeKeyboard = !isKeyboardFreeStop)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Top of the lowest stop the sheet can rest at: the keyboard floor while it's
|
|
172
|
+
* active, else the first detent.
|
|
173
|
+
*/
|
|
174
|
+
fun getLowestSheetTop(): Int = if (hasKeyboardFloor) getSheetTop(detents[0], includeKeyboard = false) else getSheetTopForDetentIndex(0)
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Top of the half stop while the keyboard floor is active: the keyboard-free
|
|
178
|
+
* second detent, or the floor itself for a single detent.
|
|
179
|
+
*/
|
|
180
|
+
fun getKeyboardHalfStopTop(): Int = getSheetTop(detents[minOf(1, detents.size - 1)], includeKeyboard = false)
|
|
181
|
+
|
|
182
|
+
// Clamp to the space the sheet can actually occupy — matching
|
|
183
|
+
// setupSheetDetents. A keyboard-inflated detent height can exceed it,
|
|
184
|
+
// placing the expected top above the screen while the real sheet stops
|
|
185
|
+
// at the top inset.
|
|
186
|
+
private fun getSheetTop(detent: Double, includeKeyboard: Boolean = true): Int {
|
|
117
187
|
val maxAvailableHeight = realScreenHeight - topInset
|
|
118
|
-
return realScreenHeight - minOf(getDetentHeight(
|
|
188
|
+
return realScreenHeight - minOf(getDetentHeight(detent, includeKeyboard), maxAvailableHeight)
|
|
119
189
|
}
|
|
120
190
|
|
|
121
191
|
/**
|
|
@@ -152,6 +222,9 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
152
222
|
*/
|
|
153
223
|
fun getStateForDetentIndex(index: Int): Int {
|
|
154
224
|
val stateMap = getDetentStateMap() ?: return BottomSheetBehavior.STATE_HIDDEN
|
|
225
|
+
// With a keyboard floor the keyboard-expanded last detent lives at the
|
|
226
|
+
// expanded stop — the half stop (which may share its index) is keyboard-free
|
|
227
|
+
if (hasKeyboardFloor && index == detents.size - 1) return BottomSheetBehavior.STATE_EXPANDED
|
|
155
228
|
return stateMap.entries.find { it.value == index }?.key ?: BottomSheetBehavior.STATE_HIDDEN
|
|
156
229
|
}
|
|
157
230
|
|
|
@@ -169,8 +242,12 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
169
242
|
*/
|
|
170
243
|
private fun getDetentStateMap(): Map<Int, Int>? =
|
|
171
244
|
when (detents.size) {
|
|
245
|
+
// With one detent halfExpandedRatio matches the peek height, so the
|
|
246
|
+
// behavior can settle HALF_EXPANDED at the same position (e.g. an upward
|
|
247
|
+
// drag release) — map it too, or the settle is unmappable
|
|
172
248
|
1 -> mapOf(
|
|
173
249
|
BottomSheetBehavior.STATE_COLLAPSED to 0,
|
|
250
|
+
BottomSheetBehavior.STATE_HALF_EXPANDED to 0,
|
|
174
251
|
BottomSheetBehavior.STATE_EXPANDED to 0
|
|
175
252
|
)
|
|
176
253
|
|
|
@@ -197,16 +274,18 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
197
274
|
* Find which segment the position falls into for interpolation.
|
|
198
275
|
* @return Triple(fromIndex, toIndex, progress) where progress is 0-1, or null if no detents
|
|
199
276
|
*/
|
|
200
|
-
fun findSegmentForPosition(positionPx: Int): Triple<Int, Int, Float>? {
|
|
277
|
+
private fun findSegmentForPosition(positionPx: Int): Triple<Int, Int, Float>? {
|
|
201
278
|
val count = detents.size
|
|
202
279
|
if (count == 0) return null
|
|
203
280
|
|
|
204
|
-
|
|
281
|
+
// A single keyboard-shifted detent can rest down at its keyboard floor —
|
|
282
|
+
// that range is still index 0, not a dismissal
|
|
283
|
+
val floorPos = getLowestSheetTop()
|
|
205
284
|
|
|
206
|
-
// Position is below
|
|
207
|
-
if (positionPx >
|
|
208
|
-
val range = realScreenHeight -
|
|
209
|
-
val progress = if (range > 0) (positionPx -
|
|
285
|
+
// Position is below the lowest stop (sheet is being dragged down to dismiss)
|
|
286
|
+
if (positionPx > floorPos) {
|
|
287
|
+
val range = realScreenHeight - floorPos
|
|
288
|
+
val progress = if (range > 0) (positionPx - floorPos).toFloat() / range else 0f
|
|
210
289
|
return Triple(-1, 0, progress)
|
|
211
290
|
}
|
|
212
291
|
|
|
@@ -238,37 +317,23 @@ class TrueSheetDetentCalculator(private val reactContext: ThemedReactContext) {
|
|
|
238
317
|
}
|
|
239
318
|
|
|
240
319
|
/**
|
|
241
|
-
* Returns continuous index (e.g., 0.5 = halfway between detent
|
|
320
|
+
* Returns interpolated continuous index (e.g., 0.5 = halfway between detent
|
|
321
|
+
* 0 and 1) and screen fraction for a position, sharing a single segment
|
|
322
|
+
* lookup — this runs on every position frame.
|
|
242
323
|
*/
|
|
243
|
-
fun
|
|
244
|
-
|
|
245
|
-
if (count == 0) return -1f
|
|
246
|
-
|
|
247
|
-
val segment = findSegmentForPosition(positionPx) ?: return 0f
|
|
248
|
-
val (fromIndex, _, progress) = segment
|
|
249
|
-
|
|
250
|
-
if (fromIndex == -1) return -progress
|
|
251
|
-
return fromIndex + progress
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Returns interpolated screen fraction for position.
|
|
256
|
-
*/
|
|
257
|
-
fun getInterpolatedDetentForPosition(positionPx: Int): Float {
|
|
258
|
-
val count = detents.size
|
|
259
|
-
if (count == 0) return 0f
|
|
324
|
+
fun getInterpolatedPositionInfo(positionPx: Int): Pair<Float, Float> {
|
|
325
|
+
if (detents.isEmpty()) return Pair(-1f, 0f)
|
|
260
326
|
|
|
261
|
-
val
|
|
262
|
-
|
|
327
|
+
val (fromIndex, toIndex, progress) = findSegmentForPosition(positionPx)
|
|
328
|
+
?: return Pair(0f, getDetentValueForIndex(0))
|
|
263
329
|
|
|
264
330
|
if (fromIndex == -1) {
|
|
265
|
-
|
|
266
|
-
return maxOf(0f, firstDetent * (1 - progress))
|
|
331
|
+
return Pair(-progress, maxOf(0f, getDetentValueForIndex(0) * (1 - progress)))
|
|
267
332
|
}
|
|
268
333
|
|
|
269
334
|
val fromDetent = getDetentValueForIndex(fromIndex)
|
|
270
335
|
val toDetent = getDetentValueForIndex(toIndex)
|
|
271
|
-
return fromDetent + progress * (toDetent - fromDetent)
|
|
336
|
+
return Pair(fromIndex + progress, fromDetent + progress * (toDetent - fromDetent))
|
|
272
337
|
}
|
|
273
338
|
|
|
274
339
|
companion object {
|
|
@@ -34,10 +34,6 @@ class TrueSheetDimView(private val reactContext: ThemedReactContext) :
|
|
|
34
34
|
View(reactContext),
|
|
35
35
|
ReactPointerEventsView {
|
|
36
36
|
|
|
37
|
-
companion object {
|
|
38
|
-
private const val MAX_ALPHA = 0.5f
|
|
39
|
-
}
|
|
40
|
-
|
|
41
37
|
var delegate: TrueSheetDimViewDelegate? = null
|
|
42
38
|
|
|
43
39
|
private var targetView: ViewGroup? = null
|
|
@@ -48,6 +44,10 @@ class TrueSheetDimView(private val reactContext: ThemedReactContext) :
|
|
|
48
44
|
private val blockGestures: Boolean
|
|
49
45
|
get() = alpha > 0f
|
|
50
46
|
|
|
47
|
+
fun setDimColor(color: Int) {
|
|
48
|
+
setBackgroundColor(color)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
51
|
init {
|
|
52
52
|
layoutParams = ViewGroup.LayoutParams(
|
|
53
53
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
@@ -109,36 +109,33 @@ class TrueSheetDimView(private val reactContext: ThemedReactContext) :
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
// =============================================================================
|
|
112
|
-
// MARK: -
|
|
112
|
+
// MARK: - Progress Calculation
|
|
113
113
|
// =============================================================================
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
/**
|
|
116
|
+
* How far the sheet is into its dimmed range, from 0 (undimmed) to 1 (fully dimmed).
|
|
117
|
+
*/
|
|
118
|
+
fun calculateProgress(sheetTop: Int, dimmedDetentIndex: Int, getSheetTopForDetentIndex: (Int) -> Int): Float {
|
|
116
119
|
val realHeight = ScreenUtils.getRealScreenHeight(reactContext)
|
|
117
120
|
val dimmedDetentTop = getSheetTopForDetentIndex(dimmedDetentIndex)
|
|
118
121
|
val belowDimmedTop = if (dimmedDetentIndex > 0) getSheetTopForDetentIndex(dimmedDetentIndex - 1) else realHeight
|
|
119
122
|
|
|
120
123
|
return when {
|
|
121
|
-
sheetTop <= dimmedDetentTop ->
|
|
122
|
-
|
|
124
|
+
sheetTop <= dimmedDetentTop -> 1f
|
|
123
125
|
sheetTop >= belowDimmedTop -> 0f
|
|
124
|
-
|
|
125
|
-
else -> {
|
|
126
|
-
val progress = 1f - (sheetTop - dimmedDetentTop).toFloat() / (belowDimmedTop - dimmedDetentTop)
|
|
127
|
-
(progress * MAX_ALPHA).coerceIn(0f, MAX_ALPHA)
|
|
128
|
-
}
|
|
126
|
+
else -> (1f - (sheetTop - dimmedDetentTop).toFloat() / (belowDimmedTop - dimmedDetentTop)).coerceIn(0f, 1f)
|
|
129
127
|
}
|
|
130
128
|
}
|
|
131
129
|
|
|
132
|
-
fun interpolateAlpha(sheetTop: Int, dimmedDetentIndex: Int, getSheetTopForDetentIndex: (Int) -> Int) {
|
|
133
|
-
alpha = calculateAlpha(sheetTop, dimmedDetentIndex, getSheetTopForDetentIndex)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
130
|
// =============================================================================
|
|
137
131
|
// MARK: - Touch Handling
|
|
138
132
|
// =============================================================================
|
|
139
133
|
|
|
140
134
|
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
141
135
|
if (blockGestures) {
|
|
136
|
+
if (event.actionMasked == MotionEvent.ACTION_DOWN) {
|
|
137
|
+
parent?.requestDisallowInterceptTouchEvent(true)
|
|
138
|
+
}
|
|
142
139
|
// When dimmed, consume touch and trigger click on ACTION_UP
|
|
143
140
|
if (event.action == MotionEvent.ACTION_UP) {
|
|
144
141
|
performClick()
|
|
@@ -2,7 +2,6 @@ package com.lodev09.truesheet.core
|
|
|
2
2
|
|
|
3
3
|
import android.annotation.SuppressLint
|
|
4
4
|
import android.content.Context
|
|
5
|
-
import android.content.res.Configuration
|
|
6
5
|
import android.graphics.Color
|
|
7
6
|
import android.graphics.drawable.GradientDrawable
|
|
8
7
|
import android.os.Bundle
|
|
@@ -13,6 +12,7 @@ import android.widget.FrameLayout
|
|
|
13
12
|
import androidx.core.graphics.ColorUtils
|
|
14
13
|
import androidx.core.view.ViewCompat
|
|
15
14
|
import com.facebook.react.uimanager.PixelUtil.dpToPx
|
|
15
|
+
import com.lodev09.truesheet.utils.isDarkMode
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Options for customizing the grabber appearance.
|
|
@@ -165,9 +165,7 @@ class TrueSheetGrabberView(
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
private fun getAdaptiveColor(baseColor: Int? = null): Int {
|
|
168
|
-
val
|
|
169
|
-
val isDarkMode = nightMode == Configuration.UI_MODE_NIGHT_YES
|
|
170
|
-
val modeColor = if (isDarkMode) Color.WHITE else Color.BLACK
|
|
168
|
+
val modeColor = if (context.isDarkMode) Color.WHITE else Color.BLACK
|
|
171
169
|
|
|
172
170
|
return if (baseColor != null) {
|
|
173
171
|
// Blend user color with mode color for adaptive effect
|