@eluvio/elv-player-js 2.0.5 → 2.0.7

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.
@@ -27,6 +27,12 @@ class PlayerControls {
27
27
  this.player = player;
28
28
  this.visible = true;
29
29
  this.allowRotation = true;
30
+ this._activeMenus = 0;
31
+ }
32
+
33
+ __ToggleMenu(active) {
34
+ this._activeMenus = active ? this._activeMenus + 1 : Math.max(0, this._activeMenus - 1);
35
+ this.player.__SettingsUpdate();
30
36
  }
31
37
 
32
38
  /**
@@ -39,6 +45,16 @@ class PlayerControls {
39
45
  return this.visible;
40
46
  }
41
47
 
48
+ /**
49
+ * Check if the player currently has a menu visible
50
+ *
51
+ * @methodGroup Controls
52
+ * @returns {boolean} - Whether or not a menu is currently visible
53
+ */
54
+ IsMenuVisible() {
55
+ return this._activeMenus > 0;
56
+ }
57
+
42
58
  /**
43
59
  * Check if the player has finished loading
44
60
  *
@@ -839,11 +855,10 @@ class PlayerControls {
839
855
  *
840
856
  * @returns {Object} - Details about the content audit
841
857
  */
842
- ContentVerificationDetails() {
858
+ GetContentVerificationDetails() {
843
859
  return this.player.contentAudit || false;
844
860
  }
845
861
 
846
-
847
862
  GetOptions() {
848
863
  let options = {
849
864
  quality: this.GetQualityLevels(),
@@ -752,9 +752,10 @@ export class EluvioPlayer {
752
752
 
753
753
  const client = await this.__Client();
754
754
 
755
- const audit = await client.AuditContentObject({
756
- versionHash: this.contentHash
757
- });
755
+ const audit =
756
+ this.isLive ?
757
+ await client.AuditStream({versionHash: this.contentHash}) :
758
+ await client.AuditContentObject({versionHash: this.contentHash});
758
759
 
759
760
  if(!audit.verified) {
760
761
  return;
@@ -764,7 +765,7 @@ export class EluvioPlayer {
764
765
 
765
766
  const objectId = client.utils.DecodeVersionHash(this.contentHash).objectId;
766
767
  audit.details = {
767
- _full: false,
768
+ _state: "initial",
768
769
  versionHash: this.contentHash,
769
770
  objectId,
770
771
  address: client.utils.HashToAddress(objectId),
@@ -778,14 +779,23 @@ export class EluvioPlayer {
778
779
  }
779
780
 
780
781
  async __LoadVerificationDetails() {
781
- if(!this.contentHash || !this.contentAudit || this.contentAudit.details._full) { return; }
782
+ if(
783
+ !this.contentHash ||
784
+ !this.contentAudit ||
785
+ this.contentAudit.details._state !== "initial" ||
786
+ this.contentAudit.loading
787
+ ) {
788
+ return;
789
+ }
790
+
791
+ this.contentAudit.loading = true;
782
792
 
783
793
  const client = await this.__Client();
784
794
 
785
795
  const objectId = client.utils.DecodeVersionHash(this.contentHash).objectId;
786
796
  const tenantId = await client.ContentObjectTenantId({objectId});
787
797
 
788
- let tenantName, lastCommittedAt, versionCount, latestTransactionHash, latestTransactionHashUrl;
798
+ let tenantName, lastCommittedAt, versionCount;
789
799
  try {
790
800
  lastCommittedAt = await client.CallContractMethod({
791
801
  contractAddress: client.utils.HashToAddress(objectId),
@@ -806,7 +816,7 @@ export class EluvioPlayer {
806
816
  }
807
817
 
808
818
  // eslint-disable-next-line no-empty
809
- } catch(error) {}
819
+ } catch (error) {}
810
820
 
811
821
  try {
812
822
  tenantName = await client.ContentObjectMetadata({
@@ -815,39 +825,46 @@ export class EluvioPlayer {
815
825
  metadataSubtree: "/public/name"
816
826
  });
817
827
  // eslint-disable-next-line no-empty
818
- } catch(error) {}
819
-
820
- try {
821
- if(client.NetworkInfo().name === "main") {
822
- const explorerUrl = new URL("https://explorer.contentfabric.io/api");
823
- explorerUrl.searchParams.set("module", "account");
824
- explorerUrl.searchParams.set("action", "txlist");
825
- explorerUrl.searchParams.set("offset", "1");
826
- explorerUrl.searchParams.set("address", client.utils.HashToAddress(objectId));
827
-
828
- latestTransactionHash = (await ((await fetch(explorerUrl)).json())).result[0].hash;
829
- latestTransactionHashUrl = `https://explorer.contentfabric.io/tx/${latestTransactionHash}`;
830
- }
831
- // eslint-disable-next-line no-empty
832
- } catch(error){}
828
+ } catch (error) {}
833
829
 
834
830
  this.contentAudit.details = {
835
- _full: true,
831
+ _state: "minus-tx",
836
832
  versionHash: this.contentHash,
837
833
  objectId,
838
834
  address: client.utils.HashToAddress(objectId),
835
+ explorerUrl: client.NetworkInfo().name !== "main" ? undefined :
836
+ `https://explorer.contentfabric.io/address/${client.utils.HashToAddress(objectId)}`,
839
837
  tenantId,
840
838
  tenantAddress: client.utils.HashToAddress(tenantId),
841
839
  tenantName,
842
840
  ownerAddress: await client.ContentObjectOwner({objectId}),
843
841
  lastCommittedAt,
844
842
  versionCount,
845
- latestTransactionHash,
846
- latestTransactionHashUrl,
843
+ latestVersionHash: await client.LatestVersionHash({objectId}),
847
844
  signatureMethod: "ECDSA secp256k1"
848
845
  };
849
846
 
850
847
  this.__SettingsUpdate();
848
+
849
+ try {
850
+ if(client.NetworkInfo().name === "main") {
851
+ const explorerUrl = new URL("https://explorer.contentfabric.io/api");
852
+ explorerUrl.searchParams.set("module", "account");
853
+ explorerUrl.searchParams.set("action", "txlist");
854
+ explorerUrl.searchParams.set("offset", "1");
855
+ explorerUrl.searchParams.set("address", client.utils.HashToAddress(objectId));
856
+
857
+ this.contentAudit.details.latestTransactionHash = (await ((await fetch(explorerUrl)).json())).result[0].hash;
858
+ this.contentAudit.details.latestTransactionHashUrl = `https://explorer.contentfabric.io/tx/${this.contentAudit.details.latestTransactionHash}`;
859
+ }
860
+ // eslint-disable-next-line no-empty
861
+ } catch (error) {
862
+ } finally {
863
+ this.contentAudit.details._state = "full";
864
+ delete this.contentAudit.loading;
865
+
866
+ this.__SettingsUpdate();
867
+ }
851
868
  }
852
869
 
853
870
  // Indicate to controls that the settings have updated
@@ -29,6 +29,6 @@ export const CheckmarkIcon = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"
29
29
  export const CaptionsIcon = `<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"icon icon-tabler icon-tabler-badge-cc\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" stroke=\"black\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path> <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" stroke=\"currentColor\"></rect> <path d=\"M10 10.5a1.5 1.5 0 0 0 -3 0v3a1.5 1.5 0 0 0 3 0\" stroke=\"currentColor\"></path> <path d=\"M17 10.5a1.5 1.5 0 0 0 -3 0v3a1.5 1.5 0 0 0 3 0\" stroke=\"currentColor\"></path></svg>`;
30
30
  export const CaptionsOffIcon = `<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"icon icon-tabler icon-tabler-badge-cc\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" stroke=\"black\" stroke-width=\"2\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"> <path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"></path> <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" stroke=\"currentColor\"></rect> <path d=\"M10 10.5a1.5 1.5 0 0 0 -3 0v3a1.5 1.5 0 0 0 3 0\" stroke=\"currentColor\"></path> <path d=\"M17 10.5a1.5 1.5 0 0 0 -3 0v3a1.5 1.5 0 0 0 3 0\" stroke=\"currentColor\"></path> <path d=\"M3 3l18 18\" stroke=\"currentColor\"></path></svg>`;
31
31
  export const RotateIcon = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-rotate-cw\"><polyline points=\"23 4 23 10 17 10\"></polyline><path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\"></path></svg>`;
32
- export const ContentShieldIcon = `<svg width=\"30\" height=\"30\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15 27.5C15 27.5 25 22.5 25 15V6.25L15 2.5L5 6.25V15C5 22.5 15 27.5 15 27.5Z\" stroke=\"currentColor\" stroke-width=\"2.14286\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.715 11.3574L13.8221 17.8396L11.1436 14.8931\" stroke=\"currentColor\" stroke-width=\"2.14286\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;
32
+ export const ContentBadgeIcon = `<svg width=\"30\" height=\"30\" viewBox=\"0 0 30 30\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15 27.5C15 27.5 25 22.5 25 15V6.25L15 2.5L5 6.25V15C5 22.5 15 27.5 15 27.5Z\" stroke=\"currentColor\" stroke-width=\"2.14286\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M19.715 11.3574L13.8221 17.8396L11.1436 14.8931\" stroke=\"currentColor\" stroke-width=\"2.14286\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>`;
33
33
  export const ContentCredentialsIcon = `<svg width=\"26\" height=\"26\" viewBox=\"0 0 26 26\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M23.7508 12.9997V23.7508H13.0003C7.05943 23.7508 2.24919 18.9406 2.24919 12.9997C2.24919 7.05888 7.05943 2.24864 13.0003 2.24864C18.9411 2.24864 23.7508 7.05888 23.7508 12.9997ZM0 12.9997C0 5.82396 5.82396 0 12.9997 0C20.1755 0 26 5.82396 26 12.9997V25.9995H13.0003C5.82396 25.9995 0 20.1755 0 12.9997ZM5.174 13.5197C5.174 16.1976 6.98078 18.4599 9.85371 18.4599C12.2198 18.4599 13.8185 16.9 14.2084 14.8589H11.8686C11.5698 15.7951 10.8155 16.367 9.85371 16.367C8.39758 16.367 7.44886 15.2227 7.44886 13.5202C7.44886 11.8178 8.39813 10.6735 9.85371 10.6735C10.7899 10.6735 11.5305 11.2066 11.8429 12.0903H14.1959C13.7797 10.1011 12.1941 8.58055 9.85371 8.58055C6.96822 8.58001 5.174 10.8418 5.174 13.5197ZM17.3419 8.83999H15.132V18.2131H17.4331V13.3253C17.4331 12.4022 17.6931 11.8041 18.1349 11.4273C18.5249 11.0761 19.0318 10.8942 19.8642 10.8942H20.4491V8.72256H19.8773C18.668 8.72256 17.8624 9.16442 17.3424 9.8406V8.82633V8.83999H17.3419Z\" fill=\"currentColor\"/></svg>`;
34
34
  export const CopyIcon = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-copy\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>`;
@@ -450,6 +450,14 @@
450
450
  }
451
451
  }
452
452
 
453
+ &__loader {
454
+ align-items: center;
455
+ border-width: 3px;
456
+ display: flex;
457
+ height: 18px;
458
+ width: 18px;
459
+ }
460
+
453
461
  &__details {
454
462
  background: var(--color-menu-background-secondary);
455
463
  display: grid;
@@ -39,6 +39,8 @@
39
39
  }
40
40
 
41
41
  .autohide {
42
+ cursor: none;
43
+
42
44
  &:not(:has(:focus-visible)) {
43
45
  .bottom-controls-container--autohide {
44
46
  opacity: 0;
@@ -49,6 +49,8 @@
49
49
  }
50
50
 
51
51
  .autohide {
52
+ cursor: none;
53
+
52
54
  &:not(:has(:focus-visible)) {
53
55
  .info-container,
54
56
  .bottom-controls-container--autohide {
@@ -370,7 +372,7 @@
370
372
 
371
373
  .info-container {
372
374
  gap: 20px;
373
- padding-top: 20px;
375
+ padding-top: 15px;
374
376
  }
375
377
 
376
378
  .info-title {
@@ -414,6 +416,7 @@
414
416
 
415
417
  .info-container {
416
418
  padding-right: 80px;
419
+ padding-top: 10px;
417
420
  }
418
421
 
419
422
  .info-headers {
@@ -32,7 +32,7 @@ const iconSource = {
32
32
  CaptionsIcon: Path.resolve(__dirname, "../static/icons/svgs/captions.svg"),
33
33
  CaptionsOffIcon: Path.resolve(__dirname, "../static/icons/svgs/captions-off.svg"),
34
34
  RotateIcon: Path.resolve(__dirname, "../static/icons/svgs/rotate-cw.svg"),
35
- ContentShieldIcon: Path.resolve(__dirname, "../static/icons/svgs/shield.svg"),
35
+ ContentBadgeIcon: Path.resolve(__dirname, "../static/icons/svgs/content-badge.svg"),
36
36
  ContentCredentialsIcon: Path.resolve(__dirname, "../static/icons/svgs/content-credentials.svg"),
37
37
  CopyIcon: Path.resolve(__dirname, "../static/icons/svgs/copy.svg"),
38
38
  };
@@ -352,7 +352,7 @@ export const ContentVerificationMenu = ({player, Hide, className=""}) => {
352
352
  player.__LoadVerificationDetails()
353
353
  .then(() => setLoaded(true));
354
354
 
355
- const UpdateSettings = () => setAudit(player.controls.ContentVerificationDetails());
355
+ const UpdateSettings = () => setAudit(player.controls.GetContentVerificationDetails());
356
356
 
357
357
  UpdateSettings();
358
358
 
@@ -380,7 +380,7 @@ export const ContentVerificationMenu = ({player, Hide, className=""}) => {
380
380
  content = (
381
381
  <>
382
382
  <div className={CommonStyles["verification-menu__group"]}>
383
- <div dangerouslySetInnerHTML={{__html: Icons.ContentShieldIcon}} className={CommonStyles["verification-menu__group-icon"]} />
383
+ <div dangerouslySetInnerHTML={{__html: Icons.ContentBadgeIcon}} style={{width: 35, height: 35}} className={CommonStyles["verification-menu__group-icon"]} />
384
384
  <div className={CommonStyles["verification-menu__group-text"]}>
385
385
  <div className={CommonStyles["verification-menu__group-title"]}>
386
386
  This content has been verified as authentic
@@ -391,7 +391,7 @@ export const ContentVerificationMenu = ({player, Hide, className=""}) => {
391
391
  </div>
392
392
  </div>
393
393
  <div className={CommonStyles["verification-menu__group"]}>
394
- <div dangerouslySetInnerHTML={{__html: Icons.ContentCredentialsIcon}} className={CommonStyles["verification-menu__group-icon"]} />
394
+ <div dangerouslySetInnerHTML={{__html: Icons.ContentCredentialsIcon}} style={{height: 30, maxWidth: 30}} className={CommonStyles["verification-menu__group-icon"]} />
395
395
  <div className={CommonStyles["verification-menu__group-text"]}>
396
396
  <button onClick={() => setShowDetails(true)} className={CommonStyles["verification-menu__group-title"]}>
397
397
  View Content Credentials
@@ -405,7 +405,7 @@ export const ContentVerificationMenu = ({player, Hide, className=""}) => {
405
405
  content = (
406
406
  <>
407
407
  <div className={CommonStyles["verification-menu__group"]}>
408
- <div dangerouslySetInnerHTML={{__html: Icons.ContentShieldIcon}} className={CommonStyles["verification-menu__group-icon"]} />
408
+ <div dangerouslySetInnerHTML={{__html: Icons.ContentBadgeIcon}} style={{width: 50, height: 50}} className={CommonStyles["verification-menu__group-icon"]} />
409
409
  <div className={CommonStyles["verification-menu__group-text"]}>
410
410
  <div className={CommonStyles["verification-menu__group-title"]}>
411
411
  This content has been verified as authentic
@@ -429,36 +429,46 @@ export const ContentVerificationMenu = ({player, Hide, className=""}) => {
429
429
  </div>
430
430
  </div>
431
431
  </div>
432
- <div className={CommonStyles["verification-menu__details"]}>
432
+ <div className={CommonStyles["verification-menu__details"]} key={`details-${audit.details._state}`}>
433
433
  <ContentDetail label="Content Fabric Object ID" value={audit.details.objectId} copyable />
434
434
  <ContentDetail label="Organization Address" value={audit.details.tenantAddress} copyable />
435
- <ContentDetail label="Organization Name" value={audit.details.tenantName} />
435
+ <ContentDetail label="Organization Name" value={audit.details.tenantName && audit.details.tenantName.toString()} />
436
436
  <ContentDetail label="Owner Address" value={audit.details.ownerAddress} copyable />
437
- <ContentDetail label="Content Object Contract Address" value={audit.details.address} copyable />
437
+ <ContentDetail
438
+ label="Content Object Contract Address"
439
+ value={
440
+ audit.details.explorerUrl ?
441
+ <a href={audit.details.explorerUrl} target="_blank" rel="noreferrer">
442
+ {audit.details.address}
443
+ </a> :
444
+ audit.details.address
445
+ }
446
+ copyable
447
+ />
448
+ <ContentDetail label="Versions" value={audit.details.versionCount} />
438
449
  <ContentDetail label="Content Version Hash" value={audit.details.versionHash} copyable />
439
450
  {
440
451
  !audit.details.lastCommittedAt ? null :
441
- <ContentDetail label="Last Commit" value={new Date(audit.details.lastCommittedAt).toLocaleTimeString(navigator.language || "en-us", {year: "numeric", "month": "long", day: "numeric"})} />
452
+ <ContentDetail label="Latest Commit" value={new Date(audit.details.lastCommittedAt).toLocaleTimeString(navigator.language || "en-us", {year: "numeric", "month": "long", day: "numeric"})} />
442
453
  }
443
- <ContentDetail label="Versions" value={audit.details.versionCount} />
444
- {
445
- !audit.details.latestTransactionHash ? null :
446
- <ContentDetail
447
- label="Latest Transaction"
448
- value={
454
+ <ContentDetail label="Latest Version Hash" value={audit.details.latestVersionHash} copyable />
455
+ <ContentDetail
456
+ label="Latest Transaction"
457
+ value={
458
+ audit.details._state !== "full" ?
459
+ <Spinner className={CommonStyles["verification-menu__loader"]} /> :
460
+ audit.details.latestTransactionHashUrl ?
449
461
  <a href={audit.details.latestTransactionHashUrl} target="_blank" rel="noreferrer">
450
- { audit.details.latestTransactionHash }
451
- </a>
452
- }
453
- />
454
- }
462
+ { audit.details.latestTransactionHash && audit.details.latestTransactionHash.toString() }
463
+ </a> : undefined
464
+ }
465
+ />
455
466
  <ContentDetail label="Signature Algorithm" value={audit.details.signatureMethod} />
456
467
  </div>
457
468
  </>
458
469
  );
459
470
  }
460
471
 
461
-
462
472
  return (
463
473
  <div ref={menuRef}>
464
474
  <div key="menu" role="menu" className={`${CommonStyles["menu"]} ${CommonStyles["verification-menu"]} ${showDetails ? CommonStyles["verification-menu--details"] : ""} ${className}`}>
@@ -45,6 +45,7 @@ const Poster = ({player}) => {
45
45
  );
46
46
  };
47
47
 
48
+ let clearInteractionTimeout;
48
49
  const PlayerUI = ({target, parameters, InitCallback, ErrorCallback, Unmount, Reset}) => {
49
50
  const [player, setPlayer] = useState(undefined);
50
51
  const [client, setClient] = useState(undefined);
@@ -176,6 +177,15 @@ const PlayerUI = ({target, parameters, InitCallback, ErrorCallback, Unmount, Res
176
177
  };
177
178
  }, [playerSet]);
178
179
 
180
+ useEffect(() => {
181
+ if(!recentUserAction) { return; }
182
+ clearTimeout(clearInteractionTimeout);
183
+
184
+ setTimeout(() => {
185
+ setRecentUserAction(undefined);
186
+ }, 1000);
187
+ }, [recentUserAction]);
188
+
179
189
  if(parameters.clientOptions.promptTicket && !client) {
180
190
  return (
181
191
  <TicketForm
@@ -92,7 +92,7 @@ const CenterButtons = ({player, videoState}) => {
92
92
  );
93
93
  };
94
94
 
95
- const MenuButton = ({label, icon, children, player, setMenuActive, MenuComponent}) => {
95
+ const MenuButton = ({label, icon, children, player, MenuComponent}) => {
96
96
  const [show, setShow] = useState(false);
97
97
 
98
98
  return (
@@ -104,14 +104,14 @@ const MenuButton = ({label, icon, children, player, setMenuActive, MenuComponent
104
104
  aria-haspopup
105
105
  icon={icon}
106
106
  onClick={() => {
107
- setMenuActive(!show);
107
+ player.controls.__ToggleMenu(!show);
108
108
  setShow(!show);
109
109
  }}
110
110
  className={`${ControlStyles["icon-button--circle-focus"]} ${show ? ControlStyles["icon-button-active"] : ""}`}
111
111
  /> :
112
112
  <button
113
113
  onClick={() => {
114
- setMenuActive(!show);
114
+ player.controls.__ToggleMenu(!show);
115
115
  setShow(!show);
116
116
  }}
117
117
  className={`${ControlStyles["text-button"]} ${show ? ControlStyles["text-button--active"] : ""}`}
@@ -124,8 +124,8 @@ const MenuButton = ({label, icon, children, player, setMenuActive, MenuComponent
124
124
  <MenuComponent
125
125
  player={player}
126
126
  Hide={() => {
127
+ player.controls.__ToggleMenu(false);
127
128
  setShow(false);
128
- setMenuActive(false);
129
129
  }}
130
130
  className={ControlStyles["menu"]}
131
131
  />
@@ -211,7 +211,7 @@ const InfoBox = ({player, Hide}) => {
211
211
  );
212
212
  };
213
213
 
214
- const ContentVerificationControls = ({player, setMenuActive}) => {
214
+ const ContentVerificationControls = ({player}) => {
215
215
  const [contentVerified, setContentVerified] = useState(false);
216
216
 
217
217
  useEffect(() => {
@@ -229,9 +229,8 @@ const ContentVerificationControls = ({player, setMenuActive}) => {
229
229
  return (
230
230
  <MenuButton
231
231
  label="Content Verification Menu"
232
- icon={Icons.ContentShieldIcon}
232
+ icon={Icons.ContentBadgeIcon}
233
233
  player={player}
234
- setMenuActive={setMenuActive}
235
234
  MenuComponent={ContentVerificationMenu}
236
235
  className={ControlStyles["content-verification-menu-button"]}
237
236
  >
@@ -243,7 +242,6 @@ const ContentVerificationControls = ({player, setMenuActive}) => {
243
242
  const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRecentUserAction, className=""}) => {
244
243
  const [videoState, setVideoState] = useState(undefined);
245
244
  const [playerClickHandler, setPlayerClickHandler] = useState(undefined);
246
- const [menuActive, setMenuActive] = useState(false);
247
245
  const [showInfo, setShowInfo] = useState(false);
248
246
 
249
247
  useEffect(() => {
@@ -263,7 +261,7 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
263
261
  const collectionInfo = player.controls.GetCollectionInfo();
264
262
 
265
263
  // Title autohide is not dependent on controls settings
266
- const showUI = recentlyInteracted || !playbackStarted || menuActive;
264
+ const showUI = recentlyInteracted || !playbackStarted || player.controls.IsMenuVisible();
267
265
  const hideControls = !showUI && player.playerOptions.controls === EluvioPlayerParameters.controls.AUTO_HIDE;
268
266
 
269
267
  player.__SetControlsVisibility(!hideControls);
@@ -277,7 +275,7 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
277
275
  ControlStyles["container"],
278
276
  showUI ? "" : ControlStyles["autohide"],
279
277
  player.playerOptions.controls !== EluvioPlayerParameters.controls.DEFAULT ? "" : ControlStyles["container--default-controls"],
280
- menuActive ? "menu-active" : ""
278
+ player.controls.IsMenuVisible() ? "menu-active" : ""
281
279
  ].join(" ")}
282
280
  >
283
281
  <IconButton
@@ -318,7 +316,6 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
318
316
  label="Collection Menu"
319
317
  icon={Icons.CollectionIcon}
320
318
  player={player}
321
- setMenuActive={setMenuActive}
322
319
  MenuComponent={CollectionMenu}
323
320
  />
324
321
  }
@@ -335,7 +332,7 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
335
332
  </div>
336
333
  <CenterButtons player={player} videoState={videoState}/>
337
334
  <div className={ControlStyles["bottom-right-controls"]}>
338
- <ContentVerificationControls player={player} setMenuActive={setMenuActive} />
335
+ <ContentVerificationControls player={player} />
339
336
  {
340
337
  !player.controls.GetOptions().hasAnyOptions ? null :
341
338
  <MenuButton
@@ -343,7 +340,6 @@ const TVControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRe
343
340
  label="Settings"
344
341
  player={player}
345
342
  MenuComponent={SettingsMenu}
346
- setMenuActive={setMenuActive}
347
343
  >
348
344
  Settings
349
345
  </MenuButton>
@@ -76,7 +76,7 @@ const CollectionControls = ({player}) => {
76
76
  );
77
77
  };
78
78
 
79
- const MenuButton = ({label, icon, player, setMenuActive, MenuComponent, className=""}) => {
79
+ const MenuButton = ({label, icon, player, MenuComponent, className=""}) => {
80
80
  const [show, setShow] = useState(false);
81
81
 
82
82
  return (
@@ -86,7 +86,7 @@ const MenuButton = ({label, icon, player, setMenuActive, MenuComponent, classNam
86
86
  aria-haspopup
87
87
  icon={icon}
88
88
  onClick={() => {
89
- setMenuActive(!show);
89
+ player.controls.__ToggleMenu(!show);
90
90
  setShow(!show);
91
91
  }}
92
92
  className={show ? ControlStyles["icon-button-active"] : ""}
@@ -97,7 +97,7 @@ const MenuButton = ({label, icon, player, setMenuActive, MenuComponent, classNam
97
97
  player={player}
98
98
  Hide={() => {
99
99
  setShow(false);
100
- setMenuActive(false);
100
+ player.controls.__ToggleMenu(false);
101
101
  }}
102
102
  />
103
103
  }
@@ -154,7 +154,7 @@ const ContentInfo = ({player}) => {
154
154
  );
155
155
  };
156
156
 
157
- const ContentVerificationControls = ({player, setMenuActive}) => {
157
+ const ContentVerificationControls = ({player}) => {
158
158
  const [contentVerified, setContentVerified] = useState(false);
159
159
 
160
160
  useEffect(() => {
@@ -176,9 +176,8 @@ const ContentVerificationControls = ({player, setMenuActive}) => {
176
176
  </div>
177
177
  <MenuButton
178
178
  label="Content Verification Menu"
179
- icon={Icons.ContentShieldIcon}
179
+ icon={Icons.ContentBadgeIcon}
180
180
  player={player}
181
- setMenuActive={setMenuActive}
182
181
  MenuComponent={ContentVerificationMenu}
183
182
  className={ControlStyles["content-verification-menu-button"]}
184
183
  />
@@ -189,7 +188,6 @@ const ContentVerificationControls = ({player, setMenuActive}) => {
189
188
  const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setRecentUserAction, className=""}) => {
190
189
  const [videoState, setVideoState] = useState(undefined);
191
190
  const [playerClickHandler, setPlayerClickHandler] = useState(undefined);
192
- const [activeMenus, setActiveMenus] = useState(0);
193
191
 
194
192
  useEffect(() => {
195
193
  setPlayerClickHandler(PlayerClick({player, setRecentUserAction}));
@@ -202,11 +200,9 @@ const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setR
202
200
  if(!videoState) { return null; }
203
201
 
204
202
  const collectionInfo = player.controls.GetCollectionInfo();
205
- const menuActive = activeMenus > 0;
206
- const setMenuActive = active => setActiveMenus(active ? activeMenus + 1 : Math.max(0, activeMenus - 1));
207
203
 
208
204
  // Title autohide is not dependent on controls settings
209
- const showUI = recentlyInteracted || !playbackStarted || menuActive;
205
+ const showUI = recentlyInteracted || !playbackStarted || player.controls.IsMenuVisible();
210
206
  const hideControls = !showUI && player.playerOptions.controls === EluvioPlayerParameters.controls.AUTO_HIDE;
211
207
 
212
208
  player.__SetControlsVisibility(!hideControls);
@@ -219,7 +215,7 @@ const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setR
219
215
  ControlStyles["container"],
220
216
  showUI ? "" : ControlStyles["autohide"],
221
217
  player.playerOptions.controls !== EluvioPlayerParameters.controls.DEFAULT ? "" : ControlStyles["container--default-controls"],
222
- menuActive ? "menu-active" : ""
218
+ player.controls.IsMenuVisible() ? "menu-active" : ""
223
219
  ].join(" ")}
224
220
  >
225
221
  <ContentInfo key={`content-info-${collectionInfo && collectionInfo.mediaIndex}`} player={player} />
@@ -258,10 +254,7 @@ const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setR
258
254
 
259
255
  <div className={ControlStyles["spacer"]}/>
260
256
 
261
- <ContentVerificationControls
262
- player={player}
263
- setMenuActive={setMenuActive}
264
- />
257
+ <ContentVerificationControls player={player} />
265
258
 
266
259
  {
267
260
  !collectionInfo ? null :
@@ -269,7 +262,6 @@ const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setR
269
262
  label="Collection Menu"
270
263
  icon={Icons.CollectionIcon}
271
264
  player={player}
272
- setMenuActive={setMenuActive}
273
265
  MenuComponent={CollectionMenu}
274
266
  />
275
267
  }
@@ -288,7 +280,6 @@ const WebControls = ({player, playbackStarted, canPlay, recentlyInteracted, setR
288
280
  label="Settings Menu"
289
281
  icon={Icons.SettingsIcon}
290
282
  player={player}
291
- setMenuActive={setMenuActive}
292
283
  MenuComponent={SettingsMenu}
293
284
  />
294
285
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eluvio/elv-player-js",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "![Eluvio Logo](lib/static/images/Logo.png \"Eluvio Logo\")",
5
5
  "main": "lib/index.js",
6
6
  "license": "MIT",
@@ -36,7 +36,7 @@
36
36
  "package-lock.json"
37
37
  ],
38
38
  "dependencies": {
39
- "@eluvio/elv-client-js": "^4.0.87",
39
+ "@eluvio/elv-client-js": "^4.0.88",
40
40
  "dashjs": "~4.7.0",
41
41
  "focus-visible": "^5.2.0",
42
42
  "hls.js": "~1.4.12",