Improve mobile double tap

This commit is contained in:
Chocobozzz 2024-09-16 10:52:45 +02:00
parent 1f1379dcad
commit 137badb6db
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
2 changed files with 29 additions and 12 deletions

View File

@ -9,11 +9,12 @@ const Plugin = videojs.getPlugin('plugin')
class PeerTubeMobilePlugin extends Plugin { class PeerTubeMobilePlugin extends Plugin {
private static readonly DOUBLE_TAP_DELAY_MS = 250 private static readonly DOUBLE_TAP_DELAY_MS = 250
private static readonly SET_CURRENT_TIME_DELAY = 1000 private static readonly SET_CURRENT_TIME_DELAY = 750
declare private peerTubeMobileButtons: PeerTubeMobileButtons declare private peerTubeMobileButtons: PeerTubeMobileButtons
declare private seekAmount: number declare private seekAmount: number
declare private doubleTapping: boolean
declare private lastTapEvent: TouchEvent declare private lastTapEvent: TouchEvent
declare private tapTimeout: ReturnType<typeof setTimeout> declare private tapTimeout: ReturnType<typeof setTimeout>
@ -88,24 +89,35 @@ class PeerTubeMobilePlugin extends Plugin {
private initTouchStartEvents () { private initTouchStartEvents () {
const handleTouchStart = (event: TouchEvent) => { const handleTouchStart = (event: TouchEvent) => {
debugLogger('Handle touch start')
if (this.tapTimeout) { if (this.tapTimeout) {
clearTimeout(this.tapTimeout) clearTimeout(this.tapTimeout)
this.tapTimeout = undefined this.tapTimeout = undefined
} }
if (this.lastTapEvent && event.timeStamp - this.lastTapEvent.timeStamp < PeerTubeMobilePlugin.DOUBLE_TAP_DELAY_MS) { if (
this.doubleTapping ||
(this.lastTapEvent && event.timeStamp - this.lastTapEvent.timeStamp < PeerTubeMobilePlugin.DOUBLE_TAP_DELAY_MS)
) {
debugLogger('Detected double tap') debugLogger('Detected double tap')
this.lastTapEvent = undefined this.lastTapEvent = event
this.onDoubleTap(event) this.onDoubleTap(event)
return return
} }
this.newActiveState = !this.player.userActive() this.newActiveState = !this.player.userActive()
this.tapTimeout = setTimeout(() => { // video.js forces userActive on tap so we prevent this behaviour with a custom class
debugLogger('No double tap detected, set user active state to %s.', this.newActiveState) if (this.newActiveState === true) {
this.player.addClass('vjs-force-inactive')
}
this.tapTimeout = setTimeout(() => {
debugLogger('No double tap detected, set user active state to ' + this.newActiveState)
this.player.removeClass('vjs-force-inactive')
this.player.userActive(this.newActiveState) this.player.userActive(this.newActiveState)
}, PeerTubeMobilePlugin.DOUBLE_TAP_DELAY_MS) }, PeerTubeMobilePlugin.DOUBLE_TAP_DELAY_MS)
@ -113,16 +125,14 @@ class PeerTubeMobilePlugin extends Plugin {
} }
this.onTouchStartHandler = event => { this.onTouchStartHandler = event => {
// Only enable user active on player touch, we listen event on peertube mobile buttons to disable it
if (this.player.userActive()) return
handleTouchStart(event) handleTouchStart(event)
} }
this.player.on('touchstart', this.onTouchStartHandler) this.player.on('touchstart', this.onTouchStartHandler)
this.onMobileButtonTouchStartHandler = event => { this.onMobileButtonTouchStartHandler = event => {
// Prevent mousemove/click events firing on the player, that conflict with our user active logic // Prevent mousemove/click/tap events firing on the player, that conflict with our user active logic
event.preventDefault() event.preventDefault()
event.stopPropagation()
handleTouchStart(event) handleTouchStart(event)
} }
@ -165,6 +175,7 @@ class PeerTubeMobilePlugin extends Plugin {
private scheduleSetCurrentTime () { private scheduleSetCurrentTime () {
this.player.pause() this.player.pause()
this.player.addClass('vjs-fast-seeking') this.player.addClass('vjs-fast-seeking')
this.doubleTapping = true
if (this.setCurrentTimeTimeout) clearTimeout(this.setCurrentTimeTimeout) if (this.setCurrentTimeTimeout) clearTimeout(this.setCurrentTimeTimeout)
@ -180,7 +191,9 @@ class PeerTubeMobilePlugin extends Plugin {
this.peerTubeMobileButtons.displayFastSeek(0) this.peerTubeMobileButtons.displayFastSeek(0)
this.player.removeClass('vjs-fast-seeking') this.player.removeClass('vjs-fast-seeking')
this.player.removeClass('vjs-force-inactive')
this.player.userActive(false) this.player.userActive(false)
this.doubleTapping = false
this.player.play() this.player.play()
}, PeerTubeMobilePlugin.SET_CURRENT_TIME_DELAY) }, PeerTubeMobilePlugin.SET_CURRENT_TIME_DELAY)

View File

@ -51,7 +51,7 @@
height: 100%; height: 100%;
top: 0; top: 0;
.vjs-user-active, .vjs-user-active:not(.vjs-force-inactive),
.vjs-paused { .vjs-paused {
display: block; display: block;
} }
@ -88,7 +88,7 @@
.icon { .icon {
opacity: 0; opacity: 0;
animation: fadeInAndOut 1s linear infinite; animation: fadeInAndOut 750ms linear infinite;
&::before { &::before {
font-size: 20px; font-size: 20px;
@ -163,7 +163,7 @@
.vjs-can-play.vjs-has-started { .vjs-can-play.vjs-has-started {
&.vjs-user-active, &.vjs-user-active:not(.vjs-force-inactive),
&.vjs-paused { &.vjs-paused {
.vjs-mobile-buttons-overlay { .vjs-mobile-buttons-overlay {
display: block; display: block;
@ -186,6 +186,10 @@
} }
} }
.vjs-force-inactive .vjs-control-bar {
display: none;
}
@keyframes fadeInAndOut { @keyframes fadeInAndOut {
0%, 0%,
20% { 20% {