// @ts-ignore import * as videojs from 'video.js' import { VideoJSComponentInterface } from '../peertube-videojs-typings' function getMainTemplate (options: any) { return `
${options.headText}
${options.suspendedText} ` } // @ts-ignore-start const Component = videojs.getComponent('Component') class EndCard extends Component { options_: any dashOffsetTotal = 586 dashOffsetStart = 293 interval = 50 upNextEvents = new videojs.EventTarget() ticks = 0 totalTicks: number container: HTMLElement title: HTMLElement autoplayRing: HTMLElement cancelButton: HTMLElement suspendedMessage: HTMLElement nextButton: HTMLElement constructor (player: videojs.Player, options: any) { super(player, options) this.totalTicks = this.options_.timeout / this.interval player.on('ended', (_: any) => { if (!this.options_.condition()) return player.addClass('vjs-upnext--showing') this.showCard((canceled: boolean) => { player.removeClass('vjs-upnext--showing') this.container.style.display = 'none' if (!canceled) { this.options_.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.suspendedMessage = container.getElementsByClassName('vjs-upnext-suspended')[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 this.autoplayRing.setAttribute('stroke-dasharray', '' + this.dashOffsetStart) this.autoplayRing.setAttribute('stroke-dashoffset', '' + -this.dashOffsetStart) this.title.innerHTML = this.options_.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 goToPercent = (percent: number) => { const newOffset = Math.max(-this.dashOffsetTotal, - this.dashOffsetStart - percent * this.dashOffsetTotal / 2 / 100) this.autoplayRing.setAttribute('stroke-dashoffset', '' + newOffset) } const tick = () => { goToPercent((this.ticks++) * 100 / this.totalTicks) } const update = () => { if (this.options_.suspended()) { this.suspendedMessage.innerText = this.options_.suspendedText goToPercent(0) this.ticks = 0 timeout = setTimeout(update.bind(this), 300) // checks once supsended can be a bit longer } else if (this.ticks >= this.totalTicks) { clearTimeout(timeout) cb(false) } else { this.suspendedMessage.innerText = '' tick() timeout = setTimeout(update.bind(this), this.interval) } } this.container.style.display = 'block' 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', suspendedText: options.suspendedText || 'Autoplay is suspended', condition: options.condition, suspended: options.suspended } super(player, settings) this.player.ready(() => { player.addClass('vjs-upnext') }) player.addChild('EndCard', settings) } } videojs.registerPlugin('upnext', UpNextPlugin) export { UpNextPlugin }