Revert "PR v2.0.7"

This commit is contained in:
PxlLoewe
2026-01-15 23:35:14 +01:00
committed by GitHub
parent 614b92325e
commit 7175f6571e
63 changed files with 1012 additions and 1752 deletions

View File

@@ -24,7 +24,6 @@ import { useSounds } from "_components/Audio/useSounds";
export const Audio = () => {
const {
selectedRoom,
speakingParticipants,
resetSpeakingParticipants,
isTalking,
@@ -38,8 +37,8 @@ export const Audio = () => {
room,
message,
removeMessage,
setSelectedRoom,
} = useAudioStore();
const [selectedRoom, setSelectedRoom] = useState<string>("LST_01");
useSounds({
isReceiving: speakingParticipants.length > 0,
@@ -49,7 +48,7 @@ export const Audio = () => {
});
const { selectedStation, status: pilotState } = usePilotConnectionStore((state) => state);
const { status: dispatcherState } = useDispatchConnectionStore((state) => state);
const { selectedZone, status: dispatcherState } = useDispatchConnectionStore((state) => state);
const session = useSession();
const [isReceivingBlick, setIsReceivingBlick] = useState(false);
const [recentSpeakers, setRecentSpeakers] = useState<typeof speakingParticipants>([]);
@@ -94,7 +93,7 @@ export const Audio = () => {
const canStopOtherSpeakers = dispatcherState === "connected";
const role =
(dispatcherState === "connected" && "VAR LST") ||
(dispatcherState === "connected" && selectedZone) ||
(pilotState == "connected" && selectedStation?.bosCallsignShort) ||
session.data?.user?.publicId;
@@ -186,20 +185,20 @@ export const Audio = () => {
</summary>
<ul className="menu dropdown-content bg-base-200 rounded-box z-[1050] w-52 p-2 shadow-sm">
{ROOMS.map((r) => (
<li key={r.id}>
<li key={r}>
<button
className="btn btn-sm btn-ghost relative flex items-center justify-start gap-2 text-left"
onClick={() => {
if (!role) return;
if (selectedRoom?.name === r.name) return;
if (selectedRoom === r) return;
setSelectedRoom(r);
connect(r, role);
}}
>
{room?.name === r.name && (
{room?.name === r && (
<Disc className="text-success absolute left-2 text-sm" width={15} />
)}
<span className="flex-1 text-center">{r.name}</span>
<span className="flex-1 text-center">{r}</span>
</button>
</li>
))}

View File

@@ -63,15 +63,14 @@ export function QueryProvider({ children }: { children: ReactNode }) {
};
const handleNotification = (notification: NotificationPayload) => {
console.log("Received notification:", notification);
const playNotificationSound = () => {
if (notificationSound.current) {
notificationSound.current.currentTime = 0;
notificationSound.current
.play()
.catch((e) => console.error("Notification sound error:", e));
}
};
notificationSound.current.currentTime = 0;
notificationSound.current
.play()
.catch((e) => console.error("Notification sound error:", e));
}
}
switch (notification.type) {
case "hpg-validation":
@@ -91,7 +90,6 @@ export function QueryProvider({ children }: { children: ReactNode }) {
});
break;
case "station-status":
console.log("station Status", QUICK_RESPONSE[notification.status]);
if (!QUICK_RESPONSE[notification.status]) return;
toast.custom((e) => <StatusToast event={notification} t={e} />, {
duration: 60000,
@@ -108,7 +106,7 @@ export function QueryProvider({ children }: { children: ReactNode }) {
break;
case "mission-closed":
toast("Dein aktueller Einsatz wurde geschlossen.");
break;
default:
toast("unbekanntes Notification-Event");

View File

@@ -1,16 +1,14 @@
import { getPublicUser, MissionSdsStatusLog, StationStatus } from "@repo/db";
import { Prisma, StationStatus } from "@repo/db";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { BaseNotification } from "_components/customToasts/BaseNotification";
import { FMS_STATUS_COLORS } from "_helpers/fmsStatusColors";
import { getConnectedAircraftsAPI } from "_querys/aircrafts";
import { editConnectedAircraftAPI, getConnectedAircraftsAPI } from "_querys/aircrafts";
import { getLivekitRooms } from "_querys/livekit";
import { sendSdsStatusMessageAPI } from "_querys/missions";
import { getStationsAPI } from "_querys/stations";
import { useAudioStore } from "_store/audioStore";
import { useMapStore } from "_store/mapStore";
import { X } from "lucide-react";
import { useSession } from "next-auth/react";
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { Toast, toast } from "react-hot-toast";
export const QUICK_RESPONSE: Record<string, string[]> = {
@@ -24,8 +22,6 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
const status5Sounds = useRef<HTMLAudioElement | null>(null);
const status9Sounds = useRef<HTMLAudioElement | null>(null);
const session = useSession();
const { data: livekitRooms } = useQuery({
queryKey: ["livekit-rooms"],
queryFn: () => getLivekitRooms(),
@@ -50,7 +46,7 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
status9Sounds.current = new Audio("/sounds/status-9.mp3");
}
}, []);
const [aircraftDataAcurate, setAircraftDataAccurate] = useState(false);
//const mapStore = useMapStore((s) => s);
const { setOpenAircraftMarker, setMap } = useMapStore((store) => store);
@@ -69,16 +65,29 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
const station = stations?.find((s) => s.id === event.data?.stationId);
const queryClient = useQueryClient();
const sendSdsStatusMutation = useMutation({
mutationFn: async ({ sdsMessage }: { sdsMessage: MissionSdsStatusLog }) => {
if (!connectedAircraft?.id) throw new Error("No connected aircraft");
await sendSdsStatusMessageAPI({ sdsMessage, aircraftId: connectedAircraft?.id });
const changeAircraftMutation = useMutation({
mutationFn: async ({
id,
update,
}: {
id: number;
update: Prisma.ConnectedAircraftUpdateInput;
}) => {
await editConnectedAircraftAPI(id, update);
queryClient.invalidateQueries({
queryKey: ["missions"],
queryKey: ["aircrafts"],
});
},
});
useEffect(() => {
if (event.status !== connectedAircraft?.fmsStatus && aircraftDataAcurate) {
toast.remove(t.id);
} else if (event.status == connectedAircraft?.fmsStatus && !aircraftDataAcurate) {
setAircraftDataAccurate(true);
}
}, [aircraftDataAcurate, connectedAircraft, event.status, t.id]);
useEffect(() => {
let soundRef: React.RefObject<HTMLAudioElement | null> | null = null;
switch (event.status) {
@@ -94,8 +103,7 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
default:
soundRef = null;
}
if (audioRoom && livekitUser?.roomName && audioRoom !== livekitUser?.roomName) {
if (audioRoom !== livekitUser?.roomName) {
toast.remove(t.id);
return;
}
@@ -113,8 +121,7 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
};
}, [event.status, livekitUser?.roomName, audioRoom, t.id]);
console.log(connectedAircraft, station);
if (!connectedAircraft || !station || !session.data) return null;
if (!connectedAircraft || !station) return null;
return (
<BaseNotification>
<div className="flex flex-row items-center gap-14">
@@ -155,18 +162,10 @@ export const StatusToast = ({ event, t }: { event: StationStatus; t: Toast }) =>
toast.error("Keine Flugzeug-ID gefunden");
return;
}
await sendSdsStatusMutation.mutateAsync({
sdsMessage: {
type: "sds-status-log",
auto: false,
data: {
direction: "to-aircraft",
stationId: event.data.stationId!,
station: station,
user: getPublicUser(session.data?.user),
status,
},
timeStamp: new Date().toISOString(),
await changeAircraftMutation.mutateAsync({
id: event.data?.aircraftId,
update: {
fmsStatus: status,
},
});
toast.remove(t.id);

View File

@@ -2,7 +2,7 @@ import { Marker, Polyline, useMap } from "react-leaflet";
import { DivIcon, Marker as LMarker, Popup as LPopup } from "leaflet";
import { useMapStore } from "_store/mapStore";
import { Fragment, useCallback, useEffect, useRef, useState, useMemo } from "react";
import { cn } from "@repo/shared-components";
import { checkSimulatorConnected, cn } from "@repo/shared-components";
import { ChevronsRightLeft, House, MessageSquareText, Minimize2 } from "lucide-react";
import { SmartPopup, calculateAnchor, useSmartPopup } from "_components/SmartPopup";
import FMSStatusHistory, {
@@ -396,11 +396,27 @@ const AircraftMarker = ({ aircraft }: { aircraft: ConnectedAircraft & { Station:
};
export const AircraftLayer = () => {
const { data: aircrafts } = useQuery({
queryKey: ["connected-aircrafts", "map"],
queryFn: () => getConnectedAircraftsAPI(),
refetchInterval: 15000,
});
const [aircrafts, setAircrafts] = useState<(ConnectedAircraft & { Station: Station })[]>([]);
useEffect(() => {
const fetchAircrafts = async () => {
try {
const res = await fetch("/api/aircrafts");
if (!res.ok) {
throw new Error("Failed to fetch aircrafts");
}
const data: (ConnectedAircraft & { Station: Station })[] = await res.json();
setAircrafts(data.filter((a) => checkSimulatorConnected(a)));
} catch (error) {
console.error("Failed to fetch aircrafts:", error);
}
};
fetchAircrafts();
const interval = setInterval(fetchAircrafts, 10_000);
return () => clearInterval(interval);
}, []);
const { setMap } = useMapStore((state) => state);
const map = useMap();
const {

View File

@@ -9,7 +9,6 @@ import {
Mission,
MissionLog,
MissionSdsLog,
MissionSdsStatusLog,
MissionStationLog,
Prisma,
PublicUser,
@@ -41,7 +40,7 @@ import {
TextSearch,
} from "lucide-react";
import { useSession } from "next-auth/react";
import { sendSdsMessageAPI, sendSdsStatusMessageAPI } from "_querys/missions";
import { sendSdsMessageAPI } from "_querys/missions";
import { getLivekitRooms } from "_querys/livekit";
import { findLeitstelleForPosition } from "_helpers/findLeitstelleinPoint";
import { formatDistance } from "date-fns";
@@ -55,13 +54,9 @@ const FMSStatusHistory = ({
mission?: Mission;
}) => {
const log = ((mission?.missionLog as unknown as MissionLog[]) || [])
.filter(
(entry) =>
(entry.type === "station-log" || entry.type == "sds-status-log") &&
entry.data.stationId === aircraft.Station.id,
)
.filter((entry) => entry.type === "station-log" && entry.data.stationId === aircraft.Station.id)
.reverse()
.splice(0, 6) as (MissionStationLog | MissionSdsStatusLog)[];
.splice(0, 6) as MissionStationLog[];
const aircraftUser: PublicUser =
typeof aircraft.publicUser === "string" ? JSON.parse(aircraft.publicUser) : aircraft.publicUser;
@@ -108,13 +103,10 @@ const FMSStatusHistory = ({
<span
className="text-base font-bold"
style={{
color:
FMS_STATUS_TEXT_COLORS[
entry.type === "sds-status-log" ? entry.data.status : entry.data.newFMSstatus
],
color: FMS_STATUS_TEXT_COLORS[entry.data.newFMSstatus],
}}
>
{entry.type === "sds-status-log" ? entry.data.status : entry.data.newFMSstatus}
{entry.data.newFMSstatus}
</span>
<span className="text-base-content">
{new Date(entry.timeStamp).toLocaleTimeString([], {
@@ -134,7 +126,6 @@ const FMSStatusSelector = ({
}: {
aircraft: ConnectedAircraft & { Station: Station };
}) => {
const session = useSession();
const dispatcherConnected = useDispatchConnectionStore((s) => s.status) === "connected";
const [hoveredStatus, setHoveredStatus] = useState<string | null>(null);
const queryClient = useQueryClient();
@@ -153,20 +144,6 @@ const FMSStatusSelector = ({
},
});
const sendSdsStatusMutation = useMutation({
mutationFn: async ({ sdsMessage }: { sdsMessage: MissionSdsStatusLog }) => {
if (!aircraft?.id) throw new Error("No connected aircraft");
await sendSdsStatusMessageAPI({ sdsMessage, aircraftId: aircraft?.id });
queryClient.invalidateQueries({
queryKey: ["missions"],
});
},
});
if (!session.data?.user) {
return null;
}
return (
<div className="text-base-content mt-2 flex flex-col gap-2 p-4">
<div className="flex h-full items-center justify-center gap-2">
@@ -236,21 +213,12 @@ const FMSStatusSelector = ({
onMouseEnter={() => setHoveredStatus(status)}
onMouseLeave={() => setHoveredStatus(null)}
onClick={async () => {
await sendSdsStatusMutation.mutateAsync({
sdsMessage: {
type: "sds-status-log",
auto: false,
timeStamp: new Date().toISOString(),
data: {
status: status,
direction: "to-aircraft",
stationId: aircraft.Station.id,
station: aircraft.Station,
user: getPublicUser(session.data?.user),
},
await changeAircraftMutation.mutateAsync({
id: aircraft.id,
update: {
fmsStatus: status,
},
});
toast.success(`SDS Status ${status} gesendet`);
}}
>
{status}
@@ -410,9 +378,7 @@ const SDSTab = ({
?.slice()
.reverse()
.filter(
(entry) =>
(entry.type === "sds-log" || entry.type == "sds-status-log") &&
entry.data.stationId === aircraft.Station.id,
(entry) => entry.type === "sds-log" && entry.data.stationId === aircraft.Station.id,
) || [],
[mission?.missionLog, aircraft.Station.id],
);
@@ -505,7 +471,7 @@ const SDSTab = ({
)}
<ul className="max-h-[300px] space-y-2 overflow-x-auto overflow-y-auto">
{log.map((entry, index) => {
const sdsEntry = entry as MissionSdsLog | MissionSdsStatusLog;
const sdsEntry = entry as MissionSdsLog;
return (
<li key={index} className="flex items-center gap-2">
<span className="text-base-content">
@@ -523,9 +489,7 @@ const SDSTab = ({
{sdsEntry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
{sdsEntry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
</span>
<span className="text-base-content">
{sdsEntry.type == "sds-log" ? sdsEntry.data.message : sdsEntry.data.status}
</span>
<span className="text-base-content">{sdsEntry.data.message}</span>
</li>
);
})}

View File

@@ -726,11 +726,7 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
<span className="text-base-content">{entry.data.station.bosCallsign}</span>
</li>
);
if (
entry.type === "message-log" ||
entry.type === "sds-log" ||
entry.type === "sds-status-log"
)
if (entry.type === "message-log" || entry.type === "sds-log")
return (
<li key={index} className="flex items-center gap-2">
<span className="text-base-content">
@@ -745,10 +741,9 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
color: FMS_STATUS_TEXT_COLORS[6],
}}
>
{entry.type == "sds-status-log" && entry.data.direction == "to-lst"
? entry.data.station.bosCallsignShort
: `${entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}${entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}`}
{(entry.type === "sds-log" || entry.type === "sds-status-log") && (
{entry.data.user.firstname?.[0]?.toUpperCase() ?? "?"}
{entry.data.user.lastname?.[0]?.toUpperCase() ?? "?"}
{entry.type === "sds-log" && (
<>
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -765,17 +760,11 @@ const FMSStatusHistory = ({ mission }: { mission: Mission }) => {
/>
</svg>
{entry.type == "sds-status-log" && entry.data.direction == "to-aircraft"
? entry.data.station.bosCallsignShort
: "LST"}
{entry.data.station.bosCallsignShort}
</>
)}
</span>
<span className="text-base-content">
{entry.type === "sds-log" || entry.type === "message-log"
? entry.data.message
: entry.data.status}
</span>
<span className="text-base-content">{entry.data.message}</span>
</li>
);
if (