]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/assets/player/playlist/playlist-menu.ts
Add playlist embed E2E test
[github/Chocobozzz/PeerTube.git] / client / src / assets / player / playlist / playlist-menu.ts
CommitLineData
4572c3d0
C
1import videojs from 'video.js'
2import { VideoPlaylistElement } from '@shared/models'
3import { PlaylistPluginOptions } from '../peertube-videojs-typings'
4import { PlaylistMenuItem } from './playlist-menu-item'
5
6const Component = videojs.getComponent('Component')
7
8class PlaylistMenu extends Component {
9 private menuItems: PlaylistMenuItem[]
10
11 constructor (player: videojs.Player, options?: PlaylistPluginOptions) {
12 super(player, options as any)
13
56674bb9
C
14 const self = this
15
16 function userInactiveHandler () {
17 self.close()
18 }
19
20 this.el().addEventListener('mouseenter', () => {
21 this.player().off('userinactive', userInactiveHandler)
22 })
23
24 this.el().addEventListener('mouseleave', () => {
25 this.player().one('userinactive', userInactiveHandler)
4572c3d0
C
26 })
27
28 this.player().on('click', event => {
29 let current = event.target as HTMLElement
30
31 do {
32 if (
33 current.classList.contains('vjs-playlist-menu') ||
34 current.classList.contains('vjs-playlist-button')
35 ) {
36 return
37 }
38
39 current = current.parentElement
40 } while (current)
41
42 this.close()
43 })
44 }
45
46 createEl () {
47 this.menuItems = []
48
49 const options = this.getOptions()
50
51 const menu = super.createEl('div', {
52 className: 'vjs-playlist-menu',
53 innerHTML: '',
54 tabIndex: -1
55 })
56
57 const header = super.createEl('div', {
58 className: 'header'
59 })
60
61 const headerLeft = super.createEl('div')
62
63 const leftTitle = super.createEl('div', {
64 innerHTML: options.playlist.displayName,
65 className: 'title'
66 })
67
7f90579c 68 const playlistChannel = options.playlist.videoChannel
4572c3d0 69 const leftSubtitle = super.createEl('div', {
7f90579c
C
70 innerHTML: playlistChannel
71 ? this.player().localize('By {1}', [ playlistChannel.displayName ])
72 : '',
4572c3d0
C
73 className: 'channel'
74 })
75
76 headerLeft.appendChild(leftTitle)
77 headerLeft.appendChild(leftSubtitle)
78
79 const tick = super.createEl('div', {
80 className: 'cross'
81 })
82 tick.addEventListener('click', () => this.close())
83
84 header.appendChild(headerLeft)
85 header.appendChild(tick)
86
87 const list = super.createEl('ol')
88
89 for (const playlistElement of options.elements) {
90 const item = new PlaylistMenuItem(this.player(), {
91 element: playlistElement,
92 onClicked: () => this.onItemClicked(playlistElement)
93 })
94
95 list.appendChild(item.el())
96
97 this.menuItems.push(item)
98 }
99
100 menu.appendChild(header)
101 menu.appendChild(list)
102
103 return menu
104 }
105
106 update () {
107 const options = this.getOptions()
108
109 this.updateSelected(options.getCurrentPosition())
110 }
111
112 open () {
113 this.player().addClass('playlist-menu-displayed')
114 }
115
116 close () {
117 this.player().removeClass('playlist-menu-displayed')
118 }
119
120 updateSelected (newPosition: number) {
121 for (const item of this.menuItems) {
122 item.setSelected(item.getElement().position === newPosition)
123 }
124 }
125
126 private getOptions () {
127 return this.options_ as PlaylistPluginOptions
128 }
129
130 private onItemClicked (element: VideoPlaylistElement) {
131 this.getOptions().onItemClicked(element)
132 }
133}
134
135Component.registerComponent('PlaylistMenu', PlaylistMenu)
136
137export { PlaylistMenu }