@lodev09/react-native-true-sheet 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +2 -5
  2. package/android/build.gradle +1 -0
  3. package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +2 -7
  4. package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +233 -0
  5. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +42 -10
  6. package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewModule.kt +63 -0
  7. package/android/src/main/java/com/lodev09/truesheet/core/Events.kt +43 -0
  8. package/android/src/main/java/com/lodev09/truesheet/core/RootViewGroup.kt +136 -0
  9. package/android/src/main/java/com/lodev09/truesheet/core/SheetBehavior.kt +198 -0
  10. package/android/src/main/java/com/lodev09/truesheet/utils/maxSize.kt +49 -0
  11. package/android/src/main/java/com/lodev09/truesheet/utils/toDIP.kt +5 -0
  12. package/android/src/main/java/com/lodev09/truesheet/utils/withPromise.kt +13 -0
  13. package/ios/Extensions/UIViewController+detentForSize.swift +22 -13
  14. package/ios/TrueSheetView.swift +3 -3
  15. package/ios/TrueSheetViewManager.m +1 -1
  16. package/lib/commonjs/TrueSheet.js +12 -5
  17. package/lib/commonjs/TrueSheet.js.map +1 -1
  18. package/lib/commonjs/TrueSheetModule.js +3 -1
  19. package/lib/commonjs/TrueSheetModule.js.map +1 -1
  20. package/lib/module/TrueSheet.js +12 -5
  21. package/lib/module/TrueSheet.js.map +1 -1
  22. package/lib/module/TrueSheetModule.js +3 -1
  23. package/lib/module/TrueSheetModule.js.map +1 -1
  24. package/lib/typescript/src/TrueSheet.d.ts +1 -1
  25. package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
  26. package/lib/typescript/src/TrueSheetModule.d.ts.map +1 -1
  27. package/lib/typescript/src/types.d.ts +4 -3
  28. package/lib/typescript/src/types.d.ts.map +1 -1
  29. package/package.json +5 -2
  30. package/src/TrueSheet.tsx +21 -10
  31. package/src/TrueSheetModule.ts +3 -2
  32. package/src/types.ts +4 -3
package/README.md CHANGED
@@ -11,6 +11,7 @@ The true native bottom sheet.
11
11
  * ✅ **_NOT_** your pure JS, (re)animated View.
12
12
  * ✅ Clean, fast and lightweight.
13
13
  * ✅ Handles your Sscrolling needs, easy.
14
+ * ✅ Asynchronus `ref` methods.
14
15
 
15
16
  ## Installation
16
17
 
@@ -34,7 +35,7 @@ const openSheet = () => {
34
35
  return (
35
36
  <View>
36
37
  <Button onPress={openSheet} title="Open Sheet" />
37
- <TrueSheet ref={sheet}>
38
+ <TrueSheet sizes={['auto', 'large']} ref={sheet}>
38
39
  // ...
39
40
  </TrueSheet>
40
41
  </View>
@@ -51,7 +52,3 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
51
52
  ## License
52
53
 
53
54
  MIT
54
-
55
- ---
56
-
57
- Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
@@ -90,5 +90,6 @@ dependencies {
90
90
  //noinspection GradleDynamicVersion
91
91
  implementation "com.facebook.react:react-native:+"
92
92
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
93
+ implementation "com.google.android.material:material:1.11.0"
93
94
  }
94
95
 
@@ -5,13 +5,8 @@ import com.facebook.react.bridge.NativeModule
5
5
  import com.facebook.react.bridge.ReactApplicationContext
6
6
  import com.facebook.react.uimanager.ViewManager
7
7
 
8
-
9
8
  class TrueSheetPackage : ReactPackage {
10
- override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
11
- return emptyList()
12
- }
9
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> = listOf(TrueSheetViewModule(reactContext))
13
10
 
14
- override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
15
- return listOf(TrueSheetViewManager())
16
- }
11
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> = listOf(TrueSheetViewManager())
17
12
  }
@@ -0,0 +1,233 @@
1
+ package com.lodev09.truesheet
2
+
3
+ import android.content.Context
4
+ import android.view.View
5
+ import android.view.ViewGroup
6
+ import android.view.ViewStructure
7
+ import android.view.accessibility.AccessibilityEvent
8
+ import android.widget.LinearLayout
9
+ import androidx.coordinatorlayout.widget.CoordinatorLayout
10
+ import com.facebook.react.bridge.LifecycleEventListener
11
+ import com.facebook.react.bridge.UiThreadUtil
12
+ import com.facebook.react.uimanager.ThemedReactContext
13
+ import com.facebook.react.uimanager.UIManagerHelper
14
+ import com.facebook.react.uimanager.events.EventDispatcher
15
+ import com.google.android.material.bottomsheet.BottomSheetBehavior
16
+ import com.google.android.material.bottomsheet.BottomSheetDialog
17
+ import com.lodev09.truesheet.core.DismissEvent
18
+ import com.lodev09.truesheet.core.PresentEvent
19
+ import com.lodev09.truesheet.core.RootViewGroup
20
+ import com.lodev09.truesheet.core.SheetBehavior
21
+ import com.lodev09.truesheet.core.SizeChangeEvent
22
+ import com.lodev09.truesheet.utils.maxSize
23
+
24
+ class TrueSheetView(context: Context) :
25
+ ViewGroup(context),
26
+ LifecycleEventListener {
27
+ private var eventDispatcher: EventDispatcher? = null
28
+
29
+ private val reactContext: ThemedReactContext
30
+ get() = context as ThemedReactContext
31
+
32
+ private val surfaceId: Int
33
+ get() = UIManagerHelper.getSurfaceId(this)
34
+
35
+ private var sizeIndex: Int = 0
36
+ private var sizes: Array<Any> = arrayOf("medium", "large")
37
+
38
+ private var presentPromise: (() -> Unit)? = null
39
+ private var dismissPromise: (() -> Unit)? = null
40
+
41
+ private val sheetDialog: BottomSheetDialog
42
+ private val sheetLayout: LinearLayout
43
+ private val sheetRootView: RootViewGroup
44
+
45
+ // 1st child of the container view
46
+ private var contentView: ViewGroup? = null
47
+
48
+ // 2nd child of the container view
49
+ private var footerView: ViewGroup? = null
50
+
51
+ private var sheetBehavior: SheetBehavior<ViewGroup>
52
+
53
+ init {
54
+ reactContext.addLifecycleEventListener(this)
55
+ eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, id)
56
+
57
+ sheetRootView = RootViewGroup(context)
58
+ sheetRootView.eventDispatcher = eventDispatcher
59
+
60
+ sheetDialog = BottomSheetDialog(context)
61
+ sheetBehavior = SheetBehavior()
62
+ sheetLayout = LinearLayout(context)
63
+
64
+ // Configure Sheet events
65
+ sheetBehavior.apply {
66
+ maxSize = maxSize(context)
67
+
68
+ addBottomSheetCallback(
69
+ object : BottomSheetBehavior.BottomSheetCallback() {
70
+ override fun onSlide(sheetView: View, slideOffset: Float) {
71
+ footerView?.let {
72
+ it.y = (sheetView.height - sheetView.top - it.height).toFloat()
73
+ }
74
+ }
75
+
76
+ override fun onStateChanged(view: View, newState: Int) {
77
+ val sizeInfo = getSizeInfoForState(sizes.size, newState)
78
+ if (sizeInfo != null && sizeInfo.index != sizeIndex) {
79
+ sizeIndex = sizeInfo.index
80
+
81
+ // dispatch onSizeChange event
82
+ eventDispatcher?.dispatchEvent(SizeChangeEvent(surfaceId, id, sizeInfo))
83
+ }
84
+
85
+ when (newState) {
86
+ BottomSheetBehavior.STATE_HIDDEN -> sheetDialog.dismiss()
87
+ else -> {}
88
+ }
89
+ }
90
+ }
91
+ )
92
+ }
93
+
94
+ // Configure the sheet layout
95
+ sheetLayout.apply {
96
+ addView(sheetRootView)
97
+ sheetDialog.setContentView(this)
98
+
99
+ val layoutParent = parent as ViewGroup
100
+ (layoutParent.layoutParams as CoordinatorLayout.LayoutParams).behavior = sheetBehavior
101
+ }
102
+
103
+ // Configure Sheet Dialog
104
+ sheetDialog.apply {
105
+ setOnShowListener {
106
+ UiThreadUtil.runOnUiThread {
107
+ footerView?.let {
108
+ val sheetView = sheetLayout.parent as ViewGroup
109
+ it.y = (sheetView.height - sheetView.top - it.height).toFloat()
110
+ }
111
+ }
112
+
113
+ presentPromise?.invoke()
114
+ presentPromise = null
115
+
116
+ // dispatch onPresent event
117
+ eventDispatcher?.dispatchEvent(PresentEvent(surfaceId, id))
118
+ }
119
+
120
+ setOnDismissListener {
121
+ dismissPromise?.invoke()
122
+ dismissPromise = null
123
+
124
+ // dispatch onDismiss event
125
+ eventDispatcher?.dispatchEvent(DismissEvent(surfaceId, id))
126
+ }
127
+ }
128
+ }
129
+
130
+ override fun dispatchProvideStructure(structure: ViewStructure) {
131
+ sheetRootView.dispatchProvideStructure(structure)
132
+ }
133
+
134
+ override fun onLayout(
135
+ changed: Boolean,
136
+ l: Int,
137
+ t: Int,
138
+ r: Int,
139
+ b: Int
140
+ ) {
141
+ // Do nothing as we are laid out by UIManager
142
+ }
143
+
144
+ override fun onDetachedFromWindow() {
145
+ super.onDetachedFromWindow()
146
+ sheetDialog.dismiss()
147
+ }
148
+
149
+ override fun addView(child: View, index: Int) {
150
+ // Hide this host view
151
+ visibility = GONE
152
+
153
+ (child as ViewGroup).let {
154
+ // Container View's first child is the Content View
155
+ contentView = it.getChildAt(0) as ViewGroup
156
+ footerView = it.getChildAt(1) as ViewGroup
157
+
158
+ sheetBehavior.contentView = contentView
159
+ sheetBehavior.footerView = footerView
160
+
161
+ // rootView's first child is the Container View
162
+ sheetRootView.addView(it, index)
163
+ }
164
+ }
165
+
166
+ override fun getChildCount(): Int {
167
+ // This method may be called by the parent constructor
168
+ // before rootView is initialized.
169
+ return sheetRootView.childCount
170
+ }
171
+
172
+ override fun getChildAt(index: Int): View = sheetRootView.getChildAt(index)
173
+
174
+ override fun removeView(child: View) {
175
+ sheetRootView.removeView(child)
176
+ }
177
+
178
+ override fun removeViewAt(index: Int) {
179
+ val child = getChildAt(index)
180
+ sheetRootView.removeView(child)
181
+ }
182
+
183
+ override fun addChildrenForAccessibility(outChildren: ArrayList<View>) {
184
+ // Explicitly override this to prevent accessibility events being passed down to children
185
+ // Those will be handled by the rootView which lives in the dialog
186
+ }
187
+
188
+ override fun dispatchPopulateAccessibilityEvent(event: AccessibilityEvent): Boolean {
189
+ // Explicitly override this to prevent accessibility events being passed down to children
190
+ // Those will be handled by the rootView which lives in the dialog
191
+ return false
192
+ }
193
+
194
+ override fun onHostResume() {
195
+ // do nothing
196
+ }
197
+
198
+ override fun onHostPause() {
199
+ // do nothing
200
+ }
201
+
202
+ override fun onHostDestroy() {
203
+ // Drop the instance if the host is destroyed which will dismiss the dialog
204
+ reactContext.removeLifecycleEventListener(this)
205
+ sheetDialog.dismiss()
206
+ }
207
+
208
+ fun setSizes(newSizes: Array<Any>) {
209
+ sizes = newSizes
210
+ sheetBehavior.configure(sizes)
211
+ }
212
+
213
+ fun present(index: Int, promiseCallback: () -> Unit) {
214
+ sheetBehavior.setStateForSizeIndex(sizes.size, index)
215
+
216
+ if (sheetDialog.isShowing) {
217
+ promiseCallback()
218
+ } else {
219
+ sheetBehavior.configure(sizes)
220
+ presentPromise = promiseCallback
221
+ sheetDialog.show()
222
+ }
223
+ }
224
+
225
+ fun dismiss(promiseCallback: () -> Unit) {
226
+ dismissPromise = promiseCallback
227
+ sheetDialog.dismiss()
228
+ }
229
+
230
+ companion object {
231
+ const val TAG = "TrueSheetView"
232
+ }
233
+ }
@@ -1,20 +1,52 @@
1
1
  package com.lodev09.truesheet
2
2
 
3
- import android.graphics.Color
4
- import android.view.View
5
- import com.facebook.react.uimanager.SimpleViewManager
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.ReadableArray
5
+ import com.facebook.react.bridge.ReadableType
6
+ import com.facebook.react.common.MapBuilder
6
7
  import com.facebook.react.uimanager.ThemedReactContext
8
+ import com.facebook.react.uimanager.ViewGroupManager
7
9
  import com.facebook.react.uimanager.annotations.ReactProp
10
+ import com.lodev09.truesheet.core.DismissEvent
11
+ import com.lodev09.truesheet.core.PresentEvent
12
+ import com.lodev09.truesheet.core.SizeChangeEvent
8
13
 
9
- class TrueSheetViewManager : SimpleViewManager<View>() {
10
- override fun getName() = "TrueSheetView"
14
+ class TrueSheetViewManager : ViewGroupManager<TrueSheetView>() {
15
+ override fun getName() = TAG
11
16
 
12
- override fun createViewInstance(reactContext: ThemedReactContext): View {
13
- return View(reactContext)
17
+ override fun createViewInstance(reactContext: ThemedReactContext): TrueSheetView = TrueSheetView(reactContext)
18
+
19
+ override fun onDropViewInstance(view: TrueSheetView) {
20
+ super.onDropViewInstance(view)
21
+ view.onHostDestroy()
22
+ }
23
+
24
+ override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any>? =
25
+ MapBuilder.builder<String, Any>()
26
+ .put(PresentEvent.EVENT_NAME, MapBuilder.of("registrationName", "onPresent"))
27
+ .put(DismissEvent.EVENT_NAME, MapBuilder.of("registrationName", "onDismiss"))
28
+ .put(SizeChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", "onSizeChange"))
29
+ .build()
30
+
31
+ @ReactProp(name = "sizes")
32
+ fun setSizes(view: TrueSheetView, sizes: ReadableArray?) {
33
+ if (sizes != null) {
34
+ val result = ArrayList<Any>()
35
+ for (i in 0 until minOf(sizes.size(), 3)) {
36
+ when (sizes.getType(i)) {
37
+ ReadableType.Number -> result.add(sizes.getDouble(i))
38
+ ReadableType.String -> result.add(sizes.getString(i))
39
+ else -> Log.d(TAG, "Invalid type")
40
+ }
41
+ }
42
+
43
+ view.setSizes(result.toArray())
44
+ } else {
45
+ view.setSizes(arrayOf("medium", "large"))
46
+ }
14
47
  }
15
48
 
16
- @ReactProp(name = "color")
17
- fun setColor(view: View, color: String) {
18
- view.setBackgroundColor(Color.parseColor(color))
49
+ companion object {
50
+ const val TAG = "TrueSheetView"
19
51
  }
20
52
  }
@@ -0,0 +1,63 @@
1
+ package com.lodev09.truesheet
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.Promise
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
7
+ import com.facebook.react.bridge.ReactMethod
8
+ import com.facebook.react.bridge.UiThreadUtil
9
+ import com.facebook.react.module.annotations.ReactModule
10
+ import com.facebook.react.uimanager.UIManagerHelper
11
+ import com.lodev09.truesheet.utils.withPromise
12
+
13
+ @ReactModule(name = TrueSheetViewModule.TAG)
14
+ class TrueSheetViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
15
+ override fun getName(): String = TAG
16
+
17
+ private fun withTrueSheetView(tag: Int, closure: (trueSheetView: TrueSheetView) -> Unit) {
18
+ UiThreadUtil.runOnUiThread {
19
+ try {
20
+ val manager = UIManagerHelper.getUIManagerForReactTag(reactApplicationContext, tag)
21
+ val view = manager?.resolveView(tag)
22
+ if (view == null) {
23
+ Log.d(TAG, "Tag $tag not found")
24
+ return@runOnUiThread
25
+ }
26
+
27
+ if (view is TrueSheetView) {
28
+ closure(view)
29
+ } else {
30
+ Log.d(TAG, "Tag $tag does not match")
31
+ }
32
+ } catch (e: Exception) {
33
+ e.printStackTrace()
34
+ }
35
+ }
36
+ }
37
+
38
+ @ReactMethod
39
+ fun present(tag: Int, index: Int, promise: Promise) {
40
+ withTrueSheetView(tag) {
41
+ it.present(index) {
42
+ withPromise(promise) {
43
+ return@withPromise null
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ @ReactMethod
50
+ fun dismiss(tag: Int, promise: Promise) {
51
+ withTrueSheetView(tag) {
52
+ it.dismiss {
53
+ withPromise(promise) {
54
+ return@withPromise null
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ companion object {
61
+ const val TAG = "TrueSheetView"
62
+ }
63
+ }
@@ -0,0 +1,43 @@
1
+ package com.lodev09.truesheet.core
2
+
3
+ import com.facebook.react.bridge.Arguments
4
+ import com.facebook.react.bridge.WritableMap
5
+ import com.facebook.react.uimanager.events.Event
6
+
7
+ // onPresent
8
+ class PresentEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
9
+ override fun getEventName() = EVENT_NAME
10
+
11
+ override fun getEventData(): WritableMap = Arguments.createMap()
12
+
13
+ companion object {
14
+ const val EVENT_NAME = "present"
15
+ }
16
+ }
17
+
18
+ // onDismiss
19
+ class DismissEvent(surfaceId: Int, viewId: Int) : Event<PresentEvent>(surfaceId, viewId) {
20
+ override fun getEventName() = EVENT_NAME
21
+
22
+ override fun getEventData(): WritableMap = Arguments.createMap()
23
+
24
+ companion object {
25
+ const val EVENT_NAME = "dismiss"
26
+ }
27
+ }
28
+
29
+ class SizeChangeEvent(surfaceId: Int, viewId: Int, private val sizeInfo: SizeInfo) : Event<SizeChangeEvent>(surfaceId, viewId) {
30
+ override fun getEventName() = EVENT_NAME
31
+
32
+ override fun getEventData(): WritableMap {
33
+ val data = Arguments.createMap()
34
+ data.putInt("index", sizeInfo.index)
35
+ data.putDouble("value", sizeInfo.value.toDouble())
36
+
37
+ return data
38
+ }
39
+
40
+ companion object {
41
+ const val EVENT_NAME = "sizeChange"
42
+ }
43
+ }
@@ -0,0 +1,136 @@
1
+ package com.lodev09.truesheet.core
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import android.view.MotionEvent
6
+ import android.view.View
7
+ import com.facebook.react.bridge.GuardedRunnable
8
+ import com.facebook.react.config.ReactFeatureFlags
9
+ import com.facebook.react.uimanager.JSPointerDispatcher
10
+ import com.facebook.react.uimanager.JSTouchDispatcher
11
+ import com.facebook.react.uimanager.RootView
12
+ import com.facebook.react.uimanager.ThemedReactContext
13
+ import com.facebook.react.uimanager.UIManagerModule
14
+ import com.facebook.react.uimanager.events.EventDispatcher
15
+ import com.facebook.react.views.view.ReactViewGroup
16
+
17
+ /**
18
+ * RootViewGroup is the ViewGroup which contains all the children of a Modal. It gets all
19
+ * child information forwarded from ReactModalHostView and uses that to create children. It is
20
+ * also responsible for acting as a RootView and handling touch events. It does this the same way
21
+ * as ReactRootView.
22
+ *
23
+ *
24
+ * To get layout to work properly, we need to layout all the elements within the Modal as if
25
+ * they can fill the entire window. To do that, we need to explicitly set the styleWidth and
26
+ * styleHeight on the LayoutShadowNode to be the window size. This is done through the
27
+ * UIManagerModule, and will then cause the children to layout as if they can fill the window.
28
+ */
29
+ internal class RootViewGroup(context: Context?) :
30
+ ReactViewGroup(context),
31
+ RootView {
32
+ private var hasAdjustedSize = false
33
+ private var viewWidth = 0
34
+ private var viewHeight = 0
35
+
36
+ private val mJSTouchDispatcher = JSTouchDispatcher(this)
37
+
38
+ private var mJSPointerDispatcher: JSPointerDispatcher? = null
39
+
40
+ var eventDispatcher: EventDispatcher? = null
41
+
42
+ init {
43
+ if (ReactFeatureFlags.dispatchPointerEvents) {
44
+ mJSPointerDispatcher = JSPointerDispatcher(this)
45
+ }
46
+ }
47
+
48
+ override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
49
+ super.onSizeChanged(w, h, oldw, oldh)
50
+
51
+ viewWidth = w
52
+ viewHeight = h
53
+ updateFirstChildView()
54
+ }
55
+
56
+ private fun updateFirstChildView() {
57
+ if (childCount > 0) {
58
+ hasAdjustedSize = false
59
+ val viewTag = getChildAt(0).id
60
+ reactContext.runOnNativeModulesQueueThread(
61
+ object : GuardedRunnable(reactContext) {
62
+ override fun runGuarded() {
63
+ val uiManager: UIManagerModule =
64
+ reactContext
65
+ .reactApplicationContext
66
+ .getNativeModule(UIManagerModule::class.java) ?: return
67
+
68
+ uiManager.updateNodeSize(viewTag, viewWidth, viewHeight)
69
+ }
70
+ }
71
+ )
72
+ } else {
73
+ hasAdjustedSize = true
74
+ }
75
+ }
76
+
77
+ override fun addView(child: View, index: Int, params: LayoutParams) {
78
+ super.addView(child, index, params)
79
+ if (hasAdjustedSize) {
80
+ updateFirstChildView()
81
+ }
82
+ }
83
+
84
+ override fun handleException(t: Throwable) {
85
+ reactContext.reactApplicationContext.handleException(RuntimeException(t))
86
+ }
87
+
88
+ private val reactContext: ThemedReactContext
89
+ get() = context as ThemedReactContext
90
+
91
+ override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
92
+ mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
93
+ mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
94
+ return super.onInterceptTouchEvent(event)
95
+ }
96
+
97
+ @SuppressLint("ClickableViewAccessibility")
98
+ override fun onTouchEvent(event: MotionEvent): Boolean {
99
+ mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher)
100
+ mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
101
+ super.onTouchEvent(event)
102
+
103
+ // In case when there is no children interested in handling touch event, we return true from
104
+ // the root view in order to receive subsequent events related to that gesture
105
+ return true
106
+ }
107
+
108
+ override fun onInterceptHoverEvent(event: MotionEvent): Boolean {
109
+ mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, true)
110
+ return super.onHoverEvent(event)
111
+ }
112
+
113
+ override fun onHoverEvent(event: MotionEvent): Boolean {
114
+ mJSPointerDispatcher?.handleMotionEvent(event, eventDispatcher, false)
115
+ return super.onHoverEvent(event)
116
+ }
117
+
118
+ override fun onChildStartedNativeGesture(childView: View, ev: MotionEvent) {
119
+ mJSTouchDispatcher.onChildStartedNativeGesture(ev, eventDispatcher)
120
+ mJSPointerDispatcher?.onChildStartedNativeGesture(childView, ev, eventDispatcher)
121
+ }
122
+
123
+ override fun onChildEndedNativeGesture(childView: View, ev: MotionEvent) {
124
+ mJSTouchDispatcher.onChildEndedNativeGesture(ev, eventDispatcher)
125
+ mJSPointerDispatcher?.onChildEndedNativeGesture()
126
+ }
127
+
128
+ override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
129
+ // No-op - override in order to still receive events to onInterceptTouchEvent
130
+ // even when some other view disallow that
131
+ }
132
+
133
+ companion object {
134
+ const val TAG = "TrueSheetView"
135
+ }
136
+ }