55 lines
1.4 KiB
JavaScript
55 lines
1.4 KiB
JavaScript
import { Controller } from "@hotwired/stimulus"
|
|
|
|
const SWIPE_DURATION = 1000
|
|
const SWIPE_THRESHOLD = 30
|
|
|
|
export default class extends Controller {
|
|
connect() {
|
|
this.element.addEventListener("touchstart", this.#handleTouchStart.bind(this), false)
|
|
this.element.addEventListener("touchend", this.#handleTouchEnd.bind(this), false)
|
|
}
|
|
|
|
#handleTouchStart(event) {
|
|
this.startX = event.touches[0].clientX
|
|
this.startY = event.touches[0].clientY
|
|
this.startTime = new Date().getTime()
|
|
}
|
|
|
|
#handleTouchEnd(event) {
|
|
this.endTime = new Date().getTime()
|
|
|
|
if (this.#isSelection || this.#exceedsDuration) return
|
|
|
|
const endX = event.changedTouches[0].clientX
|
|
const endY = event.changedTouches[0].clientY
|
|
const deltaX = Math.abs(endX - this.startX)
|
|
const deltaY = Math.abs(endY - this.startY)
|
|
|
|
if (deltaX > SWIPE_THRESHOLD && deltaY < SWIPE_THRESHOLD) {
|
|
if (this.startX > endX) {
|
|
this.#swipedRight()
|
|
} else {
|
|
this.#swipedLeft()
|
|
}
|
|
}
|
|
}
|
|
|
|
#swipedLeft() {
|
|
this.dispatch("swipe-left")
|
|
}
|
|
|
|
#swipedRight() {
|
|
this.dispatch("swipe-right")
|
|
}
|
|
|
|
get #exceedsDuration() {
|
|
const duration = this.endTime - this.startTime
|
|
return duration > SWIPE_DURATION
|
|
}
|
|
|
|
get #isSelection() {
|
|
const selection = window.getSelection()
|
|
return selection.toString().length > 0 && !selection.isCollapsed
|
|
}
|
|
}
|