added mrt, dev

This commit is contained in:
PxlLoewe
2025-05-18 23:21:08 -07:00
parent 6b58f564b2
commit 1b16b365bd
25 changed files with 514 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

@@ -0,0 +1,183 @@
import { CSSProperties } from "react";
import MrtImage from "./MRT.png";
import { useButtons } from "./useButtons";
import { useSounds } from "./useSounds";
import "./mrt.css";
import Image from "next/image";
import { useMrtStore } from "_store/pilot/MrtStore";
const MRT_BUTTON_STYLES: CSSProperties = {
cursor: "pointer",
zIndex: "9999",
backgroundColor: "transparent",
border: "none",
};
const MRT_DISPLAYLINE_STYLES: CSSProperties = {
color: "white",
zIndex: 1,
};
export interface DisplayLineProps {
style?: CSSProperties;
textLeft?: string;
textMid?: string;
textRight?: string;
textSize: "1" | "2" | "3" | "4";
}
const DisplayLine = ({
style = {},
textLeft,
textMid,
textRight,
textSize,
}: DisplayLineProps) => {
const INNER_TEXT_PARTS: CSSProperties = {
fontFamily: "Melder",
flex: "1",
flexBasis: "auto",
overflowWrap: "break-word",
};
return (
<div
className={`text-${textSize}`}
style={{
fontFamily: "Famirids",
display: "flex",
flexWrap: "wrap",
...style,
}}
>
<span style={INNER_TEXT_PARTS}>{textLeft}</span>
<span style={{ textAlign: "center", ...INNER_TEXT_PARTS }}>
{textMid}
</span>
<span style={{ textAlign: "end", ...INNER_TEXT_PARTS }}>{textRight}</span>
</div>
);
};
export const Mrt = () => {
useSounds();
const { handleButton } = useButtons();
const lines = useMrtStore((state) => state.lines);
return (
<div
id="mrt-container"
style={{
containerName: "mrtContainer",
display: "grid",
aspectRatio: "1466 / 760",
height: "auto",
width: "auto",
maxHeight: "100%",
maxWidth: "100%",
overflow: "hidden",
color: "white",
gridTemplateColumns:
"21.83% 4.43% 24.42% 18.08% 5.93% 1.98% 6.00% 1.69% 6.00% 9.35%",
gridTemplateRows:
"21.58% 11.87% 3.55% 5.00% 6.84% 0.53% 3.03% 11.84% 3.55% 11.84% 20.39%",
}}
>
<Image
src={MrtImage}
alt="MrtImage"
style={{
zIndex: 0,
height: "100%",
width: "100%",
gridArea: "1 / 1 / 13 / 13",
}}
/>
<button
onClick={handleButton("1")}
style={{ gridArea: "2 / 5 / 3 / 6", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("2")}
style={{ gridArea: "2 / 7 / 3 / 7", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("3")}
style={{ gridArea: "2 / 9 / 3 / 10", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("4")}
style={{ gridArea: "4 / 5 / 6 / 6", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("5")}
style={{ gridArea: "4 / 7 / 6 / 7", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("6")}
style={{ gridArea: "4 / 9 / 6 / 10", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("7")}
style={{ gridArea: "8 / 5 / 9 / 6", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("8")}
style={{ gridArea: "8 / 7 / 9 / 7", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("9")}
style={{ gridArea: "8 / 9 / 9 / 10", ...MRT_BUTTON_STYLES }}
/>
<button
onClick={handleButton("0")}
style={{ gridArea: "10 / 7 / 11 / 8", ...MRT_BUTTON_STYLES }}
/>
{lines[0] && (
<DisplayLine
{...lines[0]}
style={{
gridArea: "4 / 3 / 5 / 4",
marginLeft: "9px",
marginTop: "auto",
...MRT_DISPLAYLINE_STYLES,
...lines[0]?.style,
}}
/>
)}
{lines[1] && (
<DisplayLine
{...lines[1]}
style={{
gridArea: "5 / 3 / 7 / 4",
marginLeft: "3px",
marginTop: "auto",
...MRT_DISPLAYLINE_STYLES,
...lines[1].style,
}}
/>
)}
{lines[2] && (
<DisplayLine
{...lines[2]}
style={{
gridArea: "8 / 2 / 9 / 4",
...MRT_DISPLAYLINE_STYLES,
...lines[2]?.style,
}}
/>
)}
{lines[3] && (
<DisplayLine
{...lines[3]}
style={{
gridArea: "9 / 2 / 10 / 4",
marginRight: "10px",
...MRT_DISPLAYLINE_STYLES,
...lines[3]?.style,
}}
/>
)}
</div>
);
};

View File

@@ -0,0 +1,32 @@
#mrt-container {
container-name: mrtContainer;
}
@container mrtContainer (inline-size < 600px) {
#mrt-container .text-1 {
font-size: 12px;
color: red;
}
#mrt-container .text-2 {
font-size: 99px;
}
#mrt-container .text-3 {
font-size: 25px;
}
#mrt-container .text-4 {
font-size: 45px;
}
}
#mrt-container .text-1 {
font-size: 10px;
}
#mrt-container .text-2 {
font-size: 12px;
}
#mrt-container .text-3 {
font-size: 15px;
}
#mrt-container .text-4 {
font-size: 25px;
}

View File

@@ -0,0 +1,140 @@
import { useSession } from "next-auth/react";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
import { useMrtStore } from "_store/pilot/MrtStore";
import { editConnectedAircraftAPI } from "querys/aircrafts";
import { Station } from "@repo/db";
import { DisplayLineProps } from "pilot/_components/mrt/Mrt";
export const fmsStatusDescription: { [key: string]: string } = {
NaN: "Keine Daten",
"0": "Prio. Sprechwunsch",
"1": "Frei auf Funk",
"2": "Einsatzbereit am LRZ",
"3": "Auf dem Weg",
"4": "Am Einsatzort",
"5": "Sprechwunsch",
"6": "Nicht einsatzbereit",
"7": "Patient aufgenommen",
"8": "Am Transportziel",
"9": "Fremdanmeldung",
E: "Indent/Abbruch/Einsatzbefehl abgebrochen",
C: "Anmelden zur Übernahme des Einsatzes",
F: "Kommen über Draht",
H: "Fahren auf Wache",
J: "Sprechaufforderung",
L: "Lagebericht abgeben",
P: "Einsatz mit Polizei/Pause machen",
U: "Ungültiger Status",
c: "Status korrigieren",
d: "Transportziel angeben",
h: "Zielklinik verständigt",
o: "Warten, alle Abfrageplätze belegt",
u: "Verstanden",
};
export const getSendingLines = (station: Station): DisplayLineProps[] => {
return [
{
textLeft: `VAR#.${station?.bosCallsign}123`,
style: { fontWeight: "bold" },
textSize: "2",
},
{ textLeft: "ILS VAR#", textSize: "3" },
{
textMid: "sending...",
style: { fontWeight: "bold" },
textSize: "4",
},
{
textLeft: "Status wird gesendet...",
textSize: "1",
},
];
};
export const getHomeLines = (
station: Station,
fmsStatus: string,
): DisplayLineProps[] => {
return [
{
textLeft: `VAR#.${station?.bosCallsign}`,
style: { fontWeight: "bold" },
textSize: "2",
},
{ textLeft: "ILS VAR#", textSize: "3" },
{
textLeft: fmsStatus,
style: { fontWeight: "extrabold" },
textSize: "4",
},
{
textLeft: fmsStatusDescription[fmsStatus],
textSize: "1",
},
];
};
export const getNewStatusLines = (
station: Station,
fmsStatus: string,
): DisplayLineProps[] => {
return [
{
textLeft: `VAR#.${station?.bosCallsign}`,
style: { fontWeight: "bold" },
textSize: "2",
},
{ textLeft: "ILS VAR#", textSize: "3" },
{
textLeft: fmsStatus,
style: { fontWeight: "extrabold" },
textSize: "4",
},
{
textLeft: fmsStatusDescription[fmsStatus],
textSize: "1",
},
];
};
export const useButtons = () => {
const user = useSession().data?.user;
const station = usePilotConnectionStore((state) => state.selectedStation);
const connectedAircraft = usePilotConnectionStore(
(state) => state.connectedAircraft,
);
const { page, setLines } = useMrtStore((state) => state);
const handleButton =
(button: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0") =>
() => {
if (!station) return;
if (!connectedAircraft?.id) return;
if (
button === "1" ||
button === "2" ||
button === "3" ||
button === "4" ||
button === "5" ||
button === "6" ||
button === "7" ||
button === "8" ||
button === "9" ||
button === "0"
) {
if (page !== "home") return;
setLines(getSendingLines(station));
setTimeout(async () => {
await editConnectedAircraftAPI(connectedAircraft!.id, {
fmsStatus: button,
});
setLines(getNewStatusLines(station, button));
}, 1000);
}
};
return { handleButton };
};

View File

@@ -0,0 +1,66 @@
"use client";
import { usePilotConnectionStore } from "_store/pilot/connectionStore";
import { useMrtStore } from "_store/pilot/MrtStore";
import { editConnectedAircraftAPI } from "querys/aircrafts";
import { useEffect, useRef } from "react";
const MRTstatusSound = new Audio("/sounds/MRT-status.mp3");
const MrtMessageReceivedSound = new Audio("/sounds/MRT-message-received.mp3");
export const useSounds = () => {
const mrtState = useMrtStore((state) => state);
const { connectedAircraft, selectedStation } = usePilotConnectionStore(
(state) => state,
);
const fmsStatus = connectedAircraft?.fmsStatus || "NaN";
const previousFmsStatus = useRef(fmsStatus || "6");
const timeout = useRef<NodeJS.Timeout>(null);
useEffect(() => {
const handleSoundEnd = () => {
mrtState.setPage("home");
};
const playSound = (sound: HTMLAudioElement) => {
sound.play();
sound.addEventListener("ended", handleSoundEnd);
};
if (!connectedAircraft) return;
if (mrtState.page === "new-status") {
if (fmsStatus === "J") {
playSound(MrtMessageReceivedSound);
timeout.current = setTimeout(() => {
editConnectedAircraftAPI(connectedAircraft.id, {
fmsStatus: previousFmsStatus.current,
});
}, 5000);
} else if (previousFmsStatus.current !== fmsStatus) {
playSound(MRTstatusSound);
} else {
handleSoundEnd();
}
if (!timeout.current) {
previousFmsStatus.current = fmsStatus || "6";
}
}
return () => {
if (timeout.current) clearTimeout(timeout.current);
[MRTstatusSound, MrtMessageReceivedSound].forEach((sound) => {
sound.removeEventListener("ended", handleSoundEnd);
sound.pause();
sound.currentTime = 0;
});
};
}, [
mrtState,
fmsStatus,
connectedAircraft,
selectedStation,
previousFmsStatus,
timeout,
]);
};