From 80b407943f4dc97a2255fef4ab7780e6ad0706e9 Mon Sep 17 00:00:00 2001 From: Toba Ojo Date: Thu, 25 Sep 2025 10:38:49 +0100 Subject: [PATCH] refactor: NPED Context, sound update and start session --- src/assets/sounds/ui/computer-mouse-click.mp3 | Bin 33792 -> 0 bytes src/assets/sounds/ui/keystroke_hard.mp3 | Bin 8822 -> 0 bytes src/assets/sounds/ui/switch.mp3 | Bin 0 -> 8640 bytes src/components/HistoryList/AlertItem.tsx | 1 + src/components/SessionForm/SessionCard.tsx | 17 ++++++------ .../SettingForms/NPED/NPEDHotlist.tsx | 3 +- .../SightingsWidget/SightingWidget.tsx | 13 ++++++++- src/components/UI/Header.tsx | 5 ++++ src/components/UI/NavigationArrow.tsx | 4 +-- src/context/NPEDUserContext.ts | 6 +++- src/context/SightingFeedContext.ts | 5 +++- .../providers/NPEDUserContextProvider.tsx | 15 ++++++++-- .../providers/SightingFeedProvider.tsx | 12 ++++++-- src/hooks/useOverviewVideo.ts | 5 ++-- src/hooks/useSightingFeed.ts | 26 ++++++++++++++---- src/main.tsx | 2 +- src/pages/Dashboard.tsx | 1 + src/pages/Session.tsx | 15 ++++++---- src/utils/config.ts | 3 +- vite.config.ts | 2 +- 20 files changed, 96 insertions(+), 39 deletions(-) delete mode 100644 src/assets/sounds/ui/computer-mouse-click.mp3 delete mode 100644 src/assets/sounds/ui/keystroke_hard.mp3 create mode 100644 src/assets/sounds/ui/switch.mp3 diff --git a/src/assets/sounds/ui/computer-mouse-click.mp3 b/src/assets/sounds/ui/computer-mouse-click.mp3 deleted file mode 100644 index bb8e2373b69535f4baf0fae5491b4ed208ad6200..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33792 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 { const [isModalOpen, setIsModalOpen] = useState(false); const { dispatch } = useAlertHitContext(); + // const {d} = useCameraBlackboard(); const motionAway = (item?.motion ?? "").toUpperCase() === "AWAY"; const isHotListHit = item?.metadata?.hotlistMatches?.Hotlist0 === true; diff --git a/src/components/SessionForm/SessionCard.tsx b/src/components/SessionForm/SessionCard.tsx index e898e65..300b41b 100644 --- a/src/components/SessionForm/SessionCard.tsx +++ b/src/components/SessionForm/SessionCard.tsx @@ -1,12 +1,13 @@ -import { useSound } from "react-sounds"; import Card from "../UI/Card"; import CardHeader from "../UI/CardHeader"; +import { useNPEDContext } from "../../context/NPEDUserContext"; const SessionCard = () => { - const { play } = useSound("notification/notification"); - // function onStart(): void { - // throw new Error("Function not implemented."); - // } + const { sessionStarted, setSessionStarted, sessionList } = useNPEDContext(); + + const handleStartClick = () => { + setSessionStarted(!sessionStarted); + }; return ( @@ -14,15 +15,13 @@ const SessionCard = () => {
    -
  • Number of Vehicles:
  • +
  • Number of Vehicles: {sessionList.length}
  • Vehicles without Tax:
  • Vehicles without MOT:
  • Vehicles with NPED Cat A:
  • diff --git a/src/components/SettingForms/NPED/NPEDHotlist.tsx b/src/components/SettingForms/NPED/NPEDHotlist.tsx index 24b92d9..a654b7c 100644 --- a/src/components/SettingForms/NPED/NPEDHotlist.tsx +++ b/src/components/SettingForms/NPED/NPEDHotlist.tsx @@ -1,6 +1,7 @@ import { Form, Formik } from "formik"; import type { HotlistUploadType } from "../../../types/types"; import { useSystemConfig } from "../../../hooks/useSystemConfig"; +import { CAM_BASE } from "../../../utils/config"; const NPEDHotlist = () => { const { uploadSettings } = useSystemConfig(); @@ -14,7 +15,7 @@ const NPEDHotlist = () => { opts: { timeoutMs: 30000, fieldName: "upload", - uploadUrl: "http://192.168.0.90:8080/upload/hotlist-upload/2", + uploadUrl: `${CAM_BASE}/upload/hotlist-upload/2`, }, }; diff --git a/src/components/SightingsWidget/SightingWidget.tsx b/src/components/SightingsWidget/SightingWidget.tsx index df1c816..2ea925f 100644 --- a/src/components/SightingsWidget/SightingWidget.tsx +++ b/src/components/SightingsWidget/SightingWidget.tsx @@ -15,6 +15,7 @@ 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"; function useNow(tickMs = 1000) { const [, setNow] = useState(() => Date.now()); @@ -46,9 +47,18 @@ export default function SightingHistoryWidget({ 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); @@ -84,10 +94,11 @@ export default function SightingHistoryWidget({ 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; + return isNPEDHitA || isNPEDHitB || isNPEDHitC || isHotListHit; }); if (firstHot) { setSelectedSighting(firstHot); diff --git a/src/components/UI/Header.tsx b/src/components/UI/Header.tsx index e038343..1e0866a 100644 --- a/src/components/UI/Header.tsx +++ b/src/components/UI/Header.tsx @@ -11,6 +11,7 @@ import { import type { VersionFieldType } from "../../types/types"; import { useEffect, useState } from "react"; import SoundBtn from "./SoundBtn"; +import { useNPEDContext } from "../../context/NPEDUserContext"; async function fetchVersions( signal?: AbortSignal @@ -43,6 +44,7 @@ export default function Header() { const [offsetMs, setOffsetMs] = useState(null); const [nowMs, setNowMs] = useState(Date.now()); const [isFullscreen, setIsFullscreen] = useState(false); + const { sessionStarted } = useNPEDContext(); const toggleFullscreen = () => { if (!document.fullscreenElement) { @@ -98,6 +100,9 @@ export default function Header() {
+ {sessionStarted && ( +
Session Active
+ )}

Local: {localStr}

UTC: {utcStr}

diff --git a/src/components/UI/NavigationArrow.tsx b/src/components/UI/NavigationArrow.tsx index dd3612f..65c14d7 100644 --- a/src/components/UI/NavigationArrow.tsx +++ b/src/components/UI/NavigationArrow.tsx @@ -3,14 +3,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { useNavigate } from "react-router"; type NavigationArrowProps = { - side: string; + side: string | undefined; settingsPage?: boolean; }; const NavigationArrow = ({ side, settingsPage }: NavigationArrowProps) => { const navigate = useNavigate(); - const navigationDest = (side: string) => { + const navigationDest = (side: string | undefined) => { if (settingsPage) { navigate("/"); return; diff --git a/src/context/NPEDUserContext.ts b/src/context/NPEDUserContext.ts index 1acce93..749fd7d 100644 --- a/src/context/NPEDUserContext.ts +++ b/src/context/NPEDUserContext.ts @@ -1,9 +1,13 @@ import { createContext, useContext, type SetStateAction } from "react"; -import type { NPEDUser } from "../types/types"; +import type { NPEDUser, SightingType } from "../types/types"; type UserContextValue = { user: NPEDUser | null; setUser: React.Dispatch>; + sessionStarted: boolean; + setSessionStarted: React.Dispatch>; + sessionList: SightingType[]; + setSessionList: React.Dispatch>; }; export const NPEDUserContext = createContext( diff --git a/src/context/SightingFeedContext.ts b/src/context/SightingFeedContext.ts index 493fde6..dbcbdb3 100644 --- a/src/context/SightingFeedContext.ts +++ b/src/context/SightingFeedContext.ts @@ -7,7 +7,7 @@ type SightingFeedContextType = { setSelectedRef: (ref: number | null) => void; // effectiveSelected: SightingType | null; mostRecent: SightingType | null; - side: string; + side: string | undefined; selectedSighting: SightingType | null; setSelectedSighting: (sighting: SightingType | SightingType | null) => void; setSightingModalOpen: (isSightingModalOpen: boolean) => void; @@ -15,6 +15,9 @@ type SightingFeedContextType = { isError: boolean; isLoading: boolean; data: SightingType | undefined; + sessionList: SightingType[]; + sessionStarted: boolean; + setSessionStarted: (started: boolean) => void; }; export const SightingFeedContext = createContext< diff --git a/src/context/providers/NPEDUserContextProvider.tsx b/src/context/providers/NPEDUserContextProvider.tsx index b634c57..2a15b3a 100644 --- a/src/context/providers/NPEDUserContextProvider.tsx +++ b/src/context/providers/NPEDUserContextProvider.tsx @@ -1,5 +1,5 @@ import { useState, type ReactNode } from "react"; -import type { NPEDUser } from "../../types/types"; +import type { NPEDUser, SightingType } from "../../types/types"; import { NPEDUserContext } from "../NPEDUserContext"; type NPEDUserProviderType = { @@ -8,9 +8,20 @@ type NPEDUserProviderType = { export const NPEDUserProvider = ({ children }: NPEDUserProviderType) => { const [user, setUser] = useState(null); + const [sessionStarted, setSessionStarted] = useState(false); + const [sessionList, setSessionList] = useState([]); return ( - + {children} ); diff --git a/src/context/providers/SightingFeedProvider.tsx b/src/context/providers/SightingFeedProvider.tsx index c903ede..6b6b8aa 100644 --- a/src/context/providers/SightingFeedProvider.tsx +++ b/src/context/providers/SightingFeedProvider.tsx @@ -3,9 +3,9 @@ import { useSightingFeed } from "../../hooks/useSightingFeed"; import { SightingFeedContext } from "../SightingFeedContext"; type SightingFeedProviderProps = { - url: string; + url?: string | undefined; children: ReactNode; - side: string; + side?: string | undefined; }; export const SightingFeedProvider = ({ @@ -23,7 +23,10 @@ export const SightingFeedProvider = ({ setSelectedSighting, selectedSighting, mostRecent, - } = useSightingFeed(url, side); + sessionList, + sessionStarted, + setSessionStarted, + } = useSightingFeed(url); const [isSightingModalOpen, setSightingModalOpen] = useState(false); @@ -42,6 +45,9 @@ export const SightingFeedProvider = ({ isLoading, side, data, + sessionList, + sessionStarted, + setSessionStarted, }} > {children} diff --git a/src/hooks/useOverviewVideo.ts b/src/hooks/useOverviewVideo.ts index e93a904..df56363 100644 --- a/src/hooks/useOverviewVideo.ts +++ b/src/hooks/useOverviewVideo.ts @@ -1,10 +1,9 @@ import { useQuery } from "@tanstack/react-query"; import { useRef } from "react"; - -const apiUrl = import.meta.env.VITE_BASEURL; +import { CAM_BASE } from "../utils/config"; async function fetchOverviewImage(cameraSide: string) { - const response = await fetch(`${apiUrl}${cameraSide}-preview`); + const response = await fetch(`${CAM_BASE}/${cameraSide}-preview`); if (!response.ok) throw new Error("could not fetch overview image"); return response.blob(); } diff --git a/src/hooks/useSightingFeed.ts b/src/hooks/useSightingFeed.ts index 6ca2715..e880f07 100644 --- a/src/hooks/useSightingFeed.ts +++ b/src/hooks/useSightingFeed.ts @@ -2,25 +2,30 @@ import { useEffect, useRef, useState } from "react"; import { useQuery } from "@tanstack/react-query"; import type { SightingType } from "../types/types"; import { useSoundOnChange } from "react-sounds"; -import click from "../assets/sounds/ui/computer-mouse-click.mp3"; +import switchSound from "../assets/sounds/ui/switch.mp3"; -async function fetchSighting(url: string, ref: number): Promise { +async function fetchSighting( + url: string | undefined, + ref: number +): Promise { const res = await fetch(`${url}${ref}`); if (!res.ok) throw new Error(String(res.status)); return res.json(); } -export function useSightingFeed(url: string, side: string) { +export function useSightingFeed(url: string | undefined) { const [sightings, setSightings] = useState([]); const [selectedRef, setSelectedRef] = useState(null); + const [sessionStarted, setSessionStarted] = useState(false); + const [sessionList, setSessionList] = useState([]); const mostRecent = sightings[0] ?? null; const latestRef = mostRecent?.ref ?? null; const [selectedSighting, setSelectedSighting] = useState( null ); - useSoundOnChange(click, latestRef, { - volume: side === "Rear" ? 0 : 1, + useSoundOnChange(switchSound, latestRef, { + volume: 1, }); const currentRef = useRef(-1); @@ -52,6 +57,13 @@ export function useSightingFeed(url: string, side: string) { staleTime: 0, }); + useEffect(() => { + if (sessionStarted) { + if (!mostRecent) return; + setSessionList([...sessionList, mostRecent]); + } + }, [mostRecent, sessionList, sessionStarted]); + useEffect(() => { const data = query.data; if (!data) return; @@ -92,13 +104,15 @@ export function useSightingFeed(url: string, side: string) { // console.error("Sighting feed error:", query.error); } }, [query.error]); - return { sightings, selectedRef, setSelectedRef, mostRecent, selectedSighting, + sessionList, + sessionStarted, + setSessionStarted, setSelectedSighting, data: query.data, isLoading: query.isLoading, diff --git a/src/main.tsx b/src/main.tsx index 027b230..258824d 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -13,7 +13,7 @@ Modal.setAppElement("#root"); createRoot(document.getElementById("root")!).render( - + diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index fb45cd2..fa99529 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -2,6 +2,7 @@ import FrontCameraOverviewCard from "../components/FrontCameraOverview/FrontCame import RearCameraOverviewCard from "../components/RearCameraOverview/RearCameraOverviewCard"; import SightingHistoryWidget from "../components/SightingsWidget/SightingWidget"; import { SightingFeedProvider } from "../context/providers/SightingFeedProvider"; + import { CAM_BASE } from "../utils/config"; const Dashboard = () => { diff --git a/src/pages/Session.tsx b/src/pages/Session.tsx index 11440d7..cbb682b 100644 --- a/src/pages/Session.tsx +++ b/src/pages/Session.tsx @@ -2,18 +2,21 @@ import HistoryList from "../components/HistoryList/HistoryList.tsx"; import HitSearchCard from "../components/SessionForm/HitSearchCard.tsx"; import SessionCard from "../components/SessionForm/SessionCard.tsx"; import { useAlertHitContext } from "../context/AlertHitContext.ts"; +import { SightingFeedProvider } from "../context/providers/SightingFeedProvider.tsx"; const Session = () => { useAlertHitContext(); return ( -
- - -
- + +
+ + +
+ +
-
+ ); }; diff --git a/src/utils/config.ts b/src/utils/config.ts index fac7887..6665faa 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,5 +1,4 @@ -// const rawCamBase = import.meta.env.VITE_CAM_BASE; -const rawCamBase = import.meta.env.VITE_OUTSIDE_BASEURL; +const rawCamBase = import.meta.env.VITE_CAM_BASE; export const CAM_BASE = rawCamBase && rawCamBase.trim().length > 0 diff --git a/vite.config.ts b/vite.config.ts index bc2b686..ce718e8 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -6,5 +6,5 @@ import tailwindcss from "@tailwindcss/vite"; export default defineConfig({ plugins: [react(), tailwindcss()], server: { host: true }, - base: "/index", + base: "/InCarTest", });