Skip to content

Commit cc033f8

Browse files
authored
this should make swipes register reliably on mobile as currently its not always recognizing (#51)
Signed-off-by: Kai Wagner <kai.wagner@percona.com>
1 parent 7e38acb commit cc033f8

File tree

1 file changed

+62
-6
lines changed

1 file changed

+62
-6
lines changed

app/javascript/controllers/swipe_nav_controller.js

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,18 @@ export default class extends Controller {
99
this.onPointerDown = this.onPointerDown.bind(this)
1010
this.onPointerMove = this.onPointerMove.bind(this)
1111
this.onPointerUp = this.onPointerUp.bind(this)
12+
this.onTouchStart = this.onTouchStart.bind(this)
13+
this.onTouchMove = this.onTouchMove.bind(this)
14+
this.onTouchEnd = this.onTouchEnd.bind(this)
1215
window.addEventListener("pointerdown", this.onPointerDown, { passive: true })
16+
window.addEventListener("touchstart", this.onTouchStart, { passive: true })
1317
}
1418

1519
disconnect() {
1620
window.removeEventListener("pointerdown", this.onPointerDown, { passive: true })
21+
window.removeEventListener("touchstart", this.onTouchStart, { passive: true })
1722
this.detachTrackingListeners()
23+
this.detachTouchTrackingListeners()
1824
}
1925

2026
onPointerDown(event) {
@@ -23,6 +29,7 @@ export default class extends Controller {
2329
if (event.button && event.button !== 0) return
2430
if (this.shouldIgnoreTarget(event.target)) return
2531

32+
this.usingPointer = true
2633
this.tracking = true
2734
this.pointerId = event.pointerId
2835
this.startX = event.clientX
@@ -51,8 +58,63 @@ export default class extends Controller {
5158

5259
this.tracking = false
5360
this.pointerId = null
61+
this.usingPointer = false
5462
this.detachTrackingListeners()
5563

64+
this.maybeNavigate(elapsed, deltaX, deltaY)
65+
}
66+
67+
detachTrackingListeners() {
68+
window.removeEventListener("pointermove", this.onPointerMove, { passive: true })
69+
window.removeEventListener("pointerup", this.onPointerUp, { passive: true })
70+
window.removeEventListener("pointercancel", this.onPointerUp, { passive: true })
71+
}
72+
73+
onTouchStart(event) {
74+
if (this.usingPointer) return
75+
if (!event.touches || event.touches.length !== 1) return
76+
if (this.shouldIgnoreTarget(event.target)) return
77+
78+
const touch = event.touches[0]
79+
this.touchTracking = true
80+
this.startX = touch.clientX
81+
this.startY = touch.clientY
82+
this.startTime = performance.now()
83+
this.lastX = touch.clientX
84+
this.lastY = touch.clientY
85+
86+
window.addEventListener("touchmove", this.onTouchMove, { passive: true })
87+
window.addEventListener("touchend", this.onTouchEnd, { passive: true })
88+
window.addEventListener("touchcancel", this.onTouchEnd, { passive: true })
89+
}
90+
91+
onTouchMove(event) {
92+
if (!this.touchTracking || !event.touches || event.touches.length !== 1) return
93+
const touch = event.touches[0]
94+
this.lastX = touch.clientX
95+
this.lastY = touch.clientY
96+
}
97+
98+
onTouchEnd() {
99+
if (!this.touchTracking) return
100+
101+
const elapsed = performance.now() - this.startTime
102+
const deltaX = this.lastX - this.startX
103+
const deltaY = this.lastY - this.startY
104+
105+
this.touchTracking = false
106+
this.detachTouchTrackingListeners()
107+
108+
this.maybeNavigate(elapsed, deltaX, deltaY)
109+
}
110+
111+
detachTouchTrackingListeners() {
112+
window.removeEventListener("touchmove", this.onTouchMove, { passive: true })
113+
window.removeEventListener("touchend", this.onTouchEnd, { passive: true })
114+
window.removeEventListener("touchcancel", this.onTouchEnd, { passive: true })
115+
}
116+
117+
maybeNavigate(elapsed, deltaX, deltaY) {
56118
if (elapsed > SWIPE_TIME_MS) return
57119
if (Math.abs(deltaX) < SWIPE_DISTANCE_PX) return
58120
if (Math.abs(deltaX) < Math.abs(deltaY) * SWIPE_AXIS_RATIO) return
@@ -64,12 +126,6 @@ export default class extends Controller {
64126
}
65127
}
66128

67-
detachTrackingListeners() {
68-
window.removeEventListener("pointermove", this.onPointerMove, { passive: true })
69-
window.removeEventListener("pointerup", this.onPointerUp, { passive: true })
70-
window.removeEventListener("pointercancel", this.onPointerUp, { passive: true })
71-
}
72-
73129
shouldIgnoreTarget(target) {
74130
if (!target) return true
75131
if (target.closest("input, textarea, select, [contenteditable='true']")) return true

0 commit comments

Comments
 (0)