Files
var-monorepo/apps/dispatch/app/_components/Audio/useSounds.ts
2025-07-10 00:35:34 -07:00

118 lines
3.7 KiB
TypeScript

"use client";
import { useDebounce } from "@repo/shared-components";
import { useAudioStore } from "_store/audioStore";
import { useEffect, useRef, useState } from "react";
export const useSounds = ({
isReceiving,
isTransmitting,
unpausedTracks,
transmitBlocked,
}: {
isReceiving: boolean;
isTransmitting: boolean;
unpausedTracks: unknown[];
transmitBlocked?: boolean;
}) => {
const { room } = useAudioStore();
// Sounds as refs
const connectionStart = useRef<HTMLAudioElement | null>(null);
const connectionEnd = useRef<HTMLAudioElement | null>(null);
const ownCallStarted = useRef<HTMLAudioElement | null>(null);
const foreignCallStop = useRef<HTMLAudioElement | null>(null);
const foreignCallBlocked = useRef<HTMLAudioElement | null>(null);
const callToLong = useRef<HTMLAudioElement | null>(null);
const adminCall = useRef<HTMLAudioElement | null>(null);
useEffect(() => {
if (!window) return;
connectionStart.current = new Audio("/sounds/connection_started_sepura.mp3");
connectionEnd.current = new Audio("/sounds/connection_stoped_sepura.mp3");
ownCallStarted.current = new Audio("/sounds/call_end_sepura.wav");
foreignCallStop.current = new Audio("/sounds/call_end_sepura.wav");
foreignCallBlocked.current = new Audio("/sounds/call_blocked_sepura.wav");
callToLong.current = new Audio("/sounds/call_to_long.wav");
adminCall.current = new Audio("/sounds/call_interrupted_by_admin.mp3");
}, []);
const [soundConnectionStarted, setSoundsConnectionStarted] = useState(false);
useDebounce(
() => {
if (!isReceiving && !isTransmitting && soundConnectionStarted) {
setSoundsConnectionStarted(false);
connectionEnd.current!.currentTime = 0;
connectionEnd.current!.play();
}
},
3000,
[unpausedTracks, isReceiving, isTransmitting],
);
useEffect(() => {
if ((isReceiving || isTransmitting) && !soundConnectionStarted) {
setSoundsConnectionStarted(true);
connectionStart.current!.currentTime = 0;
connectionStart.current!.play();
ownCallStarted.current!.pause();
}
}, [isReceiving, isTransmitting, soundConnectionStarted]);
useEffect(() => {
if (transmitBlocked && foreignCallBlocked.current) {
foreignCallBlocked.current.volume = 0.2;
foreignCallBlocked.current.currentTime = 0;
foreignCallBlocked.current.loop = true;
foreignCallBlocked.current.play().catch(() => {});
} else if (foreignCallBlocked.current) {
foreignCallBlocked.current.pause();
}
}, [transmitBlocked]);
useEffect(() => {
if (isTransmitting && connectionStart.current!.paused) {
ownCallStarted.current!.volume = 0.2;
ownCallStarted.current!.currentTime = 0;
ownCallStarted.current!.play();
}
}, [isTransmitting]);
useEffect(() => {
if (!isReceiving) {
foreignCallStop.current!.volume = 0.2;
foreignCallStop.current!.currentTime = 0;
foreignCallStop.current!.play().catch(() => {});
}
}, [isReceiving]);
// Hotmic warning after 25 seconds
useEffect(() => {
if (isTransmitting) {
const soundsTimeout = setTimeout(() => {
if (isTransmitting) {
callToLong.current!.loop = true;
callToLong.current!.currentTime = 0;
callToLong.current!.volume = 1;
callToLong.current!.play();
}
}, 25000);
const forceEndTransmitionTimeout = setTimeout(() => {
if (isTransmitting) {
room?.localParticipant.setMicrophoneEnabled(false);
useAudioStore.setState({
isTalking: false,
message: "Hotmic erkannt! Ruf wurde beendet.",
});
}
}, 25000 + 10000);
return () => {
clearTimeout(soundsTimeout);
clearTimeout(forceEndTransmitionTimeout);
callToLong.current!.pause();
};
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isTransmitting]);
};