Skip to content

Commit cf39de5

Browse files
committed
feat: add android support for shouldDismissByDrag
1 parent aaf8f88 commit cf39de5

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ alert({
154154
| `preset` | string | `done` | ![Both] ||| `done, error, none, spinner` |
155155
| `duration` | number | `3` | ![Both] ||| The lifetime of the toast (seconds) |
156156
| `titleColor` | string | null | ![Both] ||| |
157-
| `shouldDismissByDrag` | boolean | true | ![Both] || | The behavior on `Android` is click |
157+
| `shouldDismissByDrag` | boolean | true | ![Both] ||
158158
| `position` | string | `top` | ![Both] || | **Toast** is displayed from `top` or `bottom` |
159159
| `haptic` | string | null | ![iOS] || | `success, warning, error, none` |
160160
| `shouldDismissByTap` | boolean | true | ![Both] | || |
@@ -178,7 +178,7 @@ alert({
178178
- [x] `backgroundColor` (v.1.0.3)
179179
- [x] `spinner preset for toast` (v.1.1.0)
180180
- [x] custom color like StyleSheet (e.g. `#fff`, `red`, `rgba(0, 0, 0, .8)`)
181-
- [ ] `shouldDismissByDrag` on **Android**
181+
- [x] `shouldDismissByDrag` on **Android**
182182
- [ ] `callback`
183183

184184

android/src/main/java/com/ting/TingModule.kt

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import android.graphics.drawable.AnimatedVectorDrawable
1111
import android.graphics.drawable.GradientDrawable
1212
import android.os.Handler
1313
import android.os.Looper
14+
import android.view.GestureDetector
1415
import android.view.Gravity
1516
import android.view.LayoutInflater
17+
import android.view.MotionEvent
18+
import android.view.View
1619
import android.widget.ImageView
1720
import android.widget.LinearLayout
1821
import android.widget.ProgressBar
@@ -26,6 +29,7 @@ import com.facebook.react.bridge.WritableMap
2629
import com.hjq.window.EasyWindow
2730
import java.io.IOException
2831
import java.net.URL
32+
import kotlin.math.abs
2933
import kotlin.math.roundToInt
3034

3135

@@ -38,9 +42,9 @@ class TingModule internal constructor(context: ReactApplicationContext) : TingSp
3842
private var alertOptionInit: ReadableMap? = null
3943

4044
@ReactMethod
41-
override fun toast(options: ReadableMap) {
45+
override fun toast(rnOptions: ReadableMap) {
4246
// get container View
43-
val options = toastOptionInit?.let { mergeMaps(it, options) } ?: options
47+
val options = toastOptionInit?.let { mergeMaps(it, rnOptions) } ?: rnOptions
4448

4549
val container = getContainerView(R.layout.toast, options, "toast")
4650
val duration: Int = getDuration(options)
@@ -66,19 +70,46 @@ class TingModule internal constructor(context: ReactApplicationContext) : TingSp
6670
setYOffset(48)
6771
setAnimStyle(toastAnim)
6872
setOutsideTouchable(true)
69-
setOnClickListener(R.id.toast,
70-
EasyWindow.OnClickListener { toast: EasyWindow<*>, _: LinearLayout? ->
71-
val shouldDismissByTap =
72-
if (options.hasKey("shouldDismissByDrag")) options.getBoolean("shouldDismissByDrag") else true
73-
if (shouldDismissByTap) toast.cancel()
74-
})
73+
74+
if (options.hasKey("shouldDismissByDrag") && options.getBoolean("shouldDismissByDrag")) {
75+
// Define dragThreshold in density-independent pixels (dp)
76+
val dragThresholdDP = 12
77+
val scale = context.resources.displayMetrics.density
78+
val dragThreshold = (dragThresholdDP * scale + 0.5f).toInt()
79+
80+
// Add drag gesture recognizer
81+
contentView?.let { contentView ->
82+
val gestureDetector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
83+
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
84+
// Check if the user scrolls vertically and dismiss the toast window if needed
85+
if (abs(distanceY) > abs(distanceX)) {
86+
if (position == Gravity.TOP && distanceY > dragThreshold) { // Dismiss upward if toast is at the top
87+
toastWindow.cancel()
88+
return true
89+
} else if (position == Gravity.BOTTOM && distanceY < -dragThreshold) { // Dismiss downward if toast is at the bottom
90+
toastWindow.cancel()
91+
return true
92+
}
93+
}
94+
95+
return super.onScroll(e1, e2, distanceX, distanceY)
96+
}
97+
})
98+
99+
contentView.setOnTouchListener(fun(_: View, event: MotionEvent): Boolean {
100+
gestureDetector.onTouchEvent(event)
101+
return true // Consume the touch event
102+
})
103+
}
104+
}
105+
75106
}.show()
76107
}
77108
}
78109

79110
@ReactMethod
80-
override fun alert(options: ReadableMap) {
81-
val options = alertOptionInit?.let { mergeMaps(it, options) } ?: options
111+
override fun alert(rnOptions: ReadableMap) {
112+
val options = alertOptionInit?.let { mergeMaps(it, rnOptions) } ?: rnOptions
82113

83114
val container = getContainerView(R.layout.alert, options, "alert")
84115
val duration: Int = getDuration(options)

example/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ const DATA: ItemType[] = [
160160
onPress: () =>
161161
toast({
162162
duration: 10,
163-
164163
title: 'Việt Nam',
165164
titleColor: '#ffffff',
166165
message: 'Vietnamese Gangz 🇻🇳',
@@ -195,6 +194,7 @@ const DATA: ItemType[] = [
195194
message: 'Chờ xíu',
196195
preset: 'spinner',
197196
progressColor: '#FD966A',
197+
shouldDismissByDrag: true,
198198
}),
199199
},
200200
{

0 commit comments

Comments
 (0)