@gcorevideo/player 2.22.0 → 2.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/bottom-gear/bottomgear copy.ejs +10 -0
- package/assets/bottom-gear/bottomgear.ejs +4 -8
- package/assets/bottom-gear/gear-sub-menu.scss +0 -1
- package/assets/bottom-gear/gear.scss +0 -1
- package/assets/clappr-nerd-stats/button.ejs +3 -3
- package/assets/level-selector/button.ejs +2 -4
- package/assets/level-selector/list.ejs +14 -10
- package/assets/level-selector/style.scss +9 -4
- package/assets/playback-rate/list.ejs +5 -5
- package/dist/core.js +1 -2
- package/dist/index.css +1104 -1103
- package/dist/index.js +3849 -3767
- package/dist/player.d.ts +10 -17
- package/dist/plugins/index.css +1541 -1540
- package/dist/plugins/index.js +3949 -3868
- package/docs/api/player.mediacontrol.md +8 -36
- package/docs/api/player.mediacontrol.toggleelement.md +72 -0
- package/docs/api/player.mediacontrolelement.md +1 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +0 -1
- package/lib/plugins/bottom-gear/BottomGear.d.ts +65 -14
- package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
- package/lib/plugins/bottom-gear/BottomGear.js +113 -37
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +2 -3
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
- package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +18 -15
- package/lib/plugins/dvr-controls/DvrControls.js +1 -1
- package/lib/plugins/level-selector/LevelSelector.d.ts +8 -11
- package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
- package/lib/plugins/level-selector/LevelSelector.js +66 -102
- package/lib/plugins/media-control/MediaControl.d.ts +7 -5
- package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
- package/lib/plugins/media-control/MediaControl.js +37 -19
- package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
- package/lib/plugins/picture-in-picture/PictureInPicture.js +7 -2
- package/lib/plugins/playback-rate/PlaybackRate.d.ts +42 -14
- package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
- package/lib/plugins/playback-rate/PlaybackRate.js +101 -83
- package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
- package/lib/testUtils.d.ts +1 -0
- package/lib/testUtils.d.ts.map +1 -1
- package/lib/testUtils.js +13 -0
- package/package.json +1 -1
- package/src/playback/dash-playback/DashPlayback.ts +0 -1
- package/src/plugins/bottom-gear/BottomGear.ts +162 -72
- package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +21 -5
- package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +5 -12
- package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +27 -25
- package/src/plugins/dvr-controls/DvrControls.ts +1 -1
- package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +1 -1
- package/src/plugins/level-selector/LevelSelector.ts +80 -120
- package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +69 -79
- package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +38 -71
- package/src/plugins/media-control/MediaControl.ts +51 -25
- package/src/plugins/media-control/__tests__/MediaControl.test.ts +4 -4
- package/src/plugins/picture-in-picture/PictureInPicture.ts +7 -2
- package/src/plugins/playback-rate/PlaybackRate.ts +136 -108
- package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +84 -37
- package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +55 -6
- package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
- package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
- package/src/testUtils.ts +14 -0
- package/src/typings/vitest.d.ts +1 -0
- package/temp/player.api.json +66 -94
- package/tsconfig.tsbuildinfo +1 -1
- package/docs/api/player.mediacontrol.getcenterpanel.md +0 -18
- package/docs/api/player.mediacontrol.getleftpanel.md +0 -22
- package/docs/api/player.mediacontrol.getrightpanel.md +0 -22
|
@@ -1,31 +1,36 @@
|
|
|
1
|
-
import { UICorePlugin, template, Events as ClapprEvents } from '@clappr/core'
|
|
2
|
-
import { trace } from '@gcorevideo/utils'
|
|
3
|
-
import assert from 'assert'
|
|
1
|
+
import { UICorePlugin, template, Events as ClapprEvents, $ } from '@clappr/core'
|
|
2
|
+
import { trace } from '@gcorevideo/utils'
|
|
3
|
+
import assert from 'assert'
|
|
4
4
|
|
|
5
|
-
import { CLAPPR_VERSION } from '../../build.js'
|
|
5
|
+
import { CLAPPR_VERSION } from '../../build.js'
|
|
6
6
|
|
|
7
|
-
import pluginHtml from '../../../assets/bottom-gear/bottomgear.ejs'
|
|
8
|
-
import '../../../assets/bottom-gear/gear.scss'
|
|
9
|
-
import '../../../assets/bottom-gear/gear-sub-menu.scss'
|
|
10
|
-
import gearIcon from '../../../assets/icons/new/gear.svg'
|
|
11
|
-
import gearHdIcon from '../../../assets/icons/new/gear-hd.svg'
|
|
12
|
-
import { ZeptoResult } from '../../types.js'
|
|
13
|
-
import { MediaControlEvents } from '../media-control/MediaControl'
|
|
7
|
+
import pluginHtml from '../../../assets/bottom-gear/bottomgear.ejs'
|
|
8
|
+
import '../../../assets/bottom-gear/gear.scss'
|
|
9
|
+
import '../../../assets/bottom-gear/gear-sub-menu.scss'
|
|
10
|
+
import gearIcon from '../../../assets/icons/new/gear.svg'
|
|
11
|
+
import gearHdIcon from '../../../assets/icons/new/gear-hd.svg'
|
|
12
|
+
import { ZeptoResult } from '../../types.js'
|
|
13
|
+
import { MediaControlEvents } from '../media-control/MediaControl'
|
|
14
14
|
|
|
15
|
-
const VERSION = '2.19.12'
|
|
15
|
+
const VERSION = '2.19.12'
|
|
16
16
|
|
|
17
|
-
const T = 'plugins.bottom_gear'
|
|
17
|
+
const T = 'plugins.bottom_gear'
|
|
18
|
+
|
|
19
|
+
export enum GearEvents {
|
|
20
|
+
RENDERED = 'rendered',
|
|
21
|
+
}
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* An element inside the gear menu
|
|
21
25
|
* @beta
|
|
26
|
+
* @deprecated
|
|
22
27
|
*/
|
|
23
|
-
export type GearOptionsItem = 'quality' | 'rate' | 'nerd'
|
|
28
|
+
export type GearOptionsItem = 'quality' | 'rate' | 'nerd'
|
|
24
29
|
|
|
25
30
|
/**
|
|
26
31
|
* @deprecated Use {@link GearOptionsItem} instead
|
|
27
32
|
*/
|
|
28
|
-
export type GearItemElement = GearOptionsItem
|
|
33
|
+
export type GearItemElement = GearOptionsItem
|
|
29
34
|
|
|
30
35
|
// TODO disabled if no items added
|
|
31
36
|
|
|
@@ -34,33 +39,90 @@ export type GearItemElement = GearOptionsItem;
|
|
|
34
39
|
* @beta
|
|
35
40
|
* @remarks
|
|
36
41
|
* The plugins provides a base for attaching custom settings UI in the gear menu
|
|
37
|
-
*
|
|
42
|
+
*
|
|
38
43
|
* Depends on:
|
|
39
44
|
*
|
|
40
45
|
* - {@link MediaControl}
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* You can use bottom gear to add custom settings UI to the gear menu.
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { BottomGear } from '@gcorevideo/player/plugins/bottom-gear';
|
|
52
|
+
*
|
|
53
|
+
* class CustomOptionsPlugin extends UICorePlugin {
|
|
54
|
+
* // ...
|
|
55
|
+
*
|
|
56
|
+
* override get events() {
|
|
57
|
+
* return {
|
|
58
|
+
* 'click #my-button': 'doMyAction',
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* private doMyAction() {
|
|
63
|
+
* // ...
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* override render() {
|
|
67
|
+
* const bottomGear = this.core.getPlugin('bottom_gear');
|
|
68
|
+
* if (!bottomGear) {
|
|
69
|
+
* return this;
|
|
70
|
+
* }
|
|
71
|
+
* this.$el.html('<button class="custom-option">Custom option</button>');
|
|
72
|
+
* // Put rendered element into the gear menu
|
|
73
|
+
* bottomGear.addItem('custom').html(this.$el)
|
|
74
|
+
* return this;
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* // alternatively, add an option with a submenu
|
|
78
|
+
* override render() {
|
|
79
|
+
* this.$el.html(template(templateHtml)({
|
|
80
|
+
* // ...
|
|
81
|
+
* })));
|
|
82
|
+
* return this;
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* private addGearOption() {
|
|
86
|
+
* this.core.getPlugin('bottom_gear')
|
|
87
|
+
* .addItem('custom', this.$el)
|
|
88
|
+
* .html($('<button class="custom-option">Custom option</button>'))
|
|
89
|
+
* }
|
|
90
|
+
*
|
|
91
|
+
* override bindEvents() {
|
|
92
|
+
* this.listenToOnce(this.core, ClapprEvents.CORE_READY, () => {
|
|
93
|
+
* const bottomGear = this.core.getPlugin('bottom_gear');
|
|
94
|
+
* assert(bottomGear, 'bottom_gear plugin is required');
|
|
95
|
+
* // simple case
|
|
96
|
+
* this.listenTo(bottomGear, GearEvents.RENDERED, this.render);
|
|
97
|
+
* // or with a submenu
|
|
98
|
+
* this.listenTo(bottomGear, GearEvents.RENDERED, this.addGearOption);
|
|
99
|
+
* });
|
|
100
|
+
* }
|
|
101
|
+
* }
|
|
102
|
+
* ```
|
|
41
103
|
*/
|
|
42
104
|
export class BottomGear extends UICorePlugin {
|
|
43
|
-
private isHd = false
|
|
105
|
+
private isHd = false
|
|
44
106
|
|
|
45
107
|
/**
|
|
46
108
|
* @internal
|
|
47
109
|
*/
|
|
48
110
|
get name() {
|
|
49
|
-
return 'bottom_gear'
|
|
111
|
+
return 'bottom_gear'
|
|
50
112
|
}
|
|
51
113
|
|
|
52
114
|
/**
|
|
53
115
|
* @internal
|
|
54
116
|
*/
|
|
55
117
|
get supportedVersion() {
|
|
56
|
-
return { min: CLAPPR_VERSION }
|
|
118
|
+
return { min: CLAPPR_VERSION }
|
|
57
119
|
}
|
|
58
120
|
|
|
59
121
|
/**
|
|
60
122
|
* @internal
|
|
61
123
|
*/
|
|
62
124
|
static get version() {
|
|
63
|
-
return VERSION
|
|
125
|
+
return VERSION
|
|
64
126
|
}
|
|
65
127
|
|
|
66
128
|
private static readonly template = template(pluginHtml)
|
|
@@ -70,8 +132,8 @@ export class BottomGear extends UICorePlugin {
|
|
|
70
132
|
*/
|
|
71
133
|
override get attributes() {
|
|
72
134
|
return {
|
|
73
|
-
|
|
74
|
-
}
|
|
135
|
+
class: 'media-control-gear',
|
|
136
|
+
}
|
|
75
137
|
}
|
|
76
138
|
|
|
77
139
|
/**
|
|
@@ -79,94 +141,122 @@ export class BottomGear extends UICorePlugin {
|
|
|
79
141
|
*/
|
|
80
142
|
override get events() {
|
|
81
143
|
return {
|
|
82
|
-
'click
|
|
83
|
-
}
|
|
144
|
+
'click #gear-button': 'toggleGearMenu',
|
|
145
|
+
}
|
|
84
146
|
}
|
|
85
147
|
|
|
86
148
|
/**
|
|
87
149
|
* @internal
|
|
88
150
|
*/
|
|
89
151
|
override bindEvents() {
|
|
90
|
-
this.
|
|
91
|
-
this.listenTo(
|
|
152
|
+
this.listenToOnce(this.core, ClapprEvents.CORE_READY, this.onCoreReady)
|
|
153
|
+
this.listenTo(
|
|
154
|
+
this.core,
|
|
155
|
+
ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
156
|
+
this.onActiveContainerChanged,
|
|
157
|
+
)
|
|
92
158
|
}
|
|
93
159
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
160
|
+
addItem(name: string, $subMenu?: ZeptoResult): ZeptoResult {
|
|
161
|
+
const $existingItem = this.$el.find(`#gear-options li[data-${name}`)
|
|
162
|
+
if ($existingItem.length) {
|
|
163
|
+
trace(`${T} addItem already exists`, { name })
|
|
164
|
+
return $existingItem
|
|
165
|
+
}
|
|
166
|
+
const $item = $('<li></li>')
|
|
167
|
+
.attr(`data-${name}`, '')
|
|
168
|
+
.appendTo(this.$el.find('#gear-options'))
|
|
169
|
+
if ($subMenu) {
|
|
170
|
+
trace(`${T} addItem adding submenu`, { name })
|
|
171
|
+
$subMenu
|
|
172
|
+
.addClass('gear-sub-menu-wrapper')
|
|
173
|
+
.hide()
|
|
174
|
+
.appendTo(this.$el.find('#gear-options-wrapper'))
|
|
175
|
+
$item.on('click', (e: MouseEvent) => {
|
|
176
|
+
trace(`${T} addItem submenu clicked`, { name })
|
|
177
|
+
e.stopPropagation()
|
|
178
|
+
$subMenu.show()
|
|
179
|
+
this.$el.find('#gear-options').hide()
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
return $item
|
|
110
183
|
}
|
|
111
184
|
|
|
112
185
|
private onActiveContainerChanged() {
|
|
113
|
-
trace(`${T} onActiveContainerChanged`)
|
|
114
|
-
this.bindContainerEvents()
|
|
186
|
+
trace(`${T} onActiveContainerChanged`)
|
|
187
|
+
this.bindContainerEvents()
|
|
115
188
|
}
|
|
116
189
|
|
|
117
190
|
private bindContainerEvents() {
|
|
118
|
-
trace(`${T} bindContainerEvents`)
|
|
119
|
-
this.listenTo(
|
|
191
|
+
trace(`${T} bindContainerEvents`)
|
|
192
|
+
this.listenTo(
|
|
193
|
+
this.core.activeContainer,
|
|
194
|
+
ClapprEvents.CONTAINER_HIGHDEFINITIONUPDATE,
|
|
195
|
+
this.highDefinitionUpdate,
|
|
196
|
+
)
|
|
120
197
|
}
|
|
121
198
|
|
|
122
199
|
private highDefinitionUpdate(isHd: boolean) {
|
|
123
|
-
trace(`${T} highDefinitionUpdate`, { isHd })
|
|
124
|
-
this.isHd = isHd
|
|
125
|
-
this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon)
|
|
200
|
+
trace(`${T} highDefinitionUpdate`, { isHd })
|
|
201
|
+
this.isHd = isHd
|
|
202
|
+
this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon)
|
|
126
203
|
}
|
|
127
204
|
|
|
128
205
|
/**
|
|
129
206
|
* @internal
|
|
130
207
|
*/
|
|
131
208
|
override render() {
|
|
132
|
-
|
|
209
|
+
trace(`${T} render`)
|
|
210
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
211
|
+
if (!mediaControl) {
|
|
212
|
+
return this // TODO test
|
|
213
|
+
}
|
|
214
|
+
const icon = this.isHd ? gearHdIcon : gearIcon
|
|
215
|
+
this.$el
|
|
216
|
+
.html(BottomGear.template({ icon }))
|
|
217
|
+
.find('#gear-sub-menu-wrapper')
|
|
218
|
+
.hide()
|
|
219
|
+
|
|
220
|
+
// TODO make non-clickable when there are no items
|
|
221
|
+
mediaControl.putElement('gear', this.$el)
|
|
133
222
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'rate',
|
|
138
|
-
'nerd',
|
|
139
|
-
];
|
|
140
|
-
const icon = this.isHd ? gearHdIcon : gearIcon;
|
|
141
|
-
this.$el.html(BottomGear.template({ icon, items }));
|
|
223
|
+
setTimeout(() => {
|
|
224
|
+
this.trigger(GearEvents.RENDERED)
|
|
225
|
+
}, 0)
|
|
142
226
|
|
|
143
|
-
|
|
144
|
-
mediaControl.trigger(MediaControlEvents.MEDIACONTROL_GEAR_RENDERED);
|
|
145
|
-
return this;
|
|
227
|
+
return this
|
|
146
228
|
}
|
|
147
229
|
|
|
148
230
|
/**
|
|
149
|
-
*
|
|
150
|
-
* It fires the {@link MediaControlEvents.MEDIACONTROL_GEAR_RENDERED | MEDIACONTROL_GEAR_RENDERED} event,
|
|
151
|
-
* which the plugins that attach to the gear menu can listen to to re-render themselves.
|
|
231
|
+
* Collapses any submenu open back to the gear menu
|
|
152
232
|
*/
|
|
153
233
|
refresh() {
|
|
154
|
-
this.
|
|
155
|
-
this.$el.find('
|
|
234
|
+
this.$el.find('.gear-sub-menu-wrapper').hide()
|
|
235
|
+
this.$el.find('#gear-options').show()
|
|
156
236
|
}
|
|
157
237
|
|
|
158
238
|
private toggleGearMenu() {
|
|
159
|
-
this.$el.find('
|
|
239
|
+
this.$el.find('#gear-options-wrapper').toggle()
|
|
160
240
|
}
|
|
161
241
|
|
|
162
242
|
private hide() {
|
|
163
|
-
this.$el.find('
|
|
243
|
+
this.$el.find('#gear-options-wrapper').hide()
|
|
164
244
|
}
|
|
165
245
|
|
|
166
246
|
private onCoreReady() {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.listenTo(
|
|
247
|
+
trace(`${T} onCoreReady`)
|
|
248
|
+
const mediaControl = this.core.getPlugin('media_control')
|
|
249
|
+
assert(mediaControl, 'media_control plugin is required')
|
|
250
|
+
this.listenTo(
|
|
251
|
+
mediaControl,
|
|
252
|
+
ClapprEvents.MEDIACONTROL_RENDERED,
|
|
253
|
+
this.onMediaControlRendered,
|
|
254
|
+
)
|
|
255
|
+
this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private onMediaControlRendered() {
|
|
259
|
+
trace(`${T} onMediaControlRendered`)
|
|
260
|
+
this.render()
|
|
171
261
|
}
|
|
172
262
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { MockedFunction, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { BottomGear } from '../BottomGear'
|
|
3
|
+
import { BottomGear, GearEvents } from '../BottomGear'
|
|
4
4
|
import { createMockCore, createMockMediaControl } from '../../../testUtils'
|
|
5
|
-
import { MediaControlEvents } from '../../media-control/MediaControl'
|
|
6
5
|
|
|
7
6
|
describe('BottomGear', () => {
|
|
8
7
|
let mediaControl: any
|
|
@@ -19,16 +18,33 @@ describe('BottomGear', () => {
|
|
|
19
18
|
)
|
|
20
19
|
bottomGear = new BottomGear(core)
|
|
21
20
|
onGearRendered = vi.fn()
|
|
22
|
-
|
|
21
|
+
bottomGear.on(GearEvents.RENDERED, onGearRendered, null)
|
|
23
22
|
bottomGear.render()
|
|
24
23
|
})
|
|
25
24
|
it('should render', () => {
|
|
26
25
|
expect(bottomGear.el.innerHTML).toMatchSnapshot()
|
|
27
26
|
})
|
|
28
27
|
it('should attach to media control', () => {
|
|
29
|
-
expect(mediaControl.putElement).toHaveBeenCalledWith('gear', bottomGear
|
|
28
|
+
expect(mediaControl.putElement).toHaveBeenCalledWith('gear', bottomGear.$el)
|
|
30
29
|
})
|
|
31
|
-
it('should emit event', () => {
|
|
30
|
+
it('should emit event in the next cycle', async () => {
|
|
31
|
+
expect(onGearRendered).not.toHaveBeenCalled()
|
|
32
|
+
await new Promise((resolve) => setTimeout(resolve, 0))
|
|
32
33
|
expect(onGearRendered).toHaveBeenCalled()
|
|
33
34
|
})
|
|
35
|
+
it('should render the gear menu hidden', () => {
|
|
36
|
+
expect(bottomGear.$el.find('#gear-options-wrapper').css('display')).toBe(
|
|
37
|
+
'none',
|
|
38
|
+
)
|
|
39
|
+
})
|
|
40
|
+
describe('when clicked', () => {
|
|
41
|
+
beforeEach(() => {
|
|
42
|
+
bottomGear.$el.find('#gear-button').click()
|
|
43
|
+
})
|
|
44
|
+
it('should toggle the gear menu', () => {
|
|
45
|
+
expect(bottomGear.$el.find('#gear-options-wrapper').css('display')).toBe(
|
|
46
|
+
'block',
|
|
47
|
+
)
|
|
48
|
+
})
|
|
49
|
+
})
|
|
34
50
|
})
|
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`BottomGear > should render 1`] = `
|
|
4
|
-
"<button type="button" class="
|
|
4
|
+
"<button type="button" class="media-control-button gplayer-lite-btn gcore-skin-button-color gear-icon" id="gear-button">
|
|
5
5
|
/assets/icons/new/gear.svg
|
|
6
6
|
</button>
|
|
7
|
-
<div class="gear-wrapper gcore-skin-bg-color">
|
|
8
|
-
<ul class="gear-options-list" id="gear-options">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<li data-rate=""></li>
|
|
13
|
-
|
|
14
|
-
<li data-nerd=""></li>
|
|
15
|
-
|
|
16
|
-
</ul>
|
|
17
|
-
</div>"
|
|
7
|
+
<div class="gear-wrapper gcore-skin-bg-color" id="gear-options-wrapper" style="display: none;">
|
|
8
|
+
<ul class="gear-options-list" id="gear-options"></ul>
|
|
9
|
+
</div>
|
|
10
|
+
"
|
|
18
11
|
`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UICorePlugin, Events, template, Core, Container } from '@clappr/core'
|
|
2
|
-
import { reportError } from '@gcorevideo/utils'
|
|
2
|
+
import { reportError, trace } from '@gcorevideo/utils'
|
|
3
3
|
import Mousetrap from 'mousetrap'
|
|
4
4
|
|
|
5
5
|
import { CLAPPR_VERSION } from '../../build.js'
|
|
@@ -24,8 +24,8 @@ import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss'
|
|
|
24
24
|
import pluginHtml from '../../../assets/clappr-nerd-stats/clappr-nerd-stats.ejs'
|
|
25
25
|
import buttonHtml from '../../../assets/clappr-nerd-stats/button.ejs'
|
|
26
26
|
import statsIcon from '../../../assets/icons/new/stats.svg'
|
|
27
|
-
import { BottomGear } from '../bottom-gear/BottomGear.js'
|
|
28
|
-
import { MediaControl
|
|
27
|
+
import { BottomGear, GearEvents } from '../bottom-gear/BottomGear.js'
|
|
28
|
+
import { MediaControl } from '../media-control/MediaControl.js'
|
|
29
29
|
import assert from 'assert'
|
|
30
30
|
|
|
31
31
|
const qualityClasses = [
|
|
@@ -114,7 +114,7 @@ type Metrics = BaseMetrics & {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
const T = 'plugins.clappr_nerd_stats'
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* `PLUGIN` that displays useful network-related statistics.
|
|
@@ -123,8 +123,6 @@ type Metrics = BaseMetrics & {
|
|
|
123
123
|
* @remarks
|
|
124
124
|
* Depends on:
|
|
125
125
|
*
|
|
126
|
-
* - {@link MediaControl}
|
|
127
|
-
*
|
|
128
126
|
* - {@link BottomGear}
|
|
129
127
|
*
|
|
130
128
|
* - {@link ClapprStats}
|
|
@@ -151,6 +149,8 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
151
149
|
|
|
152
150
|
private iconPosition: IconPosition
|
|
153
151
|
|
|
152
|
+
private static readonly buttonTemplate = template(buttonHtml)
|
|
153
|
+
|
|
154
154
|
/**
|
|
155
155
|
* @internal
|
|
156
156
|
*/
|
|
@@ -224,17 +224,15 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
224
224
|
* @internal
|
|
225
225
|
*/
|
|
226
226
|
override bindEvents() {
|
|
227
|
-
|
|
228
|
-
assert(mediaControl, 'media_control plugin is required')
|
|
229
|
-
this.listenToOnce(this.core, Events.CORE_READY, this.init)
|
|
230
|
-
this.listenTo(
|
|
231
|
-
mediaControl,
|
|
232
|
-
MediaControlEvents.MEDIACONTROL_GEAR_RENDERED,
|
|
233
|
-
this.addToBottomGear,
|
|
234
|
-
)
|
|
227
|
+
this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady)
|
|
235
228
|
}
|
|
236
229
|
|
|
237
|
-
private
|
|
230
|
+
private onCoreReady() {
|
|
231
|
+
const bottomGear = this.core.getPlugin('bottom_gear') as BottomGear
|
|
232
|
+
assert(bottomGear, 'bottom_gear plugin is required')
|
|
233
|
+
|
|
234
|
+
this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear)
|
|
235
|
+
|
|
238
236
|
this.container = this.core.activeContainer
|
|
239
237
|
const clapprStats = this.container?.getPlugin('clappr_stats')
|
|
240
238
|
|
|
@@ -375,6 +373,7 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
375
373
|
* @internal
|
|
376
374
|
*/
|
|
377
375
|
override render() {
|
|
376
|
+
trace(`${T} render`)
|
|
378
377
|
// TODO append to the container
|
|
379
378
|
this.core.$el.append(this.$el[0])
|
|
380
379
|
this.hide()
|
|
@@ -383,17 +382,20 @@ export class ClapprNerdStats extends UICorePlugin {
|
|
|
383
382
|
}
|
|
384
383
|
|
|
385
384
|
private addToBottomGear() {
|
|
385
|
+
trace(`${T} addToBottomGear`)
|
|
386
386
|
const gear = this.core.getPlugin('bottom_gear') as BottomGear
|
|
387
|
-
const $
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
387
|
+
const $button = gear
|
|
388
|
+
.addItem('nerd')
|
|
389
|
+
.html(
|
|
390
|
+
ClapprNerdStats.buttonTemplate({
|
|
391
|
+
icon: statsIcon,
|
|
392
|
+
i18n: this.core.i18n,
|
|
393
|
+
}),
|
|
394
|
+
)
|
|
395
|
+
.on('click', (e: MouseEvent) => {
|
|
396
|
+
e.stopPropagation()
|
|
397
|
+
this.toggle()
|
|
398
|
+
})
|
|
397
399
|
}
|
|
398
400
|
|
|
399
401
|
private clearCustomMetrics() {
|
|
@@ -50,7 +50,7 @@ describe('DvrControls', () => {
|
|
|
50
50
|
expect(mediaControl.toggleElement).toHaveBeenCalledWith('position', false)
|
|
51
51
|
})
|
|
52
52
|
it('should render to the media control', () => {
|
|
53
|
-
expect(mediaControl.putElement).toHaveBeenCalledWith('dvr', dvrControls
|
|
53
|
+
expect(mediaControl.putElement).toHaveBeenCalledWith('dvr', dvrControls.$el)
|
|
54
54
|
})
|
|
55
55
|
})
|
|
56
56
|
describe('when back_to_live button is clicked', () => {
|