diff --git a/package-lock.json b/package-lock.json
index 11b495d..eb44095 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,8 +19,7 @@
"next": "^14.0.4",
"qrcode.react": "^3.1.0",
"react": "^18",
- "react-dom": "^18",
- "react-hot-toast": "^2.4.1"
+ "react-dom": "^18"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
@@ -2008,7 +2007,8 @@
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
- "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "devOptional": true
},
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
@@ -3073,14 +3073,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/goober": {
- "version": "2.1.14",
- "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.14.tgz",
- "integrity": "sha512-4UpC0NdGyAFqLNPnhCT2iHpza2q+RAY3GV85a/mRPdzyPQMsj0KmMMuetdIkzWRbJ+Hgau1EZztq8ImmiMGhsg==",
- "peerDependencies": {
- "csstype": "^3.0.10"
- }
- },
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -4609,21 +4601,6 @@
"react": "^18.3.1"
}
},
- "node_modules/react-hot-toast": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.4.1.tgz",
- "integrity": "sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==",
- "dependencies": {
- "goober": "^2.1.10"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "react": ">=16",
- "react-dom": ">=16"
- }
- },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
diff --git a/package.json b/package.json
index 0db5564..612a7c5 100644
--- a/package.json
+++ b/package.json
@@ -20,8 +20,7 @@
"next": "^14.0.4",
"qrcode.react": "^3.1.0",
"react": "^18",
- "react-dom": "^18",
- "react-hot-toast": "^2.4.1"
+ "react-dom": "^18"
},
"devDependencies": {
"@types/js-yaml": "^4.0.9",
diff --git a/src/components/toast/PlaygroundToast.tsx b/src/components/toast/PlaygroundToast.tsx
index a444fde..86e72d5 100644
--- a/src/components/toast/PlaygroundToast.tsx
+++ b/src/components/toast/PlaygroundToast.tsx
@@ -1,3 +1,5 @@
+import { useToast } from "./ToasterProvider";
+
export type ToastType = "error" | "success" | "info";
export type ToastProps = {
message: string;
@@ -5,16 +7,24 @@ export type ToastProps = {
onDismiss: () => void;
};
-export const PlaygroundToast = ({ message, type, onDismiss }: ToastProps) => {
+export const PlaygroundToast = () => {
+ const { toastMessage, setToastMessage } = useToast();
const color =
- type === "error" ? "red" : type === "success" ? "green" : "amber";
+ toastMessage?.type === "error"
+ ? "red"
+ : toastMessage?.type === "success"
+ ? "green"
+ : "amber";
+
return (
- {message}
+ {toastMessage?.message}
);
};
diff --git a/src/components/toast/ToasterProvider.tsx b/src/components/toast/ToasterProvider.tsx
new file mode 100644
index 0000000..38aa174
--- /dev/null
+++ b/src/components/toast/ToasterProvider.tsx
@@ -0,0 +1,40 @@
+"use client"
+
+import React, { createContext, useState } from "react";
+import { ToastType } from "./PlaygroundToast";
+
+type ToastProviderData = {
+ setToastMessage: (
+ message: { message: string; type: ToastType } | null
+ ) => void;
+ toastMessage: { message: string; type: ToastType } | null;
+};
+
+const ToastContext = createContext(undefined);
+
+export const ToastProvider = ({
+ children,
+}: {
+ children: React.ReactNode;
+}) => {
+ const [toastMessage, setToastMessage] = useState<{message: string, type: ToastType} | null>(null);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useToast = () => {
+ const context = React.useContext(ToastContext);
+ if (context === undefined) {
+ throw new Error("useToast must be used within a ToastProvider");
+ }
+ return context;
+}
\ No newline at end of file
diff --git a/src/hooks/useConnection.tsx b/src/hooks/useConnection.tsx
index 0ed145f..f0fa548 100644
--- a/src/hooks/useConnection.tsx
+++ b/src/hooks/useConnection.tsx
@@ -4,7 +4,7 @@ import { useCloud } from "@/cloud/useCloud";
import React, { createContext, useState } from "react";
import { useCallback } from "react";
import { useConfig } from "./useConfig";
-import toast from "react-hot-toast";
+import { useToast } from "@/components/toast/ToasterProvider";
export type ConnectionMode = "cloud" | "manual" | "env"
@@ -25,6 +25,7 @@ export const ConnectionProvider = ({
children: React.ReactNode;
}) => {
const { generateToken, wsUrl: cloudWSUrl } = useCloud();
+ const { setToastMessage } = useToast();
const { config } = useConfig();
const [connectionDetails, setConnectionDetails] = useState<{
wsUrl: string;
@@ -33,36 +34,44 @@ export const ConnectionProvider = ({
shouldConnect: boolean;
}>({ wsUrl: "", token: "", shouldConnect: false, mode: "manual" });
- const connect = useCallback(async (mode: ConnectionMode) => {
- let token = "";
- let url = "";
- if (mode === "cloud") {
- try {
- token = await generateToken();
- } catch (error) {
- toast.error(
- "Failed to generate token, you may need to increase your role in this LiveKit Cloud project."
+ const connect = useCallback(
+ async (mode: ConnectionMode) => {
+ let token = "";
+ let url = "";
+ if (mode === "cloud") {
+ try {
+ token = await generateToken();
+ } catch (error) {
+ setToastMessage({
+ type: "error",
+ message:
+ "Failed to generate token, you may need to increase your role in this LiveKit Cloud project.",
+ });
+ }
+ url = cloudWSUrl;
+ } else if (mode === "env") {
+ if (!process.env.NEXT_PUBLIC_LIVEKIT_URL) {
+ throw new Error("NEXT_PUBLIC_LIVEKIT_URL is not set");
+ }
+ url = process.env.NEXT_PUBLIC_LIVEKIT_URL;
+ const { accessToken } = await fetch("/api/token").then((res) =>
+ res.json()
);
+ token = accessToken;
+ } else {
+ token = config.settings.token;
+ url = config.settings.ws_url;
}
- url = cloudWSUrl;
- } else if (mode === "env") {
- if(!process.env.NEXT_PUBLIC_LIVEKIT_URL) {
- throw new Error("NEXT_PUBLIC_LIVEKIT_URL is not set");
- }
- url = process.env.NEXT_PUBLIC_LIVEKIT_URL;
- const {accessToken} = await fetch("/api/token").then((res) => res.json());
- token = accessToken;
- } else {
- token = config.settings.token;
- url = config.settings.ws_url;
- }
- setConnectionDetails({ wsUrl: url, token, shouldConnect: true, mode });
- }, [
- cloudWSUrl,
- config.settings.token,
- config.settings.ws_url,
- generateToken,
- ]);
+ setConnectionDetails({ wsUrl: url, token, shouldConnect: true, mode });
+ },
+ [
+ cloudWSUrl,
+ config.settings.token,
+ config.settings.ws_url,
+ generateToken,
+ setToastMessage,
+ ]
+ );
const disconnect = useCallback(async () => {
setConnectionDetails((prev) => ({ ...prev, shouldConnect: false }));
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index c68396e..7c501ee 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,12 +1,10 @@
import { CloudProvider } from "@/cloud/useCloud";
import "@/styles/globals.css";
import type { AppProps } from "next/app";
-import { Toaster } from "react-hot-toast";
export default function App({ Component, pageProps }: AppProps) {
return (
-
);}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index 7517966..9243af0 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -14,6 +14,7 @@ import { PlaygroundToast, ToastType } from "@/components/toast/PlaygroundToast";
import { ConfigProvider, useConfig } from "@/hooks/useConfig";
import { ConnectionMode, ConnectionProvider, useConnection } from "@/hooks/useConnection";
import { useMemo } from "react";
+import { ToastProvider, useToast } from "@/components/toast/ToasterProvider";
const themeColors = [
"cyan",
@@ -30,23 +31,22 @@ const inter = Inter({ subsets: ["latin"] });
export default function Home() {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
}
export function HomeInner() {
- const [toastMessage, setToastMessage] = useState<{
- message: string;
- type: ToastType;
- } | null>(null);
const { shouldConnect, wsUrl, token, mode, connect, disconnect } =
useConnection();
const {config} = useConfig();
+ const { toastMessage, setToastMessage } = useToast();
const handleConnect = useCallback(
async (c: boolean, mode: ConnectionMode) => {
@@ -93,13 +93,7 @@ export function HomeInner() {
animate={{ opacity: 1, translateY: 0 }}
exit={{ opacity: 0, translateY: -50 }}
>
- {
- setToastMessage(null);
- }}
- />
+
)}