feat: Add support for NPED Category D across components

This commit is contained in:
2025-12-15 13:17:43 +00:00
parent 5dc1d13e25
commit 696a36ba92
10 changed files with 193 additions and 92 deletions

View File

@@ -12,14 +12,10 @@ import HotListImg from "/Hotlist_Hit.svg";
import NPED_CAT_A from "/NPED_Cat_A.svg";
import NPED_CAT_B from "/NPED_Cat_B.svg";
import NPED_CAT_C from "/NPED_Cat_C.svg";
import popup from "../../assets/sounds/ui/popup_open.mp3";
import notification from "../../assets/sounds/ui/notification.mp3";
import { useSound } from "react-sounds";
import NPED_CAT_D from "/NPED_Cat_D.svg";
import { useIntegrationsContext } from "../../context/IntegrationsContext";
import { useSoundContext } from "../../context/SoundContext";
import Loading from "../UI/Loading";
import { checkIsHotListHit, getNPEDCategory } from "../../utils/utils";
import { useCachedSoundSrc } from "../../hooks/usecachedSoundSrc";
function useNow(tickMs = 1000) {
const [, setNow] = useState(() => Date.now());
@@ -41,14 +37,9 @@ type SightingHistoryProps = {
export default function SightingHistoryWidget({ className, title }: SightingHistoryProps) {
const [modalQueue, setModalQueue] = useState<QueuedHit[]>([]);
useNow(1000);
const { state } = useSoundContext();
const { src: soundSrcHotlist } = useCachedSoundSrc(state?.hotlistSound, state?.soundOptions, notification);
const { src: soundSrcNped } = useCachedSoundSrc(state?.NPEDsound, state?.soundOptions, popup);
const { play: npedSound } = useSound(soundSrcNped, { volume: state.NPEDsoundVolume });
const { play: hotlistsound } = useSound(soundSrcHotlist, { volume: state.hotlistSoundVolume });
const {
sightings,
setSelectedSighting,
@@ -73,18 +64,24 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
const isCatCEnabled = integrationState?.iscatEnabled?.catC;
const isCatDEnabled = integrationState?.iscatEnabled?.catD;
const enqueue = useCallback((sighting: SightingType, kind: HitKind) => {
const id = sighting.vrm ?? sighting.ref;
if (processedRefs.current.has(id)) return;
const enqueue = useCallback(
(sighting: SightingType, kind: HitKind) => {
if (!sighting) return;
const inList = alertState?.alertList?.find((sighting) => sighting.vrm === id);
if (inList) {
return;
}
processedRefs.current.add(id);
const id = sighting.vrm ?? sighting.ref;
if (processedRefs.current.has(id)) return;
setModalQueue((q) => [...q, { id, sighting, kind }]);
}, []);
const inList = alertState?.alertList?.find((sighting) => sighting.vrm === id);
if (inList) {
return;
}
processedRefs.current.add(id);
setModalQueue((q) => [...q, { id, sighting, kind }]);
},
[alertState?.alertList]
);
const reduceObject = (obj: SightingType): ReducedSightingType => {
return {
@@ -133,31 +130,16 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
enqueue(sighting, isNPED ? "NPED" : "HOTLIST"); // enqueue ONLY
}
}
}, [rows, enqueue]);
useEffect(() => {
rows?.forEach((obj) => {
const cat = getNPEDCategory(obj);
const isNPEDHitA = cat === "A";
const isNPEDHitB = cat === "B";
const isNPEDHitC = cat === "C";
if (isNPEDHitA || isNPEDHitB || isNPEDHitC) {
dispatch({
type: "ADD",
payload: obj,
});
}
});
}, [dispatch]);
}, [rows, enqueue, isCatAEnabled, isCatBEnabled, isCatCEnabled, isCatDEnabled]);
useEffect(() => {
if (hasAutoOpenedRef.current || npedRef.current) return;
const firstNPED = rows.find((r) => {
const cat = getNPEDCategory(r);
const isNPEDHitA = cat === "A";
const isNPEDHitB = cat === "B";
const isNPEDHitC = cat === "C";
const isNPEDHitD = cat === "D";
const isNPEDHitA = cat === "A" && isCatAEnabled;
const isNPEDHitB = cat === "B" && isCatBEnabled;
const isNPEDHitC = cat === "C" && isCatCEnabled;
const isNPEDHitD = cat === "D" && isCatDEnabled;
return isNPEDHitA || isNPEDHitB || isNPEDHitC || isNPEDHitD;
});
const firstHot = rows?.find((r) => {
@@ -176,20 +158,42 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
hasAutoOpenedRef.current = true;
}
}, [enqueue, hotlistsound, npedSound, rows, setSelectedSighting, setSightingModalOpen]);
}, [
enqueue,
rows,
setSelectedSighting,
setSightingModalOpen,
isCatAEnabled,
isCatBEnabled,
isCatCEnabled,
isCatDEnabled,
]);
useEffect(() => {
if (!isSightingModalOpen && modalQueue.length > 0) {
const next = modalQueue[0];
if (next.kind === "NPED") npedSound();
else hotlistsound();
setSelectedSighting(next.sighting);
setSightingModalOpen(true);
}
}, [isSightingModalOpen, npedSound, hotlistsound, setSelectedSighting, setSightingModalOpen, modalQueue]);
}, [isSightingModalOpen, setSelectedSighting, setSightingModalOpen, modalQueue]);
useEffect(() => {
rows?.forEach((obj) => {
const cat = getNPEDCategory(obj);
const isNPEDHitA = cat === "A";
const isNPEDHitB = cat === "B";
const isNPEDHitC = cat === "C";
const isNPEDHitD = cat === "D";
if (isNPEDHitA || isNPEDHitB || isNPEDHitC || isNPEDHitD) {
console.log("first");
dispatch({
type: "ADD",
payload: obj,
});
}
});
}, [dispatch, rows]);
const handleClose = () => {
setSightingModalOpen(false);
@@ -212,6 +216,7 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
const isNPEDHitA = cat === "A";
const isNPEDHitB = cat === "B";
const isNPEDHitC = cat === "C";
const isNPEDHitD = cat === "D";
const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY";
const isHotListHit = checkIsHotListHit(obj);
return (
@@ -230,6 +235,7 @@ export default function SightingHistoryWidget({ className, title }: SightingHist
{isNPEDHitA && <img src={NPED_CAT_A} alt="hotlistHit" className="h-20 object-contain rounded-md" />}
{isNPEDHitB && <img src={NPED_CAT_B} alt="hotlistHit" className="h-20 object-contain rounded-md" />}
{isNPEDHitC && <img src={NPED_CAT_C} alt="hotlistHit" className="h-20 object-contain rounded-md" />}
{isNPEDHitD && <img src={NPED_CAT_D} alt="hotlistHit" className="h-20 object-contain rounded-md" />}
<NumberPlate motion={motionAway} vrm={obj?.vrm} />
</div>
</div>