@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.
Files changed (68) hide show
  1. package/assets/bottom-gear/bottomgear copy.ejs +10 -0
  2. package/assets/bottom-gear/bottomgear.ejs +4 -8
  3. package/assets/bottom-gear/gear-sub-menu.scss +0 -1
  4. package/assets/bottom-gear/gear.scss +0 -1
  5. package/assets/clappr-nerd-stats/button.ejs +3 -3
  6. package/assets/level-selector/button.ejs +2 -4
  7. package/assets/level-selector/list.ejs +14 -10
  8. package/assets/level-selector/style.scss +9 -4
  9. package/assets/playback-rate/list.ejs +5 -5
  10. package/dist/core.js +1 -2
  11. package/dist/index.css +1104 -1103
  12. package/dist/index.js +3849 -3767
  13. package/dist/player.d.ts +10 -17
  14. package/dist/plugins/index.css +1541 -1540
  15. package/dist/plugins/index.js +3949 -3868
  16. package/docs/api/player.mediacontrol.md +8 -36
  17. package/docs/api/player.mediacontrol.toggleelement.md +72 -0
  18. package/docs/api/player.mediacontrolelement.md +1 -1
  19. package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
  20. package/lib/playback/dash-playback/DashPlayback.js +0 -1
  21. package/lib/plugins/bottom-gear/BottomGear.d.ts +65 -14
  22. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  23. package/lib/plugins/bottom-gear/BottomGear.js +113 -37
  24. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts +2 -3
  25. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.d.ts.map +1 -1
  26. package/lib/plugins/clappr-nerd-stats/ClapprNerdStats.js +18 -15
  27. package/lib/plugins/dvr-controls/DvrControls.js +1 -1
  28. package/lib/plugins/level-selector/LevelSelector.d.ts +8 -11
  29. package/lib/plugins/level-selector/LevelSelector.d.ts.map +1 -1
  30. package/lib/plugins/level-selector/LevelSelector.js +66 -102
  31. package/lib/plugins/media-control/MediaControl.d.ts +7 -5
  32. package/lib/plugins/media-control/MediaControl.d.ts.map +1 -1
  33. package/lib/plugins/media-control/MediaControl.js +37 -19
  34. package/lib/plugins/picture-in-picture/PictureInPicture.d.ts.map +1 -1
  35. package/lib/plugins/picture-in-picture/PictureInPicture.js +7 -2
  36. package/lib/plugins/playback-rate/PlaybackRate.d.ts +42 -14
  37. package/lib/plugins/playback-rate/PlaybackRate.d.ts.map +1 -1
  38. package/lib/plugins/playback-rate/PlaybackRate.js +101 -83
  39. package/lib/plugins/subtitles/ClosedCaptions.js +1 -1
  40. package/lib/testUtils.d.ts +1 -0
  41. package/lib/testUtils.d.ts.map +1 -1
  42. package/lib/testUtils.js +13 -0
  43. package/package.json +1 -1
  44. package/src/playback/dash-playback/DashPlayback.ts +0 -1
  45. package/src/plugins/bottom-gear/BottomGear.ts +162 -72
  46. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +21 -5
  47. package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +5 -12
  48. package/src/plugins/clappr-nerd-stats/ClapprNerdStats.ts +27 -25
  49. package/src/plugins/dvr-controls/DvrControls.ts +1 -1
  50. package/src/plugins/dvr-controls/__tests__/DvrControls.test.ts +1 -1
  51. package/src/plugins/level-selector/LevelSelector.ts +80 -120
  52. package/src/plugins/level-selector/__tests__/LevelSelector.test.ts +69 -79
  53. package/src/plugins/level-selector/__tests__/__snapshots__/LevelSelector.test.ts.snap +38 -71
  54. package/src/plugins/media-control/MediaControl.ts +51 -25
  55. package/src/plugins/media-control/__tests__/MediaControl.test.ts +4 -4
  56. package/src/plugins/picture-in-picture/PictureInPicture.ts +7 -2
  57. package/src/plugins/playback-rate/PlaybackRate.ts +136 -108
  58. package/src/plugins/playback-rate/__tests__/PlaybackRate.test.ts +84 -37
  59. package/src/plugins/playback-rate/__tests__/__snapshots__/PlaybackRate.test.ts.snap +55 -6
  60. package/src/plugins/subtitles/ClosedCaptions.ts +1 -1
  61. package/src/plugins/subtitles/__tests__/ClosedCaptions.test.ts +1 -1
  62. package/src/testUtils.ts +14 -0
  63. package/src/typings/vitest.d.ts +1 -0
  64. package/temp/player.api.json +66 -94
  65. package/tsconfig.tsbuildinfo +1 -1
  66. package/docs/api/player.mediacontrol.getcenterpanel.md +0 -18
  67. package/docs/api/player.mediacontrol.getleftpanel.md +0 -22
  68. package/docs/api/player.mediacontrol.getrightpanel.md +0 -22
@@ -215,20 +215,6 @@ Description
215
215
  **_(BETA)_** Enable the user interaction disabled earlier
216
216
 
217
217
 
218
- </td></tr>
219
- <tr><td>
220
-
221
- [getCenterPanel()](./player.mediacontrol.getcenterpanel.md)
222
-
223
-
224
- </td><td>
225
-
226
-
227
- </td><td>
228
-
229
- **_(BETA)_**
230
-
231
-
232
218
  </td></tr>
233
219
  <tr><td>
234
220
 
@@ -246,21 +232,7 @@ Description
246
232
  </td></tr>
247
233
  <tr><td>
248
234
 
249
- [getLeftPanel()](./player.mediacontrol.getleftpanel.md)
250
-
251
-
252
- </td><td>
253
-
254
-
255
- </td><td>
256
-
257
- **_(BETA)_** Get the left panel area to append custom elements to
258
-
259
-
260
- </td></tr>
261
- <tr><td>
262
-
263
- [getRightPanel()](./player.mediacontrol.getrightpanel.md)
235
+ [putElement(name, element)](./player.mediacontrol.putelement.md)
264
236
 
265
237
 
266
238
  </td><td>
@@ -268,13 +240,13 @@ Description
268
240
 
269
241
  </td><td>
270
242
 
271
- **_(BETA)_** Get the right panel area to append custom elements to
243
+ **_(BETA)_**
272
244
 
273
245
 
274
246
  </td></tr>
275
247
  <tr><td>
276
248
 
277
- [putElement(name, element)](./player.mediacontrol.putelement.md)
249
+ [setInitialVolume()](./player.mediacontrol.setinitialvolume.md)
278
250
 
279
251
 
280
252
  </td><td>
@@ -282,13 +254,13 @@ Description
282
254
 
283
255
  </td><td>
284
256
 
285
- **_(BETA)_**
257
+ **_(BETA)_** Set the initial volume, which is preserved when playback is interrupted by an advertisement
286
258
 
287
259
 
288
260
  </td></tr>
289
261
  <tr><td>
290
262
 
291
- [setInitialVolume()](./player.mediacontrol.setinitialvolume.md)
263
+ [setVolume(value, isInitialVolume)](./player.mediacontrol.setvolume.md)
292
264
 
293
265
 
294
266
  </td><td>
@@ -296,13 +268,13 @@ Description
296
268
 
297
269
  </td><td>
298
270
 
299
- **_(BETA)_** Set the initial volume, which is preserved when playback is interrupted by an advertisement
271
+ **_(BETA)_** Set the volume
300
272
 
301
273
 
302
274
  </td></tr>
303
275
  <tr><td>
304
276
 
305
- [setVolume(value, isInitialVolume)](./player.mediacontrol.setvolume.md)
277
+ [toggleElement(name, show)](./player.mediacontrol.toggleelement.md)
306
278
 
307
279
 
308
280
  </td><td>
@@ -310,7 +282,7 @@ Description
310
282
 
311
283
  </td><td>
312
284
 
313
- **_(BETA)_** Set the volume
285
+ **_(BETA)_** Toggle the visibility of a media control element
314
286
 
315
287
 
316
288
  </td></tr>
@@ -0,0 +1,72 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@gcorevideo/player](./player.md) &gt; [MediaControl](./player.mediacontrol.md) &gt; [toggleElement](./player.mediacontrol.toggleelement.md)
4
+
5
+ ## MediaControl.toggleElement() method
6
+
7
+ > This API is provided as a beta preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
8
+ >
9
+
10
+ Toggle the visibility of a media control element
11
+
12
+ **Signature:**
13
+
14
+ ```typescript
15
+ toggleElement(name: MediaControlElement, show: boolean): void;
16
+ ```
17
+
18
+ ## Parameters
19
+
20
+ <table><thead><tr><th>
21
+
22
+ Parameter
23
+
24
+
25
+ </th><th>
26
+
27
+ Type
28
+
29
+
30
+ </th><th>
31
+
32
+ Description
33
+
34
+
35
+ </th></tr></thead>
36
+ <tbody><tr><td>
37
+
38
+ name
39
+
40
+
41
+ </td><td>
42
+
43
+ [MediaControlElement](./player.mediacontrolelement.md)
44
+
45
+
46
+ </td><td>
47
+
48
+ The name of the media control element
49
+
50
+
51
+ </td></tr>
52
+ <tr><td>
53
+
54
+ show
55
+
56
+
57
+ </td><td>
58
+
59
+ boolean
60
+
61
+
62
+ </td><td>
63
+
64
+ Whether to show or hide the element
65
+
66
+
67
+ </td></tr>
68
+ </tbody></table>
69
+ **Returns:**
70
+
71
+ void
72
+
@@ -12,5 +12,5 @@ Media control elements, mount points for additional plugins
12
12
  **Signature:**
13
13
 
14
14
  ```typescript
15
- export type MediaControlElement = 'audiotracks' | 'clipText' | 'gear' | 'pip' | 'playbackRate' | 'seekBarContainer' | 'cc';
15
+ export type MediaControlElement = 'audiotracks' | 'cc' | 'clipText' | 'dvr' | 'duration' | 'gear' | 'pip' | 'playbackRate' | 'position' | 'seekBarContainer';
16
16
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/dash-playback/DashPlayback.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DashPlayback.d.ts","sourceRoot":"","sources":["../../../src/playback/dash-playback/DashPlayback.ts"],"names":[],"mappings":"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"}
@@ -469,7 +469,6 @@ export default class DashPlayback extends BasePlayback {
469
469
  get audioTracks() {
470
470
  assert.ok(this._dash, 'DASH.js MediaPlayer is not initialized');
471
471
  const tracks = this._dash.getTracksFor('audio');
472
- trace(`${T} get audioTracks`, { tracks });
473
472
  return tracks.map(toClapprTrack);
474
473
  }
475
474
  // @ts-expect-error
@@ -2,9 +2,13 @@ import { UICorePlugin } from '@clappr/core';
2
2
  import '../../../assets/bottom-gear/gear.scss';
3
3
  import '../../../assets/bottom-gear/gear-sub-menu.scss';
4
4
  import { ZeptoResult } from '../../types.js';
5
+ export declare enum GearEvents {
6
+ RENDERED = "rendered"
7
+ }
5
8
  /**
6
9
  * An element inside the gear menu
7
10
  * @beta
11
+ * @deprecated
8
12
  */
9
13
  export type GearOptionsItem = 'quality' | 'rate' | 'nerd';
10
14
  /**
@@ -20,6 +24,63 @@ export type GearItemElement = GearOptionsItem;
20
24
  * Depends on:
21
25
  *
22
26
  * - {@link MediaControl}
27
+ *
28
+ * @example
29
+ * You can use bottom gear to add custom settings UI to the gear menu.
30
+ *
31
+ * ```ts
32
+ * import { BottomGear } from '@gcorevideo/player/plugins/bottom-gear';
33
+ *
34
+ * class CustomOptionsPlugin extends UICorePlugin {
35
+ * // ...
36
+ *
37
+ * override get events() {
38
+ * return {
39
+ * 'click #my-button': 'doMyAction',
40
+ * }
41
+ * }
42
+ *
43
+ * private doMyAction() {
44
+ * // ...
45
+ * }
46
+ *
47
+ * override render() {
48
+ * const bottomGear = this.core.getPlugin('bottom_gear');
49
+ * if (!bottomGear) {
50
+ * return this;
51
+ * }
52
+ * this.$el.html('<button class="custom-option">Custom option</button>');
53
+ * // Put rendered element into the gear menu
54
+ * bottomGear.addItem('custom').html(this.$el)
55
+ * return this;
56
+ * }
57
+ *
58
+ * // alternatively, add an option with a submenu
59
+ * override render() {
60
+ * this.$el.html(template(templateHtml)({
61
+ * // ...
62
+ * })));
63
+ * return this;
64
+ * }
65
+ *
66
+ * private addGearOption() {
67
+ * this.core.getPlugin('bottom_gear')
68
+ * .addItem('custom', this.$el)
69
+ * .html($('<button class="custom-option">Custom option</button>'))
70
+ * }
71
+ *
72
+ * override bindEvents() {
73
+ * this.listenToOnce(this.core, ClapprEvents.CORE_READY, () => {
74
+ * const bottomGear = this.core.getPlugin('bottom_gear');
75
+ * assert(bottomGear, 'bottom_gear plugin is required');
76
+ * // simple case
77
+ * this.listenTo(bottomGear, GearEvents.RENDERED, this.render);
78
+ * // or with a submenu
79
+ * this.listenTo(bottomGear, GearEvents.RENDERED, this.addGearOption);
80
+ * });
81
+ * }
82
+ * }
83
+ * ```
23
84
  */
24
85
  export declare class BottomGear extends UICorePlugin {
25
86
  private isHd;
@@ -48,22 +109,13 @@ export declare class BottomGear extends UICorePlugin {
48
109
  * @internal
49
110
  */
50
111
  get events(): {
51
- 'click .button-gear': string;
112
+ 'click #gear-button': string;
52
113
  };
53
114
  /**
54
115
  * @internal
55
116
  */
56
117
  bindEvents(): void;
57
- /**
58
- * @param name - Name of a gear menu placeholder item to attach custom UI
59
- * @returns Zepto result of the element
60
- */
61
- getElement(name: GearOptionsItem): ZeptoResult | null;
62
- /**
63
- * Replaces the content of the gear menu
64
- * @param content - Zepto result of the element
65
- */
66
- setContent(content: ZeptoResult): void;
118
+ addItem(name: string, $subMenu?: ZeptoResult): ZeptoResult;
67
119
  private onActiveContainerChanged;
68
120
  private bindContainerEvents;
69
121
  private highDefinitionUpdate;
@@ -72,13 +124,12 @@ export declare class BottomGear extends UICorePlugin {
72
124
  */
73
125
  render(): this;
74
126
  /**
75
- * Re-renders the gear menu.
76
- * It fires the {@link MediaControlEvents.MEDIACONTROL_GEAR_RENDERED | MEDIACONTROL_GEAR_RENDERED} event,
77
- * which the plugins that attach to the gear menu can listen to to re-render themselves.
127
+ * Collapses any submenu open back to the gear menu
78
128
  */
79
129
  refresh(): void;
80
130
  private toggleGearMenu;
81
131
  private hide;
82
132
  private onCoreReady;
133
+ private onMediaControlRendered;
83
134
  }
84
135
  //# sourceMappingURL=BottomGear.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BottomGear.d.ts","sourceRoot":"","sources":["../../../src/plugins/bottom-gear/BottomGear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoC,MAAM,cAAc,CAAC;AAO9E,OAAO,uCAAuC,CAAC;AAC/C,OAAO,gDAAgD,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAO7C;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAI9C;;;;;;;;;GASG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,IAAI,CAAS;IAErB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;MAIlB;IAED;;OAEG;IACM,UAAU;IAKnB;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW,GAAG,IAAI;IAMrD;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW;IAI/B,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAK3B,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACM,MAAM;IAiBf;;;;OAIG;IACH,OAAO;IAKP,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,WAAW;CAMpB"}
1
+ {"version":3,"file":"BottomGear.d.ts","sourceRoot":"","sources":["../../../src/plugins/bottom-gear/BottomGear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuC,MAAM,cAAc,CAAA;AAOhF,OAAO,uCAAuC,CAAA;AAC9C,OAAO,gDAAgD,CAAA;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAO5C,oBAAY,UAAU;IACpB,QAAQ,aAAa;CACtB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAA;AAEzD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,CAAA;AAI7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,IAAI,CAAQ;IAEpB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,MAAM,KAAK,OAAO,WAEjB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED;;OAEG;IACH,IAAa,MAAM;;MAIlB;IAED;;OAEG;IACM,UAAU;IASnB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW;IAyB1D,OAAO,CAAC,wBAAwB;IAKhC,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACM,MAAM;IAsBf;;OAEG;IACH,OAAO;IAKP,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,IAAI;IAIZ,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,sBAAsB;CAI/B"}
@@ -1,4 +1,4 @@
1
- import { UICorePlugin, template, Events as ClapprEvents } from '@clappr/core';
1
+ import { UICorePlugin, template, Events as ClapprEvents, $ } from '@clappr/core';
2
2
  import { trace } from '@gcorevideo/utils';
3
3
  import assert from 'assert';
4
4
  import { CLAPPR_VERSION } from '../../build.js';
@@ -7,9 +7,12 @@ import '../../../assets/bottom-gear/gear.scss';
7
7
  import '../../../assets/bottom-gear/gear-sub-menu.scss';
8
8
  import gearIcon from '../../../assets/icons/new/gear.svg';
9
9
  import gearHdIcon from '../../../assets/icons/new/gear-hd.svg';
10
- import { MediaControlEvents } from '../media-control/MediaControl';
11
10
  const VERSION = '2.19.12';
12
11
  const T = 'plugins.bottom_gear';
12
+ export var GearEvents;
13
+ (function (GearEvents) {
14
+ GearEvents["RENDERED"] = "rendered";
15
+ })(GearEvents || (GearEvents = {}));
13
16
  // TODO disabled if no items added
14
17
  /**
15
18
  * `PLUGIN` that adds the gear button with an extra options menu on the right side of the {@link MediaControl | media control} UI
@@ -20,6 +23,63 @@ const T = 'plugins.bottom_gear';
20
23
  * Depends on:
21
24
  *
22
25
  * - {@link MediaControl}
26
+ *
27
+ * @example
28
+ * You can use bottom gear to add custom settings UI to the gear menu.
29
+ *
30
+ * ```ts
31
+ * import { BottomGear } from '@gcorevideo/player/plugins/bottom-gear';
32
+ *
33
+ * class CustomOptionsPlugin extends UICorePlugin {
34
+ * // ...
35
+ *
36
+ * override get events() {
37
+ * return {
38
+ * 'click #my-button': 'doMyAction',
39
+ * }
40
+ * }
41
+ *
42
+ * private doMyAction() {
43
+ * // ...
44
+ * }
45
+ *
46
+ * override render() {
47
+ * const bottomGear = this.core.getPlugin('bottom_gear');
48
+ * if (!bottomGear) {
49
+ * return this;
50
+ * }
51
+ * this.$el.html('<button class="custom-option">Custom option</button>');
52
+ * // Put rendered element into the gear menu
53
+ * bottomGear.addItem('custom').html(this.$el)
54
+ * return this;
55
+ * }
56
+ *
57
+ * // alternatively, add an option with a submenu
58
+ * override render() {
59
+ * this.$el.html(template(templateHtml)({
60
+ * // ...
61
+ * })));
62
+ * return this;
63
+ * }
64
+ *
65
+ * private addGearOption() {
66
+ * this.core.getPlugin('bottom_gear')
67
+ * .addItem('custom', this.$el)
68
+ * .html($('<button class="custom-option">Custom option</button>'))
69
+ * }
70
+ *
71
+ * override bindEvents() {
72
+ * this.listenToOnce(this.core, ClapprEvents.CORE_READY, () => {
73
+ * const bottomGear = this.core.getPlugin('bottom_gear');
74
+ * assert(bottomGear, 'bottom_gear plugin is required');
75
+ * // simple case
76
+ * this.listenTo(bottomGear, GearEvents.RENDERED, this.render);
77
+ * // or with a submenu
78
+ * this.listenTo(bottomGear, GearEvents.RENDERED, this.addGearOption);
79
+ * });
80
+ * }
81
+ * }
82
+ * ```
23
83
  */
24
84
  export class BottomGear extends UICorePlugin {
25
85
  isHd = false;
@@ -47,7 +107,7 @@ export class BottomGear extends UICorePlugin {
47
107
  */
48
108
  get attributes() {
49
109
  return {
50
- 'class': 'media-control-gear',
110
+ class: 'media-control-gear',
51
111
  };
52
112
  }
53
113
  /**
@@ -55,30 +115,39 @@ export class BottomGear extends UICorePlugin {
55
115
  */
56
116
  get events() {
57
117
  return {
58
- 'click .button-gear': 'toggleGearMenu',
118
+ 'click #gear-button': 'toggleGearMenu',
59
119
  };
60
120
  }
61
121
  /**
62
122
  * @internal
63
123
  */
64
124
  bindEvents() {
65
- this.listenTo(this.core, ClapprEvents.CORE_READY, this.onCoreReady);
125
+ this.listenToOnce(this.core, ClapprEvents.CORE_READY, this.onCoreReady);
66
126
  this.listenTo(this.core, ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
67
127
  }
68
- /**
69
- * @param name - Name of a gear menu placeholder item to attach custom UI
70
- * @returns Zepto result of the element
71
- */
72
- getElement(name) {
73
- return this.$el.find(`.gear-options-list [data-${name}]`);
74
- }
75
- // TODO implement putElement/addElement method
76
- /**
77
- * Replaces the content of the gear menu
78
- * @param content - Zepto result of the element
79
- */
80
- setContent(content) {
81
- this.$el.find('.gear-wrapper').html(content);
128
+ addItem(name, $subMenu) {
129
+ const $existingItem = this.$el.find(`#gear-options li[data-${name}`);
130
+ if ($existingItem.length) {
131
+ trace(`${T} addItem already exists`, { name });
132
+ return $existingItem;
133
+ }
134
+ const $item = $('<li></li>')
135
+ .attr(`data-${name}`, '')
136
+ .appendTo(this.$el.find('#gear-options'));
137
+ if ($subMenu) {
138
+ trace(`${T} addItem adding submenu`, { name });
139
+ $subMenu
140
+ .addClass('gear-sub-menu-wrapper')
141
+ .hide()
142
+ .appendTo(this.$el.find('#gear-options-wrapper'));
143
+ $item.on('click', (e) => {
144
+ trace(`${T} addItem submenu clicked`, { name });
145
+ e.stopPropagation();
146
+ $subMenu.show();
147
+ this.$el.find('#gear-options').hide();
148
+ });
149
+ }
150
+ return $item;
82
151
  }
83
152
  onActiveContainerChanged() {
84
153
  trace(`${T} onActiveContainerChanged`);
@@ -97,38 +166,45 @@ export class BottomGear extends UICorePlugin {
97
166
  * @internal
98
167
  */
99
168
  render() {
169
+ trace(`${T} render`);
100
170
  const mediaControl = this.core.getPlugin('media_control');
101
- // TODO use options.mediaControl.gear.items
102
- const items = [
103
- 'quality',
104
- 'rate',
105
- 'nerd',
106
- ];
171
+ if (!mediaControl) {
172
+ return this; // TODO test
173
+ }
107
174
  const icon = this.isHd ? gearHdIcon : gearIcon;
108
- this.$el.html(BottomGear.template({ icon, items }));
109
- mediaControl.putElement('gear', this.el);
110
- mediaControl.trigger(MediaControlEvents.MEDIACONTROL_GEAR_RENDERED);
175
+ this.$el
176
+ .html(BottomGear.template({ icon }))
177
+ .find('#gear-sub-menu-wrapper')
178
+ .hide();
179
+ // TODO make non-clickable when there are no items
180
+ mediaControl.putElement('gear', this.$el);
181
+ setTimeout(() => {
182
+ this.trigger(GearEvents.RENDERED);
183
+ }, 0);
111
184
  return this;
112
185
  }
113
186
  /**
114
- * Re-renders the gear menu.
115
- * It fires the {@link MediaControlEvents.MEDIACONTROL_GEAR_RENDERED | MEDIACONTROL_GEAR_RENDERED} event,
116
- * which the plugins that attach to the gear menu can listen to to re-render themselves.
187
+ * Collapses any submenu open back to the gear menu
117
188
  */
118
189
  refresh() {
119
- this.render();
120
- this.$el.find('.gear-wrapper').show();
190
+ this.$el.find('.gear-sub-menu-wrapper').hide();
191
+ this.$el.find('#gear-options').show();
121
192
  }
122
193
  toggleGearMenu() {
123
- this.$el.find('.gear-wrapper').toggle();
194
+ this.$el.find('#gear-options-wrapper').toggle();
124
195
  }
125
196
  hide() {
126
- this.$el.find('.gear-wrapper').hide();
197
+ this.$el.find('#gear-options-wrapper').hide();
127
198
  }
128
199
  onCoreReady() {
200
+ trace(`${T} onCoreReady`);
129
201
  const mediaControl = this.core.getPlugin('media_control');
130
202
  assert(mediaControl, 'media_control plugin is required');
131
- this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_RENDERED, this.render);
132
- this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide); // TODO mediacontrol show as well
203
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_RENDERED, this.onMediaControlRendered);
204
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide);
205
+ }
206
+ onMediaControlRendered() {
207
+ trace(`${T} onMediaControlRendered`);
208
+ this.render();
133
209
  }
134
210
  }
@@ -7,8 +7,6 @@ import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss';
7
7
  * @remarks
8
8
  * Depends on:
9
9
  *
10
- * - {@link MediaControl}
11
- *
12
10
  * - {@link BottomGear}
13
11
  *
14
12
  * - {@link ClapprStats}
@@ -25,6 +23,7 @@ export declare class ClapprNerdStats extends UICorePlugin {
25
23
  private showing;
26
24
  private shortcut;
27
25
  private iconPosition;
26
+ private static readonly buttonTemplate;
28
27
  /**
29
28
  * @internal
30
29
  */
@@ -60,7 +59,7 @@ export declare class ClapprNerdStats extends UICorePlugin {
60
59
  * @internal
61
60
  */
62
61
  bindEvents(): void;
63
- private init;
62
+ private onCoreReady;
64
63
  private toggle;
65
64
  private show;
66
65
  private hide;
@@ -1 +1 @@
1
- {"version":3,"file":"ClapprNerdStats.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/ClapprNerdStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,IAAI,EAAa,MAAM,cAAc,CAAA;AAsB9E,OAAO,0DAA0D,CAAA;AAgGjE;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,SAAS,CAAyB;IAE1C,OAAO,CAAC,aAAa,CAIpB;IAED,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,YAAY,CAAc;IAElC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;;MAKtB;IAED;;OAEG;IACH,IAAa,MAAM;;;;MAMlB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,sBAAsB,GAEjC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,YAAY,GAEvB;gBAEW,IAAI,EAAE,IAAI;IAgBtB;;OAEG;IACM,UAAU;IAWnB,OAAO,CAAC,IAAI;IA4BZ,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACM,MAAM;IAQf,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;CAWzB"}
1
+ {"version":3,"file":"ClapprNerdStats.d.ts","sourceRoot":"","sources":["../../../src/plugins/clappr-nerd-stats/ClapprNerdStats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,IAAI,EAAa,MAAM,cAAc,CAAA;AAsB9E,OAAO,0DAA0D,CAAA;AAgGjE;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,SAAS,CAAyB;IAE1C,OAAO,CAAC,aAAa,CAIpB;IAED,OAAO,CAAC,OAAO,CAAwB;IAEvC,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,QAAQ,CAAU;IAE1B,OAAO,CAAC,YAAY,CAAc;IAElC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAuB;IAE7D;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAEvD;;OAEG;IACH,IAAa,UAAU;;;MAKtB;IAED;;OAEG;IACH,IAAa,MAAM;;;;MAMlB;IAED,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,sBAAsB,GAEjC;IAED,OAAO,KAAK,WAAW,GAEtB;IAED,OAAO,KAAK,YAAY,GAEvB;gBAEW,IAAI,EAAE,IAAI;IAgBtB;;OAEG;IACM,UAAU;IAInB,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IA+BxB,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,eAAe;IAUvB;;OAEG;IACM,MAAM;IASf,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,gBAAgB;CAWzB"}
@@ -1,5 +1,5 @@
1
1
  import { UICorePlugin, Events, template } from '@clappr/core';
2
- import { reportError } from '@gcorevideo/utils';
2
+ import { reportError, trace } from '@gcorevideo/utils';
3
3
  import Mousetrap from 'mousetrap';
4
4
  import { CLAPPR_VERSION } from '../../build.js';
5
5
  import { ClapprStatsEvents, } from '../clappr-stats/types.js';
@@ -10,7 +10,7 @@ import '../../../assets/clappr-nerd-stats/clappr-nerd-stats.scss';
10
10
  import pluginHtml from '../../../assets/clappr-nerd-stats/clappr-nerd-stats.ejs';
11
11
  import buttonHtml from '../../../assets/clappr-nerd-stats/button.ejs';
12
12
  import statsIcon from '../../../assets/icons/new/stats.svg';
13
- import { MediaControlEvents } from '../media-control/MediaControl.js';
13
+ import { GearEvents } from '../bottom-gear/BottomGear.js';
14
14
  import assert from 'assert';
15
15
  const qualityClasses = [
16
16
  'speedtest-quality-value-1',
@@ -79,7 +79,7 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
79
79
  vodContainer.html(vodHtml);
80
80
  liveContainer.html(liveHtml);
81
81
  };
82
- // const T = 'plugins.clappr_nerd_stats';
82
+ const T = 'plugins.clappr_nerd_stats';
83
83
  /**
84
84
  * `PLUGIN` that displays useful network-related statistics.
85
85
  * @beta
@@ -87,8 +87,6 @@ const drawSummary = (customMetrics, vodContainer, liveContainer) => {
87
87
  * @remarks
88
88
  * Depends on:
89
89
  *
90
- * - {@link MediaControl}
91
- *
92
90
  * - {@link BottomGear}
93
91
  *
94
92
  * - {@link ClapprStats}
@@ -109,6 +107,7 @@ export class ClapprNerdStats extends UICorePlugin {
109
107
  showing = false;
110
108
  shortcut;
111
109
  iconPosition;
110
+ static buttonTemplate = template(buttonHtml);
112
111
  /**
113
112
  * @internal
114
113
  */
@@ -172,12 +171,12 @@ export class ClapprNerdStats extends UICorePlugin {
172
171
  * @internal
173
172
  */
174
173
  bindEvents() {
175
- const mediaControl = this.core.getPlugin('media_control');
176
- assert(mediaControl, 'media_control plugin is required');
177
- this.listenToOnce(this.core, Events.CORE_READY, this.init);
178
- this.listenTo(mediaControl, MediaControlEvents.MEDIACONTROL_GEAR_RENDERED, this.addToBottomGear);
174
+ this.listenToOnce(this.core, Events.CORE_READY, this.onCoreReady);
179
175
  }
180
- init() {
176
+ onCoreReady() {
177
+ const bottomGear = this.core.getPlugin('bottom_gear');
178
+ assert(bottomGear, 'bottom_gear plugin is required');
179
+ this.listenTo(bottomGear, GearEvents.RENDERED, this.addToBottomGear);
181
180
  this.container = this.core.activeContainer;
182
181
  const clapprStats = this.container?.getPlugin('clappr_stats');
183
182
  if (!clapprStats) {
@@ -289,18 +288,22 @@ export class ClapprNerdStats extends UICorePlugin {
289
288
  * @internal
290
289
  */
291
290
  render() {
291
+ trace(`${T} render`);
292
292
  // TODO append to the container
293
293
  this.core.$el.append(this.$el[0]);
294
294
  this.hide();
295
295
  return this;
296
296
  }
297
297
  addToBottomGear() {
298
+ trace(`${T} addToBottomGear`);
298
299
  const gear = this.core.getPlugin('bottom_gear');
299
- const $el = gear.getElement('nerd');
300
- $el.html(buttonHtml);
301
- const $button = $el.find('.nerd-button');
302
- $button.find('.stats-icon').html(statsIcon);
303
- $button.on('click', (e) => {
300
+ const $button = gear
301
+ .addItem('nerd')
302
+ .html(ClapprNerdStats.buttonTemplate({
303
+ icon: statsIcon,
304
+ i18n: this.core.i18n,
305
+ }))
306
+ .on('click', (e) => {
304
307
  e.stopPropagation();
305
308
  this.toggle();
306
309
  });
@@ -97,7 +97,7 @@ export class DvrControls extends UICorePlugin {
97
97
  this.$el.html(DvrControls.template({
98
98
  i18n: this.core.i18n,
99
99
  }));
100
- mediaControl.putElement('dvr', this.el);
100
+ mediaControl.putElement('dvr', this.$el);
101
101
  return this;
102
102
  }
103
103
  }