diff options
author | Chocobozzz <me@florianbigard.com> | 2019-01-23 15:36:45 +0100 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-02-11 09:13:02 +0100 |
commit | 2adfc7ea9a1f858db874df9fe322e7ae833db77c (patch) | |
tree | e27c6ebe01b7c96ea0e053839a38fc1f824d1284 /client/src/assets/player/settings-menu-button.ts | |
parent | 7eeb6a0ba4028d0e20847b846332dd0b7747c7f8 (diff) | |
download | PeerTube-2adfc7ea9a1f858db874df9fe322e7ae833db77c.tar.gz PeerTube-2adfc7ea9a1f858db874df9fe322e7ae833db77c.tar.zst PeerTube-2adfc7ea9a1f858db874df9fe322e7ae833db77c.zip |
Refractor videojs player
Add fake p2p-media-loader plugin
Diffstat (limited to 'client/src/assets/player/settings-menu-button.ts')
-rw-r--r-- | client/src/assets/player/settings-menu-button.ts | 288 |
1 files changed, 0 insertions, 288 deletions
diff --git a/client/src/assets/player/settings-menu-button.ts b/client/src/assets/player/settings-menu-button.ts deleted file mode 100644 index a7aefdcc3..000000000 --- a/client/src/assets/player/settings-menu-button.ts +++ /dev/null | |||
@@ -1,288 +0,0 @@ | |||
1 | // Author: Yanko Shterev | ||
2 | // Thanks https://github.com/yshterev/videojs-settings-menu | ||
3 | |||
4 | // FIXME: something weird with our path definition in tsconfig and typings | ||
5 | // @ts-ignore | ||
6 | import * as videojs from 'video.js' | ||
7 | |||
8 | import { SettingsMenuItem } from './settings-menu-item' | ||
9 | import { VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings' | ||
10 | import { toTitleCase } from './utils' | ||
11 | |||
12 | const Button: VideoJSComponentInterface = videojsUntyped.getComponent('Button') | ||
13 | const Menu: VideoJSComponentInterface = videojsUntyped.getComponent('Menu') | ||
14 | const Component: VideoJSComponentInterface = videojsUntyped.getComponent('Component') | ||
15 | |||
16 | class SettingsButton extends Button { | ||
17 | constructor (player: videojs.Player, options: any) { | ||
18 | super(player, options) | ||
19 | |||
20 | this.playerComponent = player | ||
21 | this.dialog = this.playerComponent.addChild('settingsDialog') | ||
22 | this.dialogEl = this.dialog.el_ | ||
23 | this.menu = null | ||
24 | this.panel = this.dialog.addChild('settingsPanel') | ||
25 | this.panelChild = this.panel.addChild('settingsPanelChild') | ||
26 | |||
27 | this.addClass('vjs-settings') | ||
28 | this.el_.setAttribute('aria-label', 'Settings Button') | ||
29 | |||
30 | // Event handlers | ||
31 | this.addSettingsItemHandler = this.onAddSettingsItem.bind(this) | ||
32 | this.disposeSettingsItemHandler = this.onDisposeSettingsItem.bind(this) | ||
33 | this.playerClickHandler = this.onPlayerClick.bind(this) | ||
34 | this.userInactiveHandler = this.onUserInactive.bind(this) | ||
35 | |||
36 | this.buildMenu() | ||
37 | this.bindEvents() | ||
38 | |||
39 | // Prepare the dialog | ||
40 | this.player().one('play', () => this.hideDialog()) | ||
41 | } | ||
42 | |||
43 | onPlayerClick (event: MouseEvent) { | ||
44 | const element = event.target as HTMLElement | ||
45 | if (element.classList.contains('vjs-settings') || element.parentElement.classList.contains('vjs-settings')) { | ||
46 | return | ||
47 | } | ||
48 | |||
49 | if (!this.dialog.hasClass('vjs-hidden')) { | ||
50 | this.hideDialog() | ||
51 | } | ||
52 | } | ||
53 | |||
54 | onDisposeSettingsItem (event: any, name: string) { | ||
55 | if (name === undefined) { | ||
56 | let children = this.menu.children() | ||
57 | |||
58 | while (children.length > 0) { | ||
59 | children[0].dispose() | ||
60 | this.menu.removeChild(children[0]) | ||
61 | } | ||
62 | |||
63 | this.addClass('vjs-hidden') | ||
64 | } else { | ||
65 | let item = this.menu.getChild(name) | ||
66 | |||
67 | if (item) { | ||
68 | item.dispose() | ||
69 | this.menu.removeChild(item) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | this.hideDialog() | ||
74 | |||
75 | if (this.options_.entries.length === 0) { | ||
76 | this.addClass('vjs-hidden') | ||
77 | } | ||
78 | } | ||
79 | |||
80 | onAddSettingsItem (event: any, data: any) { | ||
81 | const [ entry, options ] = data | ||
82 | |||
83 | this.addMenuItem(entry, options) | ||
84 | this.removeClass('vjs-hidden') | ||
85 | } | ||
86 | |||
87 | onUserInactive () { | ||
88 | if (!this.dialog.hasClass('vjs-hidden')) { | ||
89 | this.hideDialog() | ||
90 | } | ||
91 | } | ||
92 | |||
93 | bindEvents () { | ||
94 | this.playerComponent.on('click', this.playerClickHandler) | ||
95 | this.playerComponent.on('addsettingsitem', this.addSettingsItemHandler) | ||
96 | this.playerComponent.on('disposesettingsitem', this.disposeSettingsItemHandler) | ||
97 | this.playerComponent.on('userinactive', this.userInactiveHandler) | ||
98 | } | ||
99 | |||
100 | buildCSSClass () { | ||
101 | return `vjs-icon-settings ${super.buildCSSClass()}` | ||
102 | } | ||
103 | |||
104 | handleClick () { | ||
105 | if (this.dialog.hasClass('vjs-hidden')) { | ||
106 | this.showDialog() | ||
107 | } else { | ||
108 | this.hideDialog() | ||
109 | } | ||
110 | } | ||
111 | |||
112 | showDialog () { | ||
113 | this.menu.el_.style.opacity = '1' | ||
114 | this.dialog.show() | ||
115 | |||
116 | this.setDialogSize(this.getComponentSize(this.menu)) | ||
117 | } | ||
118 | |||
119 | hideDialog () { | ||
120 | this.dialog.hide() | ||
121 | this.setDialogSize(this.getComponentSize(this.menu)) | ||
122 | this.menu.el_.style.opacity = '1' | ||
123 | this.resetChildren() | ||
124 | } | ||
125 | |||
126 | getComponentSize (element: any) { | ||
127 | let width: number = null | ||
128 | let height: number = null | ||
129 | |||
130 | // Could be component or just DOM element | ||
131 | if (element instanceof Component) { | ||
132 | width = element.el_.offsetWidth | ||
133 | height = element.el_.offsetHeight | ||
134 | |||
135 | // keep width/height as properties for direct use | ||
136 | element.width = width | ||
137 | element.height = height | ||
138 | } else { | ||
139 | width = element.offsetWidth | ||
140 | height = element.offsetHeight | ||
141 | } | ||
142 | |||
143 | return [ width, height ] | ||
144 | } | ||
145 | |||
146 | setDialogSize ([ width, height ]: number[]) { | ||
147 | if (typeof height !== 'number') { | ||
148 | return | ||
149 | } | ||
150 | |||
151 | let offset = this.options_.setup.maxHeightOffset | ||
152 | let maxHeight = this.playerComponent.el_.offsetHeight - offset | ||
153 | |||
154 | if (height > maxHeight) { | ||
155 | height = maxHeight | ||
156 | width += 17 | ||
157 | this.panel.el_.style.maxHeight = `${height}px` | ||
158 | } else if (this.panel.el_.style.maxHeight !== '') { | ||
159 | this.panel.el_.style.maxHeight = '' | ||
160 | } | ||
161 | |||
162 | this.dialogEl.style.width = `${width}px` | ||
163 | this.dialogEl.style.height = `${height}px` | ||
164 | } | ||
165 | |||
166 | buildMenu () { | ||
167 | this.menu = new Menu(this.player()) | ||
168 | this.menu.addClass('vjs-main-menu') | ||
169 | let entries = this.options_.entries | ||
170 | |||
171 | if (entries.length === 0) { | ||
172 | this.addClass('vjs-hidden') | ||
173 | this.panelChild.addChild(this.menu) | ||
174 | return | ||
175 | } | ||
176 | |||
177 | for (let entry of entries) { | ||
178 | this.addMenuItem(entry, this.options_) | ||
179 | } | ||
180 | |||
181 | this.panelChild.addChild(this.menu) | ||
182 | } | ||
183 | |||
184 | addMenuItem (entry: any, options: any) { | ||
185 | const openSubMenu = function (this: any) { | ||
186 | if (videojsUntyped.dom.hasClass(this.el_, 'open')) { | ||
187 | videojsUntyped.dom.removeClass(this.el_, 'open') | ||
188 | } else { | ||
189 | videojsUntyped.dom.addClass(this.el_, 'open') | ||
190 | } | ||
191 | } | ||
192 | |||
193 | options.name = toTitleCase(entry) | ||
194 | let settingsMenuItem = new SettingsMenuItem(this.player(), options, entry, this as any) | ||
195 | |||
196 | this.menu.addChild(settingsMenuItem) | ||
197 | |||
198 | // Hide children to avoid sub menus stacking on top of each other | ||
199 | // or having multiple menus open | ||
200 | settingsMenuItem.on('click', videojs.bind(this, this.hideChildren)) | ||
201 | |||
202 | // Whether to add or remove selected class on the settings sub menu element | ||
203 | settingsMenuItem.on('click', openSubMenu) | ||
204 | } | ||
205 | |||
206 | resetChildren () { | ||
207 | for (let menuChild of this.menu.children()) { | ||
208 | menuChild.reset() | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /** | ||
213 | * Hide all the sub menus | ||
214 | */ | ||
215 | hideChildren () { | ||
216 | for (let menuChild of this.menu.children()) { | ||
217 | menuChild.hideSubMenu() | ||
218 | } | ||
219 | } | ||
220 | |||
221 | } | ||
222 | |||
223 | class SettingsPanel extends Component { | ||
224 | constructor (player: videojs.Player, options: any) { | ||
225 | super(player, options) | ||
226 | } | ||
227 | |||
228 | createEl () { | ||
229 | return super.createEl('div', { | ||
230 | className: 'vjs-settings-panel', | ||
231 | innerHTML: '', | ||
232 | tabIndex: -1 | ||
233 | }) | ||
234 | } | ||
235 | } | ||
236 | |||
237 | class SettingsPanelChild extends Component { | ||
238 | constructor (player: videojs.Player, options: any) { | ||
239 | super(player, options) | ||
240 | } | ||
241 | |||
242 | createEl () { | ||
243 | return super.createEl('div', { | ||
244 | className: 'vjs-settings-panel-child', | ||
245 | innerHTML: '', | ||
246 | tabIndex: -1 | ||
247 | }) | ||
248 | } | ||
249 | } | ||
250 | |||
251 | class SettingsDialog extends Component { | ||
252 | constructor (player: videojs.Player, options: any) { | ||
253 | super(player, options) | ||
254 | this.hide() | ||
255 | } | ||
256 | |||
257 | /** | ||
258 | * Create the component's DOM element | ||
259 | * | ||
260 | * @return {Element} | ||
261 | * @method createEl | ||
262 | */ | ||
263 | createEl () { | ||
264 | const uniqueId = this.id_ | ||
265 | const dialogLabelId = 'TTsettingsDialogLabel-' + uniqueId | ||
266 | const dialogDescriptionId = 'TTsettingsDialogDescription-' + uniqueId | ||
267 | |||
268 | return super.createEl('div', { | ||
269 | className: 'vjs-settings-dialog vjs-modal-overlay', | ||
270 | innerHTML: '', | ||
271 | tabIndex: -1 | ||
272 | }, { | ||
273 | 'role': 'dialog', | ||
274 | 'aria-labelledby': dialogLabelId, | ||
275 | 'aria-describedby': dialogDescriptionId | ||
276 | }) | ||
277 | } | ||
278 | |||
279 | } | ||
280 | |||
281 | SettingsButton.prototype.controlText_ = 'Settings' | ||
282 | |||
283 | Component.registerComponent('SettingsButton', SettingsButton) | ||
284 | Component.registerComponent('SettingsDialog', SettingsDialog) | ||
285 | Component.registerComponent('SettingsPanel', SettingsPanel) | ||
286 | Component.registerComponent('SettingsPanelChild', SettingsPanelChild) | ||
287 | |||
288 | export { SettingsButton, SettingsDialog, SettingsPanel, SettingsPanelChild } | ||