Browse Source

Add player controls on mobile

pull/4723/head
Chocobozzz 1 week ago
parent
commit
f1a0555a88
No known key found for this signature in database GPG Key ID: 583A612D890159BE
11 changed files with 153 additions and 4 deletions
  1. +4
    -0
      client/src/assets/player/bezels/pause-bezel.ts
  2. +42
    -0
      client/src/assets/player/mobile/peertube-mobile-buttons.ts
  3. +16
    -0
      client/src/assets/player/mobile/peertube-mobile-plugin.ts
  4. +5
    -1
      client/src/assets/player/peertube-player-manager.ts
  5. +6
    -1
      client/src/assets/player/peertube-plugin.ts
  6. +2
    -0
      client/src/assets/player/peertube-videojs-typings.ts
  7. +0
    -1
      client/src/assets/player/videojs-components/next-previous-video-button.ts
  8. +3
    -0
      client/src/sass/player/_player-variables.scss
  9. +3
    -1
      client/src/sass/player/control-bar.scss
  10. +71
    -0
      client/src/sass/player/mobile.scss
  11. +1
    -0
      client/src/sass/player/settings-menu.scss

+ 4
- 0
client/src/assets/player/bezels/pause-bezel.ts View File

@@ -1,4 +1,5 @@
import videojs from 'video.js'
import { isMobile } from '../utils'

function getPauseBezel () {
return `
@@ -37,6 +38,9 @@ class PauseBezel extends Component {
constructor (player: videojs.Player, options?: videojs.ComponentOptions) {
super(player, options)

// Hide bezels on mobile since we already have our mobile overlay
if (isMobile()) return

player.on('pause', (_: any) => {
if (player.seeking() || player.ended()) return
this.container.innerHTML = getPauseBezel()


+ 42
- 0
client/src/assets/player/mobile/peertube-mobile-buttons.ts View File

@@ -0,0 +1,42 @@
import videojs from 'video.js'

import debug from 'debug'

const logger = debug('peertube:player:mobile')

const Component = videojs.getComponent('Component')
class PeerTubeMobileButtons extends Component {

createEl () {
const container = super.createEl('div', {
className: 'vjs-mobile-buttons-overlay'
}) as HTMLDivElement

container.addEventListener('click', () => {
logger('Set user as inactive')

this.player_.userActive(false)
})

const mainButton = super.createEl('div', {
className: 'main-button'
}) as HTMLDivElement

mainButton.addEventListener('click', e => {
e.stopPropagation()

if (this.player_.paused() || this.player_.ended()) {
this.player_.play()
return
}

this.player_.pause()
})

container.appendChild(mainButton)

return container
}
}

videojs.registerComponent('PeerTubeMobileButtons', PeerTubeMobileButtons)

+ 16
- 0
client/src/assets/player/mobile/peertube-mobile-plugin.ts View File

@@ -0,0 +1,16 @@
import videojs from 'video.js'
import './peertube-mobile-buttons'

const Plugin = videojs.getPlugin('plugin')

class PeerTubeMobilePlugin extends Plugin {

constructor (player: videojs.Player, options: videojs.PlayerOptions) {
super(player, options)

player.addChild('PeerTubeMobileButtons')
}
}

videojs.registerPlugin('peertubeMobile', PeerTubeMobilePlugin)
export { PeerTubeMobilePlugin }

+ 5
- 1
client/src/assets/player/peertube-player-manager.ts View File

@@ -21,6 +21,7 @@ import './videojs-components/settings-panel'
import './videojs-components/settings-panel-child'
import './videojs-components/theater-button'
import './playlist/playlist-plugin'
import './mobile/peertube-mobile-plugin'
import videojs from 'video.js'
import { HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs'
import { PluginsManager } from '@root-helpers/plugins-manager'
@@ -43,7 +44,7 @@ import {
VideoJSPluginOptions
} from './peertube-videojs-typings'
import { TranslationsManager } from './translations-manager'
import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils'
import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isMobile, isSafari } from './utils'

// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed'
@@ -189,7 +190,10 @@ export class PeertubePlayerManager {
videoEmbedTitle: options.common.embedTitle
})

if (isMobile()) player.peertubeMobile()

player.bezels()

player.stats({
videoUUID: options.common.videoUUID,
videoIsLive: options.common.isLive,


+ 6
- 1
client/src/assets/player/peertube-plugin.ts View File

@@ -12,6 +12,9 @@ import {
import { PeerTubePluginOptions, UserWatching, VideoJSCaption } from './peertube-videojs-typings'
import { isMobile } from './utils'
import { SettingsButton } from './videojs-components/settings-menu-button'
import debug from 'debug'

const logger = debug('peertube:player:peertube')

const Plugin = videojs.getPlugin('plugin')

@@ -233,7 +236,7 @@ class PeerTubePlugin extends Plugin {
}

private alterInactivity () {
if (this.menuOpened || this.mouseInSettings || this.mouseInControlBar || this.isTouchEnabled()) {
if (this.menuOpened || this.mouseInSettings || this.mouseInControlBar) {
this.setInactivityTimeout(0)
return
}
@@ -245,6 +248,8 @@ class PeerTubePlugin extends Plugin {
private setInactivityTimeout (timeout: number) {
(this.player as any).cache_.inactivityTimeout = timeout
this.player.options_.inactivityTimeout = timeout

logger('Set player inactivity to ' + timeout)
}

private isTouchEnabled () {


+ 2
- 0
client/src/assets/player/peertube-videojs-typings.ts View File

@@ -42,6 +42,8 @@ declare module 'video.js' {

bezels (): void

peertubeMobile (): void

stats (options?: StatsCardOptions): StatsForNerdsPlugin

textTracks (): TextTrackList & {


+ 0
- 1
client/src/assets/player/videojs-components/next-previous-video-button.ts View File

@@ -40,7 +40,6 @@ class NextPreviousVideoButton extends Button {

update () {
const disabled = this.nextPreviousVideoButtonOptions.isDisabled()
console.log(disabled)

if (disabled) this.addClass('vjs-disabled')
else this.removeClass('vjs-disabled')


+ 3
- 0
client/src/sass/player/_player-variables.scss View File

@@ -8,11 +8,14 @@ $font-size: 13px;
$control-bar-height: 38px;
$control-bar-icon-size: 26px;
$control-bar-volume-slider-height: 14px;
$control-bar-slider-top: -10px;
$control-bar-font-size: 14px;
$control-bar-play-font-size: 34px;
$control-bar-next-previous-play-font-size: 14px;
$control-bar-button-width: 38px;

$control-bar-total-height: $control-bar-height - $control-bar-slider-top;

$slider-bg-color: lighten($primary-background-color, 33%);

$progress-margin: 10px;


+ 3
- 1
client/src/sass/player/control-bar.scss View File

@@ -4,6 +4,8 @@
@use './_player-variables' as *;

.video-js.vjs-peertube-skin .vjs-control-bar {
z-index: 100;

height: $control-bar-height;
background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.6));
box-shadow: 0 -15px 40px 10px rgba(0, 0, 0, 0.2);
@@ -49,7 +51,7 @@
@include margin-left($progress-margin);

position: absolute;
top: -10px;
top: $control-bar-slider-top;
z-index: 100; // On top of the progress bar
width: calc(100% - (2 * #{$progress-margin}));
height: 14px;


+ 71
- 0
client/src/sass/player/mobile.scss View File

@@ -1,5 +1,7 @@
@use 'sass:math';
@use '_variables' as *;
@use '_mixins' as *;
@use './_player-variables' as *;

/* Special mobile style */

@@ -14,3 +16,72 @@
}
}
}

.vjs-mobile-buttons-overlay {
display: none;

position: absolute;
background-color: rgba(0, 0, 0, 0.4);
width: 100%;
height: 100%;
top: 0;

.vjs-user-active,
.vjs-paused {
display: block;
}

.main-button {
font-family: VideoJS;
font-weight: normal;
font-style: normal;
font-size: 5em;
width: fit-content;
margin: auto;
position: relative;
top: calc(50% - 10px);
transform: translateY(-50%);
}
}

.vjs-paused {
.main-button {
&:before {
content: '\f101';
}
}
}

.vjs-playing {
.main-button {
&:before {
content: '\f103';
}
}
}

.vjs-ended {
.main-button {
&:before {
content: '\f116';
}
}
}

.vjs-has-started {

&.vjs-user-active,
&.vjs-paused {
.vjs-mobile-buttons-overlay {
display: block;
}
}

&.vjs-seeking,
&.vjs-scrubbing,
&.vjs-waiting {
.vjs-mobile-buttons-overlay {
display: none;
}
}
}

+ 1
- 0
client/src/sass/player/settings-menu.scss View File

@@ -22,6 +22,7 @@ $setting-transition-easing: ease-out;
opacity: $primary-foreground-opacity;
margin: 0 auto;
font-size: $font-size !important;
z-index: 100;

width: auto;
overflow: hidden;


Loading…
Cancel
Save