Start chromecast SDK only once

This commit is contained in:
Manav Rathi 2024-05-04 10:49:33 +05:30
parent 1dafec15c7
commit 3c3955017e
No known key found for this signature in database
4 changed files with 38 additions and 33 deletions

View file

@ -5,17 +5,13 @@ import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { storeCastData } from "services/cast";
import { advertiseCode, getCastData, register } from "services/pair";
import { useCastReceiver } from "../utils/useCastReceiver";
import { castReceiverLoadingIfNeeded } from "../utils/cast-receiver";
export default function PairingMode() {
const [publicKeyB64, setPublicKeyB64] = useState<string | undefined>();
const [privateKeyB64, setPrivateKeyB64] = useState<string | undefined>();
const [pairingCode, setPairingCode] = useState<string | undefined>();
// The returned cast object is a reference to a global instance and can be
// used in a useEffect dependency list.
const cast = useCastReceiver();
const router = useRouter();
const init = () => {
@ -31,8 +27,10 @@ export default function PairingMode() {
}, []);
useEffect(() => {
if (cast) advertiseCode(cast, () => pairingCode);
}, [cast]);
castReceiverLoadingIfNeeded().then((cast) =>
advertiseCode(cast, () => pairingCode),
);
}, []);
const pollTick = async () => {
const registration = { publicKeyB64, privateKeyB64, pairingCode };

View file

@ -3,7 +3,7 @@ import { boxSealOpen, toB64 } from "@ente/shared/crypto/internal/libsodium";
import castGateway from "@ente/shared/network/cast";
import { wait } from "@ente/shared/utils";
import _sodium from "libsodium-wrappers";
import { type Cast } from "../utils/useCastReceiver";
import { type Cast } from "../utils/cast-receiver";
export interface Registration {
/** A pairing code shown on the screen. A client can use this to connect. */

View file

@ -0,0 +1,32 @@
/// <reference types="chromecast-caf-receiver" />
export type Cast = typeof cast;
let _cast: Cast | undefined;
let _loader: Promise<Cast> | undefined;
/**
* Load the Chromecast Web Receiver SDK and return a reference to the `cast`
* global object that the SDK attaches to the window.
*
* Calling this function multiple times is fine, once the Chromecast SDK is
* loaded it'll thereafter return the reference to the same object always.
*
* https://developers.google.com/cast/docs/web_receiver/basic
*/
export const castReceiverLoadingIfNeeded = async (): Promise<Cast> => {
if (_cast) return _cast;
if (_loader) return await _loader;
_loader = new Promise((resolve) => {
const script = document.createElement("script");
script.src =
"https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js";
script.addEventListener("load", () => resolve(cast));
document.body.appendChild(script);
});
const c = await _loader;
_cast = c;
return c;
};

View file

@ -1,25 +0,0 @@
/// <reference types="chromecast-caf-receiver" />
import { useEffect, useState } from "react";
export type Cast = typeof cast;
/**
* Load the Chromecast Web Receiver SDK and return a reference to the `cast`
* global object that the SDK attaches to the window.
*
* https://developers.google.com/cast/docs/web_receiver/basic
*/
export const useCastReceiver = () => {
const [receiver, setReceiver] = useState<Cast | undefined>();
useEffect(() => {
const script = document.createElement("script");
script.src =
"https://www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js";
script.addEventListener("load", () => setReceiver(cast));
document.body.appendChild(script);
}, []);
return receiver;
};