Files
var-monorepo/apps/dispatch/app/_components/navbar/Settings.tsx

243 lines
6.9 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
import { GearIcon } from "@radix-ui/react-icons";
import { SettingsIcon, Volume2 } from "lucide-react";
import MicVolumeBar from "_components/MicVolumeIndication";
import { useMutation, useQuery } from "@tanstack/react-query";
import { editUserAPI, getUserAPI } from "_querys/user";
import { useSession } from "next-auth/react";
import { useAudioStore } from "_store/audioStore";
import toast from "react-hot-toast";
export const SettingsBtn = () => {
const session = useSession();
const { data: user } = useQuery({
queryKey: ["user", session.data?.user.id],
queryFn: () => getUserAPI(session.data!.user.id),
});
const testSoundRef = useRef<HTMLAudioElement | null>(null);
const editUserMutation = useMutation({
mutationFn: editUserAPI,
});
useEffect(() => {
if (typeof window !== "undefined") {
testSoundRef.current = new Audio("/sounds/Melder3.wav");
}
}, []);
const modalRef = useRef<HTMLDialogElement>(null);
const [inputDevices, setInputDevices] = useState<MediaDeviceInfo[]>([]);
const [selectedDevice, setSelectedDevice] = useState<string | null>(
user?.settingsMicDevice || null,
);
const [showIndication, setShowIndication] = useState<boolean>(false);
const [micVol, setMicVol] = useState<number>(1);
const [funkVolume, setFunkVol] = useState<number>(0.8);
const [dmeVolume, setDmeVol] = useState<number>(0.8);
const setMic = useAudioStore((state) => state.setMic);
useEffect(() => {
if (user) {
setSelectedDevice(user.settingsMicDevice);
setMic(user.settingsMicDevice, user.settingsMicVolume || 1);
setMicVol(user.settingsMicVolume || 1);
setFunkVol(user.settingsRadioVolume || 0.8);
setDmeVol(user.settingsDmeVolume || 0.8);
}
}, [user, setMic]);
useEffect(() => {
const setDevices = async () => {
if (typeof navigator !== "undefined" && navigator.mediaDevices?.enumerateDevices) {
const stream = await navigator.mediaDevices.getUserMedia({ video: false, audio: true });
const devices = await navigator.mediaDevices.enumerateDevices();
setInputDevices(devices.filter((d) => d.kind === "audioinput"));
stream.getTracks().forEach((track) => track.stop());
}
};
setDevices();
}, []);
return (
<div>
<button
className="btn btn-ghost"
onSubmit={() => false}
onClick={() => {
modalRef.current?.showModal();
}}
>
<GearIcon className="w-5 h-5" />
</button>
<dialog ref={modalRef} className="modal">
<div className="modal-box">
<h3 className="flex items-center gap-2 text-lg font-bold mb-5">
<SettingsIcon size={20} /> Einstellungen
</h3>
<div className="flex flex-col items-center justify-center">
<fieldset className="fieldset w-full mb-2">
<label className="floating-label w-full text-base">
<span>Eingabegerät</span>
<select
className="input w-full"
value={selectedDevice ? selectedDevice : ""}
onChange={(e) => {
setSelectedDevice(e.target.value);
setShowIndication(true);
}}
>
<option key={0} value={0} disabled>
Bitte wähle ein Eingabegerät...
</option>
{inputDevices.map((device, index) => (
<option key={index} value={device.deviceId}>
{device.label}
</option>
))}
</select>
</label>
</fieldset>
<p className="flex items-center gap-2 text-base mb-2 justify-start w-full">
<Volume2 size={20} /> Eingabelautstärke
</p>
{/*
TODO: Livekit Kann aktuell keine Lautstärke manuell überschreiben, daher ist die MicVolumeBar deaktiviert
<div className="w-full">
<input
type="range"
min={0}
max={3}
step={0.01}
onChange={(e) => {
const value = parseFloat(e.target.value);
setMicVol(value);
setShowIndication(true);
}}
value={micVol}
className="range range-xs range-accent w-full"
/>
<div className="flex justify-between px-2.5 mt-2 text-xs">
<span>0%</span>
<span>25%</span>
<span>50%</span>
<span>75%</span>
<span>100%</span>
</div>
</div>
{showIndication && (
<MicVolumeBar deviceId={selectedDevice ? selectedDevice : ""} volumeInput={micVol} />
)} */}
<div className="divider w-full" />
</div>
<p className="flex items-center gap-2 text-base mb-2">
<Volume2 size={20} /> Funk Lautstärke
</p>
<div className="w-full mb-2">
<input
type="range"
min={0}
max={1}
step={0.01}
onChange={(e) => {
const value = parseFloat(e.target.value);
setFunkVol(value);
}}
value={funkVolume}
className="range range-xs range-primary w-full"
/>
<div className="flex justify-between px-2.5 mt-2 text-xs">
<span>0%</span>
<span>25%</span>
<span>50%</span>
<span>75%</span>
<span>100%</span>
</div>
</div>
<div className="flex justify-center w-full">
<div className="divider w-1/2" />
</div>
<p className="flex items-center gap-2 text-base mb-2">
<Volume2 size={20} /> Melder Lautstärke
</p>
<div className="w-full">
<input
type="range"
min={0}
max={1}
step={0.01}
onChange={(e) => {
const value = parseFloat(e.target.value);
setDmeVol(value);
if (!testSoundRef.current) return;
testSoundRef.current.volume = value;
testSoundRef.current.play();
}}
value={dmeVolume}
className="range range-xs range-primary w-full"
/>
<div className="flex justify-between px-2.5 mt-2 text-xs">
<span>0%</span>
<span>25%</span>
<span>50%</span>
<span>75%</span>
<span>100%</span>
</div>
</div>
<div className="flex justify-between modal-action">
<button
className="btn btn-soft"
type="submit"
onSubmit={() => false}
onClick={() => {
modalRef.current?.close();
testSoundRef.current?.pause();
}}
>
Schließen
</button>
<button
className="btn btn-soft btn-success"
type="submit"
onSubmit={() => false}
onClick={async () => {
testSoundRef.current?.pause();
await editUserMutation.mutateAsync({
id: session.data!.user.id,
user: {
settingsMicDevice: selectedDevice,
settingsMicVolume: micVol,
settingsRadioVolume: funkVolume,
settingsDmeVolume: dmeVolume,
},
});
setMic(selectedDevice, micVol);
modalRef.current?.close();
toast.success("Einstellungen gespeichert");
}}
>
Speichern
</button>
</div>
</div>
</dialog>
</div>
);
};
export const Settings = () => {
return (
<div>
<SettingsBtn />
</div>
);
};