This commit is contained in:
PxlLoewe
2025-03-16 13:56:18 -07:00
parent cf61740698
commit 4862f73612
26 changed files with 1268 additions and 160 deletions

View File

@@ -1,35 +0,0 @@
"use client";
export const ChangeRufgruppe = () => {
return (
<>
<details className="dropdown">
<summary className="dropdown flex items-center gap-1">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
/>
</svg>
<div className="badge badge-soft badge-success">1</div>
</summary>
<ul className="menu dropdown-content bg-base-100 rounded-box z-1 w-52 p-2 shadow-sm">
<li>
<a>Rufgruppe 1</a>
</li>
<li>
<a>Rufgruppe 2</a>
</li>
</ul>
</details>
</>
);
};

View File

@@ -1,12 +1,12 @@
"use client";
import { ToggleTalkButton } from "../ToggleTalkButton";
import { ChangeRufgruppe } from "../ChangeRufgruppe";
import { Notifications } from "../Notifications";
import Link from "next/link";
import { Connection } from "../Connection";
import { ThemeSwap } from "./_components/ThemeSwap";
import { useState } from "react";
import { Audio } from "./_components/Audio";
export default function Navbar() {
const [isDark, setIsDark] = useState(false);
@@ -31,7 +31,7 @@ export default function Navbar() {
<ToggleTalkButton />
</li>
<li>
<ChangeRufgruppe />
<Audio />
</li>
</ul>
</div>

View File

@@ -0,0 +1,159 @@
"use client";
import { useEffect, useState } from "react";
import {
LocalParticipant,
LocalTrackPublication,
Participant,
RemoteParticipant,
RemoteTrack,
RemoteTrackPublication,
Room,
RoomEvent,
Track,
VideoPresets,
} from "livekit-client";
import { connectionStore } from "../../../../_store/connectionStore";
export const Audio = () => {
const connection = connectionStore();
const [token, setToken] = useState("");
const [room, setRoom] = useState<Room | null>(null);
useEffect(() => {
const fetchToken = async () => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_DISPATCH_SERVER_URL}/livekit/token`,
);
const data = await response.json();
setToken(data.token);
};
fetchToken();
}, []);
useEffect(() => {
const joinRoom = async () => {
if (!connection.isConnected) return;
/* if (!token) return;
if (!process.env.NEXT_PUBLIC_LIVEKIT_URL)
return console.error("NEXT_PUBLIC_LIVEKIT_URL not set");
console.log("COnnecting to room", {
token,
url: process.env.NEXT_PUBLIC_LIVEKIT_URL,
}); */
const url = "ws://localhost:7880";
const token =
"eyJhbGciOiJIUzI1NiJ9.eyJ2aWRlbyI6eyJyb29tSm9pbiI6dHJ1ZSwicm9vbSI6InF1aWNrc3RhcnQtcm9vbSJ9LCJpc3MiOiJBUElBbnNHZHRkWXAySG8iLCJleHAiOjE3NDIxNDk3MzAsIm5iZiI6MCwic3ViIjoicXVpY2tzdGFydC11c2VybmFtZSJ9.MVFDpwvjCF_AXjL9Mg40TFoKukZ4F3vOVB4DI_TZhHM";
console.log("Connecting to room", { token, url });
const room = new Room({
// automatically manage subscribed video quality
adaptiveStream: true,
// optimize publishing bandwidth and CPU for published tracks
dynacast: true,
// default capture settings
videoCaptureDefaults: {
resolution: VideoPresets.h720.resolution,
},
});
// pre-warm connection, this can be called as early as your page is loaded
room.prepareConnection(url, token);
// set up event listeners
room
.on(RoomEvent.TrackSubscribed, handleTrackSubscribed)
.on(RoomEvent.TrackUnsubscribed, handleTrackUnsubscribed)
.on(RoomEvent.ActiveSpeakersChanged, handleActiveSpeakerChange)
.on(RoomEvent.Disconnected, handleDisconnect)
.on(RoomEvent.LocalTrackUnpublished, handleLocalTrackUnpublished);
// connect to room
await room.connect(url, token);
console.log("connected to room", room.name);
// publish local camera and mic tracks
await room.localParticipant.enableCameraAndMicrophone();
function handleTrackSubscribed(
track: RemoteTrack,
publication: RemoteTrackPublication,
participant: RemoteParticipant,
) {
if (
track.kind === Track.Kind.Video ||
track.kind === Track.Kind.Audio
) {
// attach it to a new HTMLVideoElement or HTMLAudioElement
const element = track.attach();
}
}
function handleTrackUnsubscribed(
track: RemoteTrack,
publication: RemoteTrackPublication,
participant: RemoteParticipant,
) {
// remove tracks from all attached elements
track.detach();
}
function handleLocalTrackUnpublished(
publication: LocalTrackPublication,
participant: LocalParticipant,
) {
// when local tracks are ended, update UI to remove them from rendering
publication.track?.detach();
}
function handleActiveSpeakerChange(speakers: Participant[]) {
// show UI indicators when participant is speaking
}
function handleDisconnect() {
console.log("disconnected from room");
}
setRoom(room);
};
joinRoom();
return () => {
room?.disconnect();
};
}, [token, connection.isConnected]);
return (
<>
<details className="dropdown">
<summary className="dropdown flex items-center gap-1">
<svg
xmlns="http://www.w3.org/2000/svg"
className="h-5 w-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
/>
</svg>
<div className="badge badge-soft badge-success">1</div>
</summary>
<ul className="menu dropdown-content bg-base-100 rounded-box z-1 w-52 p-2 shadow-sm">
<li>
<a>Rufgruppe 1</a>
</li>
<li>
<a>Rufgruppe 2</a>
</li>
</ul>
</details>
</>
);
};