"use client" import React, { createContext, useState } from "react"; import { useConfig } from "./useConfig"; import { useCallback } from "react"; // Note: cloud mode is only used in our private, hosted version export type Mode = "cloud" | "env" | "manual"; type TokenGeneratorData = { shouldConnect: boolean; wsUrl: string; token: string; disconnect: () => Promise; connect: (mode: Mode) => Promise; }; const TokenGeneratorContext = createContext(undefined); export const TokenGeneratorProvider = ({ children, generateConnectionDetails, }: { children: React.ReactNode; // generateConnectionDetails is only required in cloud mode generateConnectionDetails?: () => Promise<{ wsUrl: string; token: string }>; }) => { const { config } = useConfig(); const [token, setToken] = useState(""); const [wsUrl, setWsUrl] = useState(""); const [shouldConnect, setShouldConnect] = useState(false); const connect = useCallback( async (mode: Mode) => { console.log("connecting", mode); if (mode === "cloud") { if (!generateConnectionDetails) { throw new Error( "generateConnectionDetails must be provided in cloud mode" ); } const { wsUrl, token } = await generateConnectionDetails(); setWsUrl(wsUrl); setToken(token); } else if (mode === "env") { const url = process.env.NEXT_PUBLIC_LIVEKIT_URL; if (!url) { throw new Error("NEXT_PUBLIC_LIVEKIT_URL must be set in env mode"); } const res = await fetch("/api/token"); const { accessToken } = await res.json(); setWsUrl(url); setToken(accessToken); } else if (mode === "manual") { setWsUrl(config.settings.ws_url); setToken(config.settings.token); } setShouldConnect(true); }, [ config.settings.token, config.settings.ws_url, generateConnectionDetails, ] ); const disconnect = useCallback(async () => { setShouldConnect(false); }, []); return ( {children} ); }; export const useTokenGenerator = () => { const context = React.useContext(TokenGeneratorContext); if (context === undefined) { throw new Error("useTokenGenerator must be used within a TokenGeneratorProvider"); } return context; }