From 3bcb4fd74190aecb22c39a88772e80b223a87472 Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Tue, 17 Dec 2019 16:49:33 +0100 Subject: add 'up next' screen on autoplay --- client/src/assets/player/upnext/upnext-plugin.ts | 169 +++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 client/src/assets/player/upnext/upnext-plugin.ts (limited to 'client/src/assets/player/upnext') diff --git a/client/src/assets/player/upnext/upnext-plugin.ts b/client/src/assets/player/upnext/upnext-plugin.ts new file mode 100644 index 000000000..1f0705481 --- /dev/null +++ b/client/src/assets/player/upnext/upnext-plugin.ts @@ -0,0 +1,169 @@ +// @ts-ignore +import * as videojs from 'video.js' +import { VideoJSComponentInterface } from '../peertube-videojs-typings' + +function getMainTemplate (options: any) { + return ` +
+ ${options.headText} +
+
+
+ + + + +
+ + + + + + ` +} + +// @ts-ignore-start +const Component = videojs.getComponent('Component') +class EndCard extends Component { + options_: any + getTitle: Function + next: Function + condition: Function + dashOffsetTotal = 586 + dashOffsetStart = 293 + interval = 50 + upNextEvents = new videojs.EventTarget() + chunkSize: number + + container: HTMLElement + title: HTMLElement + autoplayRing: HTMLElement + cancelButton: HTMLElement + nextButton: HTMLElement + + constructor (player: videojs.Player, options: any) { + super(player, options) + this.options_ = options + + this.getTitle = this.options_.getTitle + this.next = this.options_.next + this.condition = this.options_.condition + + this.chunkSize = (this.dashOffsetTotal - this.dashOffsetStart) / (this.options_.timeout / this.interval) + + player.on('ended', (_: any) => { + if (!this.condition()) return + + player.addClass('vjs-upnext--showing') + this.showCard((canceled: boolean) => { + player.removeClass('vjs-upnext--showing') + this.container.style.display = 'none' + if (!canceled) { + this.next() + } + }) + }) + + player.on('playing', () => { + this.upNextEvents.trigger('playing') + }) + } + + createEl () { + const container = super.createEl('div', { + className: 'vjs-upnext-content', + innerHTML: getMainTemplate(this.options_) + }) + + this.container = container + container.style.display = 'none' + + this.autoplayRing = container.getElementsByClassName('vjs-upnext-svg-autoplay-ring')[0] + this.title = container.getElementsByClassName('vjs-upnext-title')[0] + this.cancelButton = container.getElementsByClassName('vjs-upnext-cancel-button')[0] + this.nextButton = container.getElementsByClassName('vjs-upnext-autoplay-icon')[0] + + this.cancelButton.onclick = () => { + this.upNextEvents.trigger('cancel') + } + + this.nextButton.onclick = () => { + this.upNextEvents.trigger('next') + } + + return container + } + + showCard (cb: Function) { + let timeout: any + let start: number + let now: number + let newOffset: number + + this.autoplayRing.setAttribute('stroke-dasharray', this.dashOffsetStart) + this.autoplayRing.setAttribute('stroke-dashoffset', -this.dashOffsetStart) + + this.title.innerHTML = this.getTitle() + + this.upNextEvents.one('cancel', () => { + clearTimeout(timeout) + cb(true) + }) + + this.upNextEvents.one('playing', () => { + clearTimeout(timeout) + cb(true) + }) + + this.upNextEvents.one('next', () => { + clearTimeout(timeout) + cb(false) + }) + + const update = () => { + now = this.options_.timeout - (new Date().getTime() - start) + + if (now <= 0) { + clearTimeout(timeout) + cb(false) + } else { + newOffset = Math.max(-this.dashOffsetTotal, this.autoplayRing.getAttribute('stroke-dashoffset') - this.chunkSize) + this.autoplayRing.setAttribute('stroke-dashoffset', newOffset) + timeout = setTimeout(update.bind(this), this.interval) + } + + } + + this.container.style.display = 'block' + start = new Date().getTime() + timeout = setTimeout(update.bind(this), this.interval) + } +} +// @ts-ignore-end + +videojs.registerComponent('EndCard', EndCard) + +const Plugin: VideoJSComponentInterface = videojs.getPlugin('plugin') +class UpNextPlugin extends Plugin { + constructor (player: videojs.Player, options: any = {}) { + const settings = { + next: options.next, + getTitle: options.getTitle, + timeout: options.timeout || 5000, + cancelText: options.cancelText || 'Cancel', + headText: options.headText || 'Up Next', + condition: options.condition + } + + super(player, settings) + + this.player.ready(() => { + player.addClass('vjs-upnext') + }) + + player.addChild('EndCard', settings) + } +} + +videojs.registerPlugin('upnext', UpNextPlugin) +export { UpNextPlugin } -- cgit v1.2.3