]>
Commit | Line | Data |
---|---|---|
4572c3d0 C |
1 | import videojs from 'video.js' |
2 | import { VideoPlaylistElement } from '@shared/models' | |
3 | import { PlaylistPluginOptions } from '../peertube-videojs-typings' | |
4 | import { PlaylistMenuItem } from './playlist-menu-item' | |
5 | ||
6 | const Component = videojs.getComponent('Component') | |
7 | ||
8 | class 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 | ||
135 | Component.registerComponent('PlaylistMenu', PlaylistMenu) | |
136 | ||
137 | export { PlaylistMenu } |