@gcorevideo/player 2.23.1 → 2.23.3

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 (33) hide show
  1. package/assets/bottom-gear/bottomgear.ejs +5 -2
  2. package/dist/core.js +1 -1
  3. package/dist/index.css +1501 -1501
  4. package/dist/index.js +53 -25
  5. package/dist/player.d.ts +67 -53
  6. package/docs/api/{player.mediacontrol.putelement.md → player.clips.gettext.md} +10 -23
  7. package/docs/api/player.clips.md +14 -0
  8. package/docs/api/player.md +9 -0
  9. package/docs/api/player.mediacontrol.md +0 -14
  10. package/docs/api/player.poster.md +2 -10
  11. package/docs/api/player.posterpluginsettings.md +16 -0
  12. package/docs/api/player.thumbnails._constructor_.md +50 -0
  13. package/docs/api/player.thumbnails.md +73 -0
  14. package/docs/api/player.thumbnails.render.md +18 -0
  15. package/docs/api/player.thumbnailspluginsettings.md +4 -4
  16. package/lib/plugins/bottom-gear/BottomGear.d.ts +6 -3
  17. package/lib/plugins/bottom-gear/BottomGear.d.ts.map +1 -1
  18. package/lib/plugins/bottom-gear/BottomGear.js +48 -17
  19. package/lib/plugins/thumbnails/Thumbnails.d.ts.map +1 -1
  20. package/lib/plugins/thumbnails/Thumbnails.js +3 -6
  21. package/lib/testUtils.d.ts +1 -0
  22. package/lib/testUtils.d.ts.map +1 -1
  23. package/lib/testUtils.js +3 -0
  24. package/package.json +1 -1
  25. package/src/plugins/bottom-gear/BottomGear.ts +52 -24
  26. package/src/plugins/bottom-gear/__tests__/BottomGear.test.ts +122 -48
  27. package/src/plugins/bottom-gear/__tests__/__snapshots__/BottomGear.test.ts.snap +4 -4
  28. package/src/plugins/thumbnails/Thumbnails.ts +3 -6
  29. package/src/plugins/thumbnails/__tests__/Thumbnails.test.ts +20 -3
  30. package/src/plugins/thumbnails/__tests__/__snapshots__/Thumbnails.test.ts.snap +1 -1
  31. package/src/testUtils.ts +3 -0
  32. package/temp/player.api.json +144 -70
  33. package/tsconfig.tsbuildinfo +1 -1
@@ -16,6 +16,12 @@ export declare class Thumbnails extends UICorePlugin
16
16
  ```
17
17
  **Extends:** UICorePlugin
18
18
 
19
+ ## Remarks
20
+
21
+ The plugin needs specially crafted VTT file with a thumbnail sprite sheet to work. The VTT consist of timestamp records followed by a thumbnail area
22
+
23
+ Configuration options - [ThumbnailsPluginSettings](./player.thumbnailspluginsettings.md)
24
+
19
25
  ## Example
20
26
 
21
27
 
@@ -37,3 +43,70 @@ new Player({
37
43
  })
38
44
  ```
39
45
 
46
+ ## Constructors
47
+
48
+ <table><thead><tr><th>
49
+
50
+ Constructor
51
+
52
+
53
+ </th><th>
54
+
55
+ Modifiers
56
+
57
+
58
+ </th><th>
59
+
60
+ Description
61
+
62
+
63
+ </th></tr></thead>
64
+ <tbody><tr><td>
65
+
66
+ [(constructor)(core)](./player.thumbnails._constructor_.md)
67
+
68
+
69
+ </td><td>
70
+
71
+
72
+ </td><td>
73
+
74
+ **_(BETA)_** Constructs a new instance of the `Thumbnails` class
75
+
76
+
77
+ </td></tr>
78
+ </tbody></table>
79
+
80
+ ## Methods
81
+
82
+ <table><thead><tr><th>
83
+
84
+ Method
85
+
86
+
87
+ </th><th>
88
+
89
+ Modifiers
90
+
91
+
92
+ </th><th>
93
+
94
+ Description
95
+
96
+
97
+ </th></tr></thead>
98
+ <tbody><tr><td>
99
+
100
+ [render()](./player.thumbnails.render.md)
101
+
102
+
103
+ </td><td>
104
+
105
+
106
+ </td><td>
107
+
108
+ **_(BETA)_**
109
+
110
+
111
+ </td></tr>
112
+ </tbody></table>
@@ -0,0 +1,18 @@
1
+ <!-- Do not edit this file. It is automatically generated by API Documenter. -->
2
+
3
+ [Home](./index.md) &gt; [@gcorevideo/player](./player.md) &gt; [Thumbnails](./player.thumbnails.md) &gt; [render](./player.thumbnails.render.md)
4
+
5
+ ## Thumbnails.render() 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
+ **Signature:**
11
+
12
+ ```typescript
13
+ render(): this;
14
+ ```
15
+ **Returns:**
16
+
17
+ this
18
+
@@ -13,10 +13,10 @@ Plugin configuration options for the thumbnails plugin.
13
13
 
14
14
  ```typescript
15
15
  export type ThumbnailsPluginSettings = {
16
- backdropHeight: number;
17
- backdropMaxOpacity: number;
18
- backdropMinOpacity: number;
19
- spotlightHeight: number;
16
+ backdropHeight?: number;
17
+ backdropMaxOpacity?: number;
18
+ backdropMinOpacity?: number;
19
+ spotlightHeight?: number;
20
20
  sprite: string;
21
21
  vtt: string;
22
22
  };
@@ -82,6 +82,8 @@ export declare enum GearEvents {
82
82
  */
83
83
  export declare class BottomGear extends UICorePlugin {
84
84
  private hd;
85
+ private numItems;
86
+ private collapsed;
85
87
  /**
86
88
  * @internal
87
89
  */
@@ -136,7 +138,6 @@ export declare class BottomGear extends UICorePlugin {
136
138
  * ```
137
139
  */
138
140
  addItem(name: string, $subMenu?: ZeptoResult): ZeptoResult;
139
- private onActiveContainerChanged;
140
141
  private bindContainerEvents;
141
142
  private highDefinitionUpdate;
142
143
  /**
@@ -149,9 +150,11 @@ export declare class BottomGear extends UICorePlugin {
149
150
  * Should be called by the UI plugin that added a gear item with a submenu when the latter is closed (e.g., when a "back" button is clicked).
150
151
  */
151
152
  refresh(): void;
152
- private toggleGearMenu;
153
- private hide;
153
+ private collapseSubmenus;
154
+ private toggleMenu;
155
+ private collapse;
154
156
  private onCoreReady;
155
157
  private onMediaControlRendered;
158
+ private mount;
156
159
  }
157
160
  //# 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,EAAuC,MAAM,cAAc,CAAA;AAOhF,OAAO,uCAAuC,CAAA;AAC9C,OAAO,gDAAgD,CAAA;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAO5C;;;GAGG;AACH,oBAAY,UAAU;IACpB;;OAEG;IACH,QAAQ,aAAa;CACtB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,EAAE,CAAQ;IAElB;;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;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,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;IAqBf;;;;OAIG;IACH,OAAO;IAKP,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,IAAI;IAKZ,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,sBAAsB;CAK/B"}
1
+ {"version":3,"file":"BottomGear.d.ts","sourceRoot":"","sources":["../../../src/plugins/bottom-gear/BottomGear.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAkD,MAAM,cAAc,CAAA;AAO3F,OAAO,uCAAuC,CAAA;AAC9C,OAAO,gDAAgD,CAAA;AAGvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAO5C;;;GAGG;AACH,oBAAY,UAAU;IACpB;;OAEG;IACH,QAAQ,aAAa;CACtB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,EAAE,CAAQ;IAElB,OAAO,CAAC,QAAQ,CAAK;IAErB,OAAO,CAAC,SAAS,CAAQ;IAEzB;;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;IAInB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,WAAW;IA6B1D,OAAO,CAAC,mBAAmB;IAY3B,OAAO,CAAC,oBAAoB;IAM5B;;OAEG;IACM,MAAM;IAsBf;;;;OAIG;IACH,OAAO;IAIP,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,sBAAsB;IAK9B,OAAO,CAAC,KAAK;CAOd"}
@@ -92,6 +92,8 @@ export var GearEvents;
92
92
  */
93
93
  export class BottomGear extends UICorePlugin {
94
94
  hd = false;
95
+ numItems = 0;
96
+ collapsed = true;
95
97
  /**
96
98
  * @internal
97
99
  */
@@ -124,7 +126,7 @@ export class BottomGear extends UICorePlugin {
124
126
  */
125
127
  get events() {
126
128
  return {
127
- 'click #gear-button': 'toggleGearMenu',
129
+ 'click #gear-button': 'toggleMenu',
128
130
  };
129
131
  }
130
132
  /**
@@ -132,7 +134,6 @@ export class BottomGear extends UICorePlugin {
132
134
  */
133
135
  bindEvents() {
134
136
  this.listenToOnce(this.core, ClapprEvents.CORE_READY, this.onCoreReady);
135
- this.listenTo(this.core, ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED, this.onActiveContainerChanged);
136
137
  }
137
138
  /**
138
139
  * Adds a custom option to the gear menu
@@ -178,20 +179,23 @@ export class BottomGear extends UICorePlugin {
178
179
  this.$el.find('#gear-options').hide();
179
180
  });
180
181
  }
182
+ this.numItems++;
183
+ if (this.numItems > 0) {
184
+ this.$el.show();
185
+ }
181
186
  return $item;
182
187
  }
183
- onActiveContainerChanged() {
184
- trace(`${T} onActiveContainerChanged`);
185
- this.bindContainerEvents();
186
- }
187
- bindContainerEvents() {
188
+ bindContainerEvents(container) {
188
189
  trace(`${T} bindContainerEvents`);
189
- this.listenTo(this.core.activeContainer, ClapprEvents.CONTAINER_HIGHDEFINITIONUPDATE, this.highDefinitionUpdate);
190
+ this.listenTo(container, ClapprEvents.CONTAINER_HIGHDEFINITIONUPDATE, this.highDefinitionUpdate);
191
+ this.listenTo(container, ClapprEvents.CONTAINER_CLICK, () => {
192
+ this.collapse();
193
+ });
190
194
  }
191
195
  highDefinitionUpdate(isHd) {
192
196
  trace(`${T} highDefinitionUpdate`, { isHd });
193
197
  this.hd = isHd;
194
- this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon);
198
+ this.$el.find('#gear-button').html(isHd ? gearHdIcon : gearIcon);
195
199
  }
196
200
  /**
197
201
  * @internal
@@ -203,11 +207,13 @@ export class BottomGear extends UICorePlugin {
203
207
  return this; // TODO test
204
208
  }
205
209
  const icon = this.hd ? gearHdIcon : gearIcon;
210
+ this.collapsed = true;
211
+ this.numItems = 0;
206
212
  this.$el
207
213
  .html(BottomGear.template({ icon }))
208
- .find('#gear-sub-menu-wrapper')
214
+ .hide() // until numItems > 0
215
+ .find('#gear-options-wrapper')
209
216
  .hide();
210
- // TODO make non-clickable when there are no items
211
217
  setTimeout(() => {
212
218
  this.trigger(GearEvents.RENDERED);
213
219
  }, 0);
@@ -219,33 +225,58 @@ export class BottomGear extends UICorePlugin {
219
225
  * Should be called by the UI plugin that added a gear item with a submenu when the latter is closed (e.g., when a "back" button is clicked).
220
226
  */
221
227
  refresh() {
228
+ this.collapseSubmenus();
229
+ }
230
+ collapseSubmenus() {
222
231
  this.$el.find('.gear-sub-menu-wrapper').hide();
223
232
  this.$el.find('#gear-options').show();
224
233
  }
225
- toggleGearMenu() {
234
+ toggleMenu() {
226
235
  this.core
227
236
  .getPlugin('media_control')
228
237
  .trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE, this.name);
229
- this.$el.find('#gear-options-wrapper').toggle();
238
+ this.collapsed = !this.collapsed;
239
+ if (this.collapsed) {
240
+ this.$el.find('#gear-options-wrapper').hide();
241
+ }
242
+ else {
243
+ this.$el.find('#gear-options-wrapper').show();
244
+ }
245
+ this.$el.find('#gear-button').attr('aria-expanded', (!this.collapsed).toString());
246
+ trace(`${T} toggleMenu`, { hidden: this.collapsed });
230
247
  }
231
- hide() {
232
- trace(`${T} hide`);
248
+ collapse() {
249
+ trace(`${T} collapse`);
250
+ this.collapsed = true;
233
251
  this.$el.find('#gear-options-wrapper').hide();
252
+ this.$el.find('#gear-button').attr('aria-expanded', 'false');
253
+ // TODO hide submenus
254
+ this.collapseSubmenus();
234
255
  }
235
256
  onCoreReady() {
236
257
  trace(`${T} onCoreReady`);
237
258
  const mediaControl = this.core.getPlugin('media_control');
238
259
  assert(mediaControl, 'media_control plugin is required');
239
260
  this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_RENDERED, this.onMediaControlRendered);
240
- this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide);
261
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.collapse);
262
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_CONTAINERCHANGED, () => {
263
+ this.bindContainerEvents(mediaControl.container);
264
+ });
241
265
  this.listenTo(mediaControl, ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE, (from) => {
242
266
  if (from !== this.name) {
243
- this.hide();
267
+ this.collapse();
244
268
  }
245
269
  });
270
+ this.bindContainerEvents(mediaControl.container);
246
271
  }
247
272
  onMediaControlRendered() {
248
273
  trace(`${T} onMediaControlRendered`);
274
+ this.mount();
275
+ }
276
+ mount() {
277
+ trace(`${T} mount`, {
278
+ numItems: this.numItems,
279
+ });
249
280
  const mediaControl = this.core.getPlugin('media_control');
250
281
  mediaControl.mount('gear', this.$el);
251
282
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Thumbnails.d.ts","sourceRoot":"","sources":["../../../src/plugins/thumbnails/Thumbnails.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAKZ,IAAI,EACL,MAAM,cAAc,CAAA;AAUrB,OAAO,uCAAuC,CAAA;AAM9C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,qBAAqB,CAAoB;IAEjD,OAAO,CAAC,iBAAiB,CAAY;IAErC,OAAO,CAAC,gBAAgB,CAAY;IAEpC,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,eAAe,CAAI;IAE3B,OAAO,CAAC,cAAc,CAAI;IAE1B,OAAO,CAAC,MAAM,CAAsB;IAEpC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAE3C,IAAI,EAAE,IAAI;IAgBtB,OAAO,CAAC,iBAAiB;IAiCzB;;OAEG;IACM,UAAU;IAInB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,WAAW;YAmDL,eAAe;IAO7B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,cAAc;IAuEtB,OAAO,CAAC,oBAAoB;IAkD5B,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,WAAW;IAgBnB,OAAO,KAAK,YAAY,GAMvB;IAEQ,MAAM;CAShB"}
1
+ {"version":3,"file":"Thumbnails.d.ts","sourceRoot":"","sources":["../../../src/plugins/thumbnails/Thumbnails.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAKZ,IAAI,EACL,MAAM,cAAc,CAAA;AAUrB,OAAO,uCAAuC,CAAA;AAM9C;;;GAGG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAC1C,OAAO,CAAC,qBAAqB,CAAoB;IAEjD,OAAO,CAAC,iBAAiB,CAAY;IAErC,OAAO,CAAC,gBAAgB,CAAY;IAEpC,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,OAAO,CAAQ;IAEvB,OAAO,CAAC,YAAY,CAAQ;IAE5B,OAAO,CAAC,eAAe,CAAI;IAE3B,OAAO,CAAC,cAAc,CAAI;IAE1B,OAAO,CAAC,MAAM,CAAsB;IAEpC;;OAEG;IACH,IAAI,IAAI,WAEP;IAED;;OAEG;IACH,IAAI,gBAAgB;;MAEnB;IAED;;OAEG;IACH,IAAa,UAAU;;MAItB;IAED,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAE3C,IAAI,EAAE,IAAI;IAgBtB,OAAO,CAAC,iBAAiB;IAiCzB;;OAEG;IACM,UAAU;IAInB,OAAO,CAAC,mBAAmB;IAI3B,OAAO,CAAC,WAAW;YAmDL,eAAe;IAO7B,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,cAAc;IAuEtB,OAAO,CAAC,oBAAoB;IAiD5B,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,WAAW;IAgBnB,OAAO,KAAK,YAAY,GAMvB;IAEQ,MAAM;CAShB"}
@@ -174,11 +174,9 @@ export class Thumbnails extends UICorePlugin {
174
174
  mediaControl.$el.first().after(this.$el);
175
175
  }
176
176
  onMouseMoveSeekbar(_, pos) {
177
- if (Math.abs(pos - this.hoverPosition) >= 0.01) {
178
- this.hoverPosition = pos;
179
- this.showing = true;
180
- this.update();
181
- }
177
+ this.hoverPosition = pos;
178
+ this.showing = true;
179
+ this.update();
182
180
  }
183
181
  onMouseLeave() {
184
182
  this.showing = false;
@@ -290,7 +288,6 @@ export class Thumbnails extends UICorePlugin {
290
288
  // determine which thumbnail applies to the current time
291
289
  const thumbIndex = this.getThumbIndexForTime(hoverTime);
292
290
  const thumb = this.thumbs[thumbIndex];
293
- // update thumbnail
294
291
  const $spotlight = this.$el.find('#thumbnails-spotlight');
295
292
  this.buildThumbImage(thumb, this.spotlightHeight, $spotlight.find('.thumbnail-container')).appendTo($spotlight);
296
293
  const elWidth = this.$el.width();
@@ -75,6 +75,7 @@ export declare function createMockContainer(options?: Record<string, unknown>, p
75
75
  getDuration: import("vitest").Mock<(...args: any[]) => any>;
76
76
  getPlugin: import("vitest").Mock<(...args: any[]) => any>;
77
77
  getPlaybackType: import("vitest").Mock<(...args: any[]) => any>;
78
+ getStartTimeOffset: import("vitest").Mock<(...args: any[]) => any>;
78
79
  isDvrInUse: import("vitest").Mock<(...args: any[]) => any>;
79
80
  isDvrEnabled: import("vitest").Mock<(...args: any[]) => any>;
80
81
  isHighDefinitionInUse: import("vitest").Mock<(...args: any[]) => any>;
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;EAqB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC/C;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;;;;;;;;;;;EA4BrC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAe/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAe7C"}
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;EAqB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC/C;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;;;;;;;;;;;;EA6BrC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAe7C"}
package/lib/testUtils.js CHANGED
@@ -87,6 +87,7 @@ export function createMockContainer(options = {}, playback = createMockPlayback(
87
87
  getDuration: vi.fn().mockReturnValue(0),
88
88
  getPlugin: vi.fn(),
89
89
  getPlaybackType: vi.fn(),
90
+ getStartTimeOffset: vi.fn().mockReturnValue(0),
90
91
  isDvrInUse: vi.fn().mockReturnValue(false),
91
92
  isDvrEnabled: vi.fn().mockReturnValue(false),
92
93
  isHighDefinitionInUse: vi.fn().mockReturnValue(false),
@@ -107,6 +108,8 @@ export function createMockMediaControl(core) {
107
108
  // @ts-ignore
108
109
  mediaControl.mount = vi.fn();
109
110
  // @ts-ignore
111
+ mediaControl.container = core.activeContainer;
112
+ // @ts-ignore
110
113
  mediaControl.toggleElement = vi.fn();
111
114
  vi.spyOn(mediaControl, 'trigger');
112
115
  core.$el.append(mediaControl.$el);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcorevideo/player",
3
- "version": "2.23.1",
3
+ "version": "2.23.3",
4
4
  "description": "Gcore JavaScript video player",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,4 +1,4 @@
1
- import { UICorePlugin, template, Events as ClapprEvents, $ } from '@clappr/core'
1
+ import { UICorePlugin, template, Events as ClapprEvents, $, Container } from '@clappr/core'
2
2
  import { trace } from '@gcorevideo/utils'
3
3
  import assert from 'assert'
4
4
 
@@ -100,6 +100,10 @@ export enum GearEvents {
100
100
  export class BottomGear extends UICorePlugin {
101
101
  private hd = false
102
102
 
103
+ private numItems = 0;
104
+
105
+ private collapsed = true;
106
+
103
107
  /**
104
108
  * @internal
105
109
  */
@@ -137,7 +141,7 @@ export class BottomGear extends UICorePlugin {
137
141
  */
138
142
  override get events() {
139
143
  return {
140
- 'click #gear-button': 'toggleGearMenu',
144
+ 'click #gear-button': 'toggleMenu',
141
145
  }
142
146
  }
143
147
 
@@ -146,11 +150,6 @@ export class BottomGear extends UICorePlugin {
146
150
  */
147
151
  override bindEvents() {
148
152
  this.listenToOnce(this.core, ClapprEvents.CORE_READY, this.onCoreReady)
149
- this.listenTo(
150
- this.core,
151
- ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED,
152
- this.onActiveContainerChanged,
153
- )
154
153
  }
155
154
 
156
155
  /**
@@ -197,27 +196,29 @@ export class BottomGear extends UICorePlugin {
197
196
  this.$el.find('#gear-options').hide()
198
197
  })
199
198
  }
199
+ this.numItems++;
200
+ if (this.numItems > 0) {
201
+ this.$el.show()
202
+ }
200
203
  return $item
201
204
  }
202
205
 
203
- private onActiveContainerChanged() {
204
- trace(`${T} onActiveContainerChanged`)
205
- this.bindContainerEvents()
206
- }
207
-
208
- private bindContainerEvents() {
206
+ private bindContainerEvents(container: Container) {
209
207
  trace(`${T} bindContainerEvents`)
210
208
  this.listenTo(
211
- this.core.activeContainer,
209
+ container,
212
210
  ClapprEvents.CONTAINER_HIGHDEFINITIONUPDATE,
213
211
  this.highDefinitionUpdate,
214
212
  )
213
+ this.listenTo(container, ClapprEvents.CONTAINER_CLICK, () => {
214
+ this.collapse()
215
+ })
215
216
  }
216
217
 
217
218
  private highDefinitionUpdate(isHd: boolean) {
218
219
  trace(`${T} highDefinitionUpdate`, { isHd })
219
220
  this.hd = isHd
220
- this.$el.find('.gear-icon').html(isHd ? gearHdIcon : gearIcon)
221
+ this.$el.find('#gear-button').html(isHd ? gearHdIcon : gearIcon)
221
222
  }
222
223
 
223
224
  /**
@@ -230,13 +231,14 @@ export class BottomGear extends UICorePlugin {
230
231
  return this // TODO test
231
232
  }
232
233
  const icon = this.hd ? gearHdIcon : gearIcon
234
+ this.collapsed = true;
235
+ this.numItems = 0;
233
236
  this.$el
234
237
  .html(BottomGear.template({ icon }))
235
- .find('#gear-sub-menu-wrapper')
238
+ .hide() // until numItems > 0
239
+ .find('#gear-options-wrapper')
236
240
  .hide()
237
241
 
238
- // TODO make non-clickable when there are no items
239
-
240
242
  setTimeout(() => {
241
243
  this.trigger(GearEvents.RENDERED)
242
244
  }, 0)
@@ -250,20 +252,35 @@ export class BottomGear extends UICorePlugin {
250
252
  * Should be called by the UI plugin that added a gear item with a submenu when the latter is closed (e.g., when a "back" button is clicked).
251
253
  */
252
254
  refresh() {
255
+ this.collapseSubmenus()
256
+ }
257
+
258
+ private collapseSubmenus() {
253
259
  this.$el.find('.gear-sub-menu-wrapper').hide()
254
260
  this.$el.find('#gear-options').show()
255
261
  }
256
262
 
257
- private toggleGearMenu() {
263
+ private toggleMenu() {
258
264
  this.core
259
265
  .getPlugin('media_control')
260
266
  .trigger(ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE, this.name)
261
- this.$el.find('#gear-options-wrapper').toggle()
267
+ this.collapsed = !this.collapsed;
268
+ if (this.collapsed) {
269
+ this.$el.find('#gear-options-wrapper').hide()
270
+ } else {
271
+ this.$el.find('#gear-options-wrapper').show()
272
+ }
273
+ this.$el.find('#gear-button').attr('aria-expanded', (!this.collapsed).toString())
274
+ trace(`${T} toggleMenu`, { hidden: this.collapsed })
262
275
  }
263
276
 
264
- private hide() {
265
- trace(`${T} hide`)
277
+ private collapse() {
278
+ trace(`${T} collapse`)
279
+ this.collapsed = true;
266
280
  this.$el.find('#gear-options-wrapper').hide()
281
+ this.$el.find('#gear-button').attr('aria-expanded', 'false')
282
+ // TODO hide submenus
283
+ this.collapseSubmenus()
267
284
  }
268
285
 
269
286
  private onCoreReady() {
@@ -275,20 +292,31 @@ export class BottomGear extends UICorePlugin {
275
292
  ClapprEvents.MEDIACONTROL_RENDERED,
276
293
  this.onMediaControlRendered,
277
294
  )
278
- this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.hide)
295
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_HIDE, this.collapse)
296
+ this.listenTo(mediaControl, ClapprEvents.MEDIACONTROL_CONTAINERCHANGED, () => {
297
+ this.bindContainerEvents(mediaControl.container)
298
+ })
279
299
  this.listenTo(
280
300
  mediaControl,
281
301
  ExtendedEvents.MEDIACONTROL_MENU_COLLAPSE,
282
302
  (from: string) => {
283
303
  if (from !== this.name) {
284
- this.hide()
304
+ this.collapse()
285
305
  }
286
306
  },
287
307
  )
308
+ this.bindContainerEvents(mediaControl.container)
288
309
  }
289
310
 
290
311
  private onMediaControlRendered() {
291
312
  trace(`${T} onMediaControlRendered`)
313
+ this.mount()
314
+ }
315
+
316
+ private mount() {
317
+ trace(`${T} mount`, {
318
+ numItems: this.numItems,
319
+ })
292
320
  const mediaControl = this.core.getPlugin('media_control')
293
321
  mediaControl.mount('gear', this.$el)
294
322
  }