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 bb8e237..0000000 Binary files a/src/assets/sounds/ui/computer-mouse-click.mp3 and /dev/null differ diff --git a/src/assets/sounds/ui/keystroke_hard.mp3 b/src/assets/sounds/ui/keystroke_hard.mp3 deleted file mode 100644 index 128ef88..0000000 Binary files a/src/assets/sounds/ui/keystroke_hard.mp3 and /dev/null differ diff --git a/src/assets/sounds/ui/switch.mp3 b/src/assets/sounds/ui/switch.mp3 new file mode 100644 index 0000000..6c2480c Binary files /dev/null and b/src/assets/sounds/ui/switch.mp3 differ diff --git a/src/components/HistoryList/AlertItem.tsx b/src/components/HistoryList/AlertItem.tsx index c8f27d8..ccdcb26 100644 --- a/src/components/HistoryList/AlertItem.tsx +++ b/src/components/HistoryList/AlertItem.tsx @@ -16,6 +16,7 @@ type AlertItemProps = { const AlertItem = ({ item }: AlertItemProps) => { 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 = () => {
+ {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", });