@@ -8,6 +8,7 @@ import { useAlertHitContext } from "../../context/AlertHitContext";
|
|||||||
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
||||||
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
||||||
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
||||||
|
import { checkIsHotListHit } from "../../utils/utils";
|
||||||
|
|
||||||
type AlertItemProps = {
|
type AlertItemProps = {
|
||||||
item: SightingType;
|
item: SightingType;
|
||||||
@@ -19,9 +20,8 @@ const AlertItem = ({ item }: AlertItemProps) => {
|
|||||||
|
|
||||||
// const {d} = useCameraBlackboard();
|
// const {d} = useCameraBlackboard();
|
||||||
const motionAway = (item?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (item?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
// [34].metadata.hotlistMatches["MAV_Hotlist.csv"]
|
|
||||||
//check if true is in any hotlist property
|
const isHotListHit = checkIsHotListHit(item);
|
||||||
const isHotListHit = item?.metadata?.hotlistMatches?.Hotlist0 === true;
|
|
||||||
const isNPEDHitA = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
const isNPEDHitA = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
const isNPEDHitB = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
const isNPEDHitB = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
const isNPEDHitC = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
const isNPEDHitC = item?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import HotListImg from "/Hotlist_Hit.svg";
|
|||||||
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
import NPED_CAT_A from "/NPED_Cat_A.svg";
|
||||||
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
||||||
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
||||||
|
import { checkIsHotListHit } from "../../utils/utils";
|
||||||
|
|
||||||
type SightingModalProps = {
|
type SightingModalProps = {
|
||||||
isSightingModalOpen: boolean;
|
isSightingModalOpen: boolean;
|
||||||
@@ -65,7 +66,7 @@ const SightingModal = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const motionAway = (sighting?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (sighting?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
const isHotListHit = sighting?.metadata?.hotlistMatches?.Hotlist0 === true;
|
const isHotListHit = checkIsHotListHit(sighting);
|
||||||
const isNPEDHitA = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
const isNPEDHitA = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
const isNPEDHitB = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
const isNPEDHitB = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
const isNPEDHitC = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
const isNPEDHitC = sighting?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ type InfoBarprops = {
|
|||||||
obj: SightingType;
|
obj: SightingType;
|
||||||
};
|
};
|
||||||
const InfoBar = ({ obj }: InfoBarprops) => {
|
const InfoBar = ({ obj }: InfoBarprops) => {
|
||||||
// const isNPEDHit = obj?.metadata?.npedJSON?.status_code === 404;
|
|
||||||
const isNPEDHitD = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
const isNPEDHitD = obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import NPED_CAT_A from "/NPED_Cat_A.svg";
|
|||||||
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
import NPED_CAT_B from "/NPED_Cat_B.svg";
|
||||||
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
import NPED_CAT_C from "/NPED_Cat_C.svg";
|
||||||
import popup from "../../assets/sounds/ui/popup_open.mp3";
|
import popup from "../../assets/sounds/ui/popup_open.mp3";
|
||||||
|
import notification from "../../assets/sounds/ui/notification.mp3";
|
||||||
import { useSound } from "react-sounds";
|
import { useSound } from "react-sounds";
|
||||||
import { useNPEDContext } from "../../context/NPEDUserContext";
|
import { useNPEDContext } from "../../context/NPEDUserContext";
|
||||||
import { useSoundContext } from "../../context/SoundContext";
|
import { useSoundContext } from "../../context/SoundContext";
|
||||||
import Loading from "../UI/Loading";
|
import Loading from "../UI/Loading";
|
||||||
|
import { checkIsHotListHit } from "../../utils/utils";
|
||||||
|
|
||||||
function useNow(tickMs = 1000) {
|
function useNow(tickMs = 1000) {
|
||||||
const [, setNow] = useState(() => Date.now());
|
const [, setNow] = useState(() => Date.now());
|
||||||
@@ -43,11 +45,16 @@ export default function SightingHistoryWidget({
|
|||||||
useNow(1000);
|
useNow(1000);
|
||||||
const { state } = useSoundContext();
|
const { state } = useSoundContext();
|
||||||
|
|
||||||
const soundSrc = useMemo(() => {
|
const soundSrcNped = useMemo(() => {
|
||||||
return getSoundFileURL(state.NPEDsound) ?? popup;
|
return getSoundFileURL(state.NPEDsound) ?? popup;
|
||||||
}, [state.NPEDsound]);
|
}, [state.NPEDsound]);
|
||||||
|
|
||||||
const { play } = useSound(soundSrc);
|
const soundSrcHotlist = useMemo(() => {
|
||||||
|
return getSoundFileURL(state?.hotlists?.[0]?.sound) ?? notification;
|
||||||
|
}, [state.hotlists]);
|
||||||
|
|
||||||
|
const { play: npedSound } = useSound(soundSrcNped);
|
||||||
|
const { play: hotlistsound } = useSound(soundSrcHotlist);
|
||||||
const {
|
const {
|
||||||
sightings,
|
sightings,
|
||||||
setSelectedSighting,
|
setSelectedSighting,
|
||||||
@@ -78,6 +85,7 @@ export default function SightingHistoryWidget({
|
|||||||
}, [mostRecent, sessionStarted, setSessionList]);
|
}, [mostRecent, sessionStarted, setSessionList]);
|
||||||
|
|
||||||
const hasAutoOpenedRef = useRef(false);
|
const hasAutoOpenedRef = useRef(false);
|
||||||
|
const npedRef = useRef(false);
|
||||||
|
|
||||||
const onRowClick = useCallback(
|
const onRowClick = useCallback(
|
||||||
(sighting: SightingType) => {
|
(sighting: SightingType) => {
|
||||||
@@ -106,24 +114,43 @@ export default function SightingHistoryWidget({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [dispatch, rows]);
|
}, [dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hasAutoOpenedRef.current) return;
|
if (hasAutoOpenedRef.current || npedRef.current) return;
|
||||||
const firstHot = rows?.find((r) => {
|
const firstNPED = rows.find((r) => {
|
||||||
const isHotListHit = r?.metadata?.hotlistMatches?.Hotlist0 === true;
|
|
||||||
const isNPEDHitA = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
const isNPEDHitA = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "A";
|
||||||
const isNPEDHitB = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
const isNPEDHitB = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
const isNPEDHitC = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
const isNPEDHitC = r?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
return isNPEDHitA || isNPEDHitB || isNPEDHitC || isHotListHit;
|
return isNPEDHitA || isNPEDHitB || isNPEDHitC;
|
||||||
});
|
});
|
||||||
|
const firstHot = rows?.find((r) => {
|
||||||
|
const isHotListHit = checkIsHotListHit(r);
|
||||||
|
|
||||||
|
return isHotListHit;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (firstNPED) {
|
||||||
|
setSelectedSighting(firstNPED);
|
||||||
|
console.log("first");
|
||||||
|
npedSound();
|
||||||
|
setSightingModalOpen(true);
|
||||||
|
npedRef.current = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (firstHot) {
|
if (firstHot) {
|
||||||
setSelectedSighting(firstHot);
|
setSelectedSighting(firstHot);
|
||||||
play();
|
hotlistsound();
|
||||||
setSightingModalOpen(true);
|
setSightingModalOpen(true);
|
||||||
hasAutoOpenedRef.current = true;
|
hasAutoOpenedRef.current = true;
|
||||||
}
|
}
|
||||||
}, [play, rows, setSelectedSighting, setSightingModalOpen]);
|
}, [
|
||||||
|
hotlistsound,
|
||||||
|
npedSound,
|
||||||
|
rows,
|
||||||
|
setSelectedSighting,
|
||||||
|
setSightingModalOpen,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
setSightingModalOpen(false);
|
setSightingModalOpen(false);
|
||||||
@@ -152,11 +179,8 @@ export default function SightingHistoryWidget({
|
|||||||
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "B";
|
||||||
const isNPEDHitC =
|
const isNPEDHitC =
|
||||||
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "C";
|
||||||
const isNPEDHitD =
|
|
||||||
obj?.metadata?.npedJSON?.["NPED CATEGORY"] === "D";
|
|
||||||
const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY";
|
const motionAway = (obj?.motion ?? "").toUpperCase() === "AWAY";
|
||||||
const isHotListHit =
|
const isHotListHit = checkIsHotListHit(obj);
|
||||||
obj?.metadata?.hotlistMatches?.Hotlist0 === true;
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={obj.ref}
|
key={obj.ref}
|
||||||
@@ -164,9 +188,7 @@ export default function SightingHistoryWidget({
|
|||||||
onClick={() => onRowClick(obj)}
|
onClick={() => onRowClick(obj)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={`flex items-center gap-3 mt-2 justify-between ${
|
className={`flex items-center gap-3 mt-2 justify-between `}
|
||||||
isNPEDHitD ? " border-amber-600" : ""
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className={`border p-1 `}>
|
<div className={`border p-1 `}>
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ type SightingFeedContextType = {
|
|||||||
isError: boolean;
|
isError: boolean;
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
data: SightingType | undefined;
|
data: SightingType | undefined;
|
||||||
sessionList: SightingType[];
|
|
||||||
sessionStarted: boolean;
|
sessionStarted: boolean;
|
||||||
setSessionStarted: (started: boolean) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SightingFeedContext = createContext<
|
export const SightingFeedContext = createContext<
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ export const SightingFeedProvider = ({
|
|||||||
setSelectedSighting,
|
setSelectedSighting,
|
||||||
selectedSighting,
|
selectedSighting,
|
||||||
mostRecent,
|
mostRecent,
|
||||||
sessionList,
|
|
||||||
sessionStarted,
|
sessionStarted,
|
||||||
setSessionStarted,
|
|
||||||
} = useSightingFeed(url);
|
} = useSightingFeed(url);
|
||||||
|
|
||||||
const [isSightingModalOpen, setSightingModalOpen] = useState(false);
|
const [isSightingModalOpen, setSightingModalOpen] = useState(false);
|
||||||
@@ -45,9 +43,7 @@ export const SightingFeedProvider = ({
|
|||||||
isLoading,
|
isLoading,
|
||||||
side,
|
side,
|
||||||
data,
|
data,
|
||||||
sessionList,
|
|
||||||
sessionStarted,
|
sessionStarted,
|
||||||
setSessionStarted,
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { SoundAction, SoundState } from "../../types/types";
|
|||||||
export const initialState: SoundState = {
|
export const initialState: SoundState = {
|
||||||
sightingSound: "switch",
|
sightingSound: "switch",
|
||||||
NPEDsound: "popup",
|
NPEDsound: "popup",
|
||||||
hotlists: [],
|
hotlists: [{ name: "hotlistName", sound: "notification" }],
|
||||||
soundOptions: [
|
soundOptions: [
|
||||||
{ name: "switch (Default)", soundFile: null },
|
{ name: "switch (Default)", soundFile: null },
|
||||||
{ name: "popup", soundFile: null },
|
{ name: "popup", soundFile: null },
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import switchSound from "../assets/sounds/ui/switch.mp3";
|
import switchSound from "../assets/sounds/ui/switch.mp3";
|
||||||
import popup from "../assets/sounds/ui/popup_open.mp3";
|
import popup from "../assets/sounds/ui/popup_open.mp3";
|
||||||
import notification from "../assets/sounds/ui/notification.mp3";
|
import notification from "../assets/sounds/ui/notification.mp3";
|
||||||
|
import type { SightingType } from "../types/types";
|
||||||
|
|
||||||
export function getSoundFileURL(name: string) {
|
export function getSoundFileURL(name: string) {
|
||||||
const sounds: Record<string, string> = {
|
const sounds: Record<string, string> = {
|
||||||
@@ -129,59 +130,12 @@ export function drawRects(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// setSelectedRef(data?.ref);
|
export const checkIsHotListHit = (sigthing: SightingType | null) => {
|
||||||
|
if (!sigthing) return;
|
||||||
//setItems(data);
|
if (sigthing?.metadata?.hotlistMatches) {
|
||||||
|
const isHotListHit = Object.values(
|
||||||
// const selected = useMemo(
|
sigthing?.metadata?.hotlistMatches
|
||||||
// () =>
|
).includes(true);
|
||||||
// selectedRef == null
|
return isHotListHit;
|
||||||
// ? null
|
}
|
||||||
// : items.find((x) => x?.ref === selectedRef) ?? null,
|
};
|
||||||
// [items, selectedRef]
|
|
||||||
// );
|
|
||||||
// const effectiveSelected = selected ?? mostRecent ?? null;
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// let delay = pollMs;
|
|
||||||
// let dead = false;
|
|
||||||
// const controller = new AbortController();
|
|
||||||
|
|
||||||
// async function tick() {
|
|
||||||
// try {
|
|
||||||
// // Pause when tab hidden to save CPU/network
|
|
||||||
// if (document.hidden) {
|
|
||||||
// setTimeout(tick, Math.max(delay, 2000));
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (obj && typeof obj.ref === "number" && obj.ref > -1) {
|
|
||||||
// setItems((prev) => {
|
|
||||||
// const next = [obj, ...prev].slice(0, limit);
|
|
||||||
// // maintain selection if still present; otherwise select newest if allowed
|
|
||||||
// const stillExists =
|
|
||||||
// selectedRef != null && next.some((x) => x?.ref === selectedRef);
|
|
||||||
// if (autoSelectLatest && !stillExists) {
|
|
||||||
// setSelectedRef(obj.ref);
|
|
||||||
// }
|
|
||||||
// return next;
|
|
||||||
// });
|
|
||||||
// setMostRecent(obj);
|
|
||||||
// mostRecentRef.current = obj.ref;
|
|
||||||
// delay = pollMs; // reset backoff on success
|
|
||||||
// }
|
|
||||||
// } catch {
|
|
||||||
// // exponential backoff (max 10s)
|
|
||||||
// delay = Math.min(delay * 2, 10000);
|
|
||||||
// } finally {
|
|
||||||
// if (!dead) setTimeout(tick, delay);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const t = setTimeout(tick, pollMs);
|
|
||||||
// return () => {
|
|
||||||
// dead = true;
|
|
||||||
// controller.abort();
|
|
||||||
// clearTimeout(t);
|
|
||||||
// };
|
|
||||||
// }, [baseUrl, limit, pollMs, autoSelectLatest, selectedRef]);
|
|
||||||
|
|||||||
Reference in New Issue
Block a user