Merge branch 'main' of https://github.com/VAR-Virtual-Air-Rescue/var-monorepo
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,11 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import { ToggleTalkButton } from "../ToggleTalkButton";
|
||||
<<<<<<< HEAD
|
||||
import { ChangeRufgruppe } from "../ChangeRufgruppe";
|
||||
=======
|
||||
import { Notifications } from "../Notifications";
|
||||
>>>>>>> 4862f736124cb26fdc154299b855a830e1248452
|
||||
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);
|
||||
@@ -30,7 +35,7 @@ export default function Navbar() {
|
||||
<ToggleTalkButton />
|
||||
</li>
|
||||
<li>
|
||||
<ChangeRufgruppe />
|
||||
<Audio />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user