diff --git a/package.json b/package.json
index 85f6c07..4820956 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
"react-dom": "19",
"react-hook-form": "^7.54.2",
"sonner": "^1.4.41",
+ "swr": "^2.3.0",
"tailwind-merge": "^2.2.2",
"tailwindcss-animate": "^1.0.7",
"valtio": "^2.1.2",
diff --git a/src/app/(protected)/api/livekit/broadcasterToken/route.ts b/src/app/(protected)/api/livekit/broadcasterToken/route.ts
index d248867..ee0f1b1 100644
--- a/src/app/(protected)/api/livekit/broadcasterToken/route.ts
+++ b/src/app/(protected)/api/livekit/broadcasterToken/route.ts
@@ -1,25 +1,38 @@
+import { validateRequest } from '@/lib/auth';
import { ingressClient, roomService } from '@/lib/services/livekit';
import { IngressInput } from 'livekit-server-sdk';
-export async function GET(request: Request) {
- const { searchParams } = new URL(request.url);
- const room = searchParams.get('room');
+export async function GET() {
+ const { user } = await validateRequest();
- if (!room) {
- return new Response('Missing room', { status: 400 });
+ if (!user) {
+ return new Response('Unauthorized', { status: 401 });
}
+ // delete all ingresses, deprecation should be fine :clueless:
+ const ingresses = await ingressClient.listIngress();
+ const userIngresses = ingresses.filter(ingress => ingress.name === user.username);
+
+ for (const ingress of userIngresses) {
+ await ingressClient.deleteIngress(ingress.ingressId);
+ }
+
+ // dleete and recreate room
+ const room = (await roomService.listRooms()).filter((r) => r.name === user.username)[0];
+ if (room) {
+ await roomService.deleteRoom(room.name);
+ }
+
await roomService.createRoom({
- name: room,
- })
- const ingress = await ingressClient.createIngress(
- IngressInput.RTMP_INPUT,
- {
- name: room,
- roomName: room,
- participantIdentity: 'streamer',
- }
- )
+ name: user.username,
+ });
+
+ // create new ingress
+ const ingress = await ingressClient.createIngress(IngressInput.RTMP_INPUT, {
+ name: user.username,
+ roomName: user.username,
+ participantIdentity: 'streamer',
+ });
return Response.json({ key: ingress.streamKey });
}
\ No newline at end of file
diff --git a/src/components/app/EditLivestream/EditLivestream.tsx b/src/components/app/EditLivestream/EditLivestream.tsx
index 21826e2..9ce89c4 100644
--- a/src/components/app/EditLivestream/EditLivestream.tsx
+++ b/src/components/app/EditLivestream/EditLivestream.tsx
@@ -12,6 +12,7 @@ import prisma from '@/lib/db';
import { roomService } from '@/lib/services/livekit';
import { UniversalForm } from '../UniversalForm/UniversalForm';
import { editStreamInfo } from '@/lib/form/actions';
+import RegenerateKey from '../RegenerateKey/RegenerateKey';
export default async function EditLivestream() {
const { user } = await validateRequest();
@@ -55,6 +56,9 @@ export default async function EditLivestream() {
action={editStreamInfo}
submitButtonDivClassname="float-right"
submitText="Save"
+ otherSubmitButton={
+
+ }
key={streamInfo?.id}
/>
diff --git a/src/components/app/RegenerateKey/RegenerateKey.tsx b/src/components/app/RegenerateKey/RegenerateKey.tsx
new file mode 100644
index 0000000..7c258ab
--- /dev/null
+++ b/src/components/app/RegenerateKey/RegenerateKey.tsx
@@ -0,0 +1,37 @@
+'use client';
+
+import { Button } from '@/components/ui/button';
+import { fetcher as defaultFetcher } from '@/lib/services/swr';
+import React from 'react';
+import { toast } from 'sonner';
+import useSWR from 'swr/mutation';
+
+export default function RegenerateKey() {
+ const { error, isMutating, trigger } = useSWR('/api/livekit/broadcasterToken', async (url) =>
+ defaultFetcher(url)
+ );
+
+ React.useEffect(() => {
+ if (error) {
+ toast.error(error);
+ }
+ }, [error]);
+
+ return (
+
+ );
+}
diff --git a/src/lib/services/swr.ts b/src/lib/services/swr.ts
new file mode 100644
index 0000000..ee9c742
--- /dev/null
+++ b/src/lib/services/swr.ts
@@ -0,0 +1,3 @@
+type FetcherArgs = Parameters;
+
+export const fetcher = (...args: FetcherArgs): Promise => fetch(...args).then(res => res.json());
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 93b0366..f582b52 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1807,6 +1807,11 @@ define-properties@^1.1.3, define-properties@^1.2.1:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
+dequal@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
+ integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+
detect-libc@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700"
@@ -4255,6 +4260,14 @@ supports-preserve-symlinks-flag@^1.0.0:
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
+swr@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/swr/-/swr-2.3.0.tgz#66fa45023efd4199f4e7ce608c255709a135943d"
+ integrity sha512-NyZ76wA4yElZWBHzSgEJc28a0u6QZvhb6w0azeL2k7+Q1gAzVK+IqQYXhVOC/mzi+HZIozrZvBVeSeOZNR2bqA==
+ dependencies:
+ dequal "^2.0.3"
+ use-sync-external-store "^1.4.0"
+
tailwind-merge@^2.2.2:
version "2.6.0"
resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.6.0.tgz#ac5fb7e227910c038d458f396b7400d93a3142d5"
@@ -4500,6 +4513,11 @@ use-sidecar@^1.1.2:
detect-node-es "^1.1.0"
tslib "^2.0.0"
+use-sync-external-store@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz#adbc795d8eeb47029963016cefdf89dc799fcebc"
+ integrity sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==
+
usehooks-ts@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/usehooks-ts/-/usehooks-ts-3.1.0.tgz#156119f36efc85f1b1952616c02580f140950eca"