import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { SightingType } from "../../types/types"; import { BLANK_IMG, getSoundFileName } from "../../utils/utils"; import NumberPlate from "../PlateStack/NumberPlate"; import Card from "../UI/Card"; import CardHeader from "../UI/CardHeader"; import clsx from "clsx"; import { useSightingFeedContext } from "../../context/SightingFeedContext"; import SightingModal from "../SightingModal/SightingModal"; import { useAlertHitContext } from "../../context/AlertHitContext"; 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 { useSound } from "react-sounds"; import { useNPEDContext } from "../../context/NPEDUserContext"; import { useSoundContext } from "../../context/SoundContext"; function useNow(tickMs = 1000) { const [, setNow] = useState(() => Date.now()); useEffect(() => { const id = setInterval(() => setNow(Date.now()), tickMs); return () => clearInterval(id); }, [tickMs]); return null; } type SightingHistoryProps = { baseUrl?: string; entries?: number; pollMs?: number; autoSelectLatest?: boolean; title: string; className?: string; }; export default function SightingHistoryWidget({ className, title, }: SightingHistoryProps) { useNow(1000); const { state } = useSoundContext(); const soundSrc = useMemo(() => { return getSoundFileName(state.sightingSound) ?? popup; }, [state.sightingSound]); const { play } = useSound(soundSrc); const { sightings, setSelectedSighting, setSightingModalOpen, isSightingModalOpen, selectedSighting, mostRecent, } = useSightingFeedContext(); const { dispatch } = useAlertHitContext(); const { sessionStarted, setSessionList, sessionList } = useNPEDContext(); useEffect(() => { if (sessionStarted) { if (!mostRecent) return; setSessionList([...sessionList, mostRecent]); } }, [mostRecent, sessionStarted, setSessionList]); const hasAutoOpenedRef = useRef(false); const onRowClick = useCallback( (sighting: SightingType) => { if (!sighting) return; setSightingModalOpen(true); setSelectedSighting(sighting); }, [setSelectedSighting, setSightingModalOpen] ); const rows = useMemo( () => sightings?.filter(Boolean) as SightingType[], [sightings] ); useEffect(() => { rows?.forEach((obj) => { const isNPEDHitA = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "A"; const isNPEDHitB = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B"; const isNPEDHitC = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C"; if (isNPEDHitA || isNPEDHitB || isNPEDHitC) { dispatch({ type: "ADD", payload: obj, }); } }); }, [dispatch, rows]); useEffect(() => { if (hasAutoOpenedRef.current) return; const firstHot = rows?.find((r) => { const isHotListHit = r?.metadata?.hotlistMatches?.Hotlist0 === true; const isNPEDHitA = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "A"; const isNPEDHitB = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "B"; const isNPEDHitC = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "C"; return isNPEDHitA || isNPEDHitB || isNPEDHitC || isHotListHit; }); if (firstHot) { setSelectedSighting(firstHot); play(); setSightingModalOpen(true); hasAutoOpenedRef.current = true; } }, [play, rows, setSelectedSighting, setSightingModalOpen]); const handleClose = () => { setSightingModalOpen(false); }; return ( <>
{/* Rows */}
{rows?.map((obj) => { const isNPEDHitA = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "A"; const isNPEDHitB = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B"; const isNPEDHitC = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C"; const isNPEDHitD = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D"; const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY"; const isHotListHit = obj?.metadata?.hotlistMatches?.Hotlist0 === true; return (
onRowClick(obj)} >
colour patch
{isHotListHit && ( hotlistHit )} {isNPEDHitA && ( hotlistHit )} {isNPEDHitB && ( hotlistHit )} {isNPEDHitC && ( hotlistHit )}
); })}
); }