@lodev09/react-native-true-sheet 3.11.0-beta.11 → 3.11.0-beta.12

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.
@@ -192,6 +192,11 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
192
192
  private val jsTouchDispatcher = JSTouchDispatcher(this)
193
193
  private val jsPointerDispatcher = JSPointerDispatcher(this)
194
194
 
195
+ // True when the active touch stream began inside the footer. Latched on
196
+ // ACTION_DOWN so subsequent MOVE events keep routing to the footer even if
197
+ // the finger drifts outside the footer's rect mid-gesture.
198
+ private var footerOwnsTouchStream = false
199
+
195
200
  private val eventDispatcher
196
201
  get() = delegate?.eventDispatcher
197
202
 
@@ -1291,26 +1296,36 @@ class TrueSheetViewController(private val reactContext: ThemedReactContext) :
1291
1296
 
1292
1297
  override fun dispatchTouchEvent(event: MotionEvent): Boolean {
1293
1298
  val footer = containerView?.footerView
1299
+ val action = event.actionMasked
1300
+
1294
1301
  if (footer != null && footer.isShown) {
1295
- val footerLocation = ScreenUtils.getScreenLocation(footer)
1296
- val touchX = event.rawX.toInt()
1297
- val touchY = event.rawY.toInt()
1298
-
1299
- if (touchX >= footerLocation[0] &&
1300
- touchX <= footerLocation[0] + footer.width &&
1301
- touchY >= footerLocation[1] &&
1302
- touchY <= footerLocation[1] + footer.height
1303
- ) {
1302
+ if (action == MotionEvent.ACTION_DOWN) {
1303
+ val loc = ScreenUtils.getScreenLocation(footer)
1304
+ val x = event.rawX.toInt()
1305
+ val y = event.rawY.toInt()
1306
+ footerOwnsTouchStream = x >= loc[0] &&
1307
+ x <= loc[0] + footer.width &&
1308
+ y >= loc[1] &&
1309
+ y <= loc[1] + footer.height
1310
+ }
1311
+
1312
+ if (footerOwnsTouchStream) {
1313
+ val loc = ScreenUtils.getScreenLocation(footer)
1304
1314
  val localEvent = MotionEvent.obtain(event)
1305
- localEvent.setLocation(
1306
- (touchX - footerLocation[0]).toFloat(),
1307
- (touchY - footerLocation[1]).toFloat()
1308
- )
1315
+ localEvent.setLocation(event.rawX - loc[0], event.rawY - loc[1])
1309
1316
  val handled = footer.dispatchTouchEvent(localEvent)
1310
1317
  localEvent.recycle()
1318
+
1319
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
1320
+ footerOwnsTouchStream = false
1321
+ }
1311
1322
  if (handled) return true
1312
1323
  }
1313
1324
  }
1325
+
1326
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
1327
+ footerOwnsTouchStream = false
1328
+ }
1314
1329
  return super.dispatchTouchEvent(event)
1315
1330
  }
1316
1331
 
@@ -36,6 +36,14 @@ class TrueSheetCoordinatorLayout(context: Context) :
36
36
  private var initialY = 0f
37
37
  private var activePointerId = 0
38
38
 
39
+ // Horizontal-dominance tracking. iOS lets horizontal child gestures win over
40
+ // the sheet's vertical pan; we mirror that by locking out BottomSheetBehavior
41
+ // interception once the first significant movement of a stream is horizontal.
42
+ private var streamInitialX = 0f
43
+ private var streamInitialY = 0f
44
+ private var streamHorizontalLocked = false
45
+ private var streamDirectionDecided = false
46
+
39
47
  init {
40
48
  layoutParams = LayoutParams(
41
49
  LayoutParams.MATCH_PARENT,
@@ -94,8 +102,35 @@ class TrueSheetCoordinatorLayout(context: Context) :
94
102
  * See: https://github.com/facebook/react-native/pull/44099
95
103
  */
96
104
  override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
97
- if (ev.actionMasked == MotionEvent.ACTION_DOWN) {
105
+ val action = ev.actionMasked
106
+
107
+ if (action == MotionEvent.ACTION_DOWN) {
98
108
  clearStaleNestedScrollingChildRef()
109
+
110
+ streamInitialX = ev.rawX
111
+ streamInitialY = ev.rawY
112
+ streamHorizontalLocked = false
113
+ streamDirectionDecided = false
114
+ }
115
+
116
+ // Decide gesture direction on first significant movement of the stream.
117
+ // If horizontal wins, lock out BottomSheetBehavior for the rest of the stream
118
+ // so child handlers (carousels, swipe buttons, etc.) can claim the touch.
119
+ if (!streamDirectionDecided && action == MotionEvent.ACTION_MOVE) {
120
+ val dx = kotlin.math.abs(ev.rawX - streamInitialX)
121
+ val dy = kotlin.math.abs(ev.rawY - streamInitialY)
122
+ if (dx > touchSlop || dy > touchSlop) {
123
+ streamDirectionDecided = true
124
+ streamHorizontalLocked = dx > dy
125
+ }
126
+ }
127
+
128
+ if (streamHorizontalLocked) {
129
+ if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
130
+ streamHorizontalLocked = false
131
+ streamDirectionDecided = false
132
+ }
133
+ return false
99
134
  }
100
135
 
101
136
  val scrollView = delegate?.findScrollView()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-true-sheet",
3
- "version": "3.11.0-beta.11",
3
+ "version": "3.11.0-beta.12",
4
4
  "description": "The true native bottom sheet experience for your React Native Apps.",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",