]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/assets/player/playlist/playlist-menu-item.ts
Merge branch 'release/3.3.0' into develop
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / playlist / playlist-menu-item.ts
1 import videojs from 'video.js'
2 import { secondsToTime } from '@shared/core-utils'
3 import { VideoPlaylistElement } from '@shared/models'
4 import { PlaylistItemOptions } from '../peertube-videojs-typings'
5
6 const Component = videojs.getComponent('Component')
7
8 class PlaylistMenuItem extends Component {
9 private element: VideoPlaylistElement
10
11 constructor (player: videojs.Player, options?: PlaylistItemOptions) {
12 super(player, options as any)
13
14 this.emitTapEvents()
15
16 this.element = options.element
17
18 this.on([ 'click', 'tap' ], () => this.switchPlaylistItem())
19 this.on('keydown', event => this.handleKeyDown(event))
20 }
21
22 createEl () {
23 const options = this.options_ as PlaylistItemOptions
24
25 const li = super.createEl('li', {
26 className: 'vjs-playlist-menu-item',
27 innerHTML: ''
28 }) as HTMLElement
29
30 if (!options.element.video) {
31 li.classList.add('vjs-disabled')
32 }
33
34 const positionBlock = super.createEl('div', {
35 className: 'item-position-block'
36 }) as HTMLElement
37
38 const position = super.createEl('div', {
39 className: 'item-position',
40 innerHTML: options.element.position
41 })
42
43 positionBlock.appendChild(position)
44 li.appendChild(positionBlock)
45
46 if (options.element.video) {
47 this.buildAvailableVideo(li, positionBlock, options)
48 } else {
49 this.buildUnavailableVideo(li)
50 }
51
52 return li
53 }
54
55 setSelected (selected: boolean) {
56 if (selected) this.addClass('vjs-selected')
57 else this.removeClass('vjs-selected')
58 }
59
60 getElement () {
61 return this.element
62 }
63
64 private buildAvailableVideo (li: HTMLElement, positionBlock: HTMLElement, options: PlaylistItemOptions) {
65 const videoElement = options.element
66
67 const player = super.createEl('div', {
68 className: 'item-player'
69 })
70
71 positionBlock.appendChild(player)
72
73 const thumbnail = super.createEl('img', {
74 src: window.location.origin + videoElement.video.thumbnailPath
75 })
76
77 const infoBlock = super.createEl('div', {
78 className: 'info-block'
79 })
80
81 const title = super.createEl('div', {
82 innerHTML: videoElement.video.name,
83 className: 'title'
84 })
85
86 const channel = super.createEl('div', {
87 innerHTML: videoElement.video.channel.displayName,
88 className: 'channel'
89 })
90
91 infoBlock.appendChild(title)
92 infoBlock.appendChild(channel)
93
94 if (videoElement.startTimestamp || videoElement.stopTimestamp) {
95 let html = ''
96
97 if (videoElement.startTimestamp) html += secondsToTime(videoElement.startTimestamp)
98 if (videoElement.stopTimestamp) html += ' - ' + secondsToTime(videoElement.stopTimestamp)
99
100 const timestamps = super.createEl('div', {
101 innerHTML: html,
102 className: 'timestamps'
103 })
104
105 infoBlock.append(timestamps)
106 }
107
108 li.append(thumbnail)
109 li.append(infoBlock)
110 }
111
112 private buildUnavailableVideo (li: HTMLElement) {
113 const block = super.createEl('div', {
114 className: 'item-unavailable',
115 innerHTML: this.player().localize('Unavailable video')
116 })
117
118 li.appendChild(block)
119 }
120
121 private handleKeyDown (event: KeyboardEvent) {
122 if (event.code === 'Space' || event.code === 'Enter') {
123 this.switchPlaylistItem()
124 }
125 }
126
127 private switchPlaylistItem () {
128 const options = this.options_ as PlaylistItemOptions
129
130 options.onClicked()
131 }
132 }
133
134 Component.registerComponent('PlaylistMenuItem', PlaylistMenuItem)
135
136 export { PlaylistMenuItem }