Only fetch events when review group is open

This commit is contained in:
Nicolas Mowen 2025-12-08 10:20:49 -07:00
parent 1c9c111a5e
commit 5bff7214a3

View File

@ -25,7 +25,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Switch } from "@/components/ui/switch"; import { Switch } from "@/components/ui/switch";
import { useUserPersistence } from "@/hooks/use-user-persistence"; import { useUserPersistence } from "@/hooks/use-user-persistence";
import { isDesktop } from "react-device-detect"; import { isDesktop, isOpera } from "react-device-detect";
import { resolveZoneName } from "@/hooks/use-zone-friendly-name"; import { resolveZoneName } from "@/hooks/use-zone-friendly-name";
import { PiSlidersHorizontalBold } from "react-icons/pi"; import { PiSlidersHorizontalBold } from "react-icons/pi";
import { MdAutoAwesome } from "react-icons/md"; import { MdAutoAwesome } from "react-icons/md";
@ -67,37 +67,6 @@ export default function DetailStream({
onSeek(timestamp, isPlaying); onSeek(timestamp, isPlaying);
}; };
// Collect all unique event IDs from all review items
const allEventIds = useMemo(() => {
if (!reviewItems || reviewItems.length === 0) return [];
const idsSet = new Set<string>();
reviewItems.forEach((review) => {
if (review?.data?.detections?.length > 0) {
review.data.detections.forEach((id) => idsSet.add(id));
}
});
return Array.from(idsSet);
}, [reviewItems]);
// Fetch all events in a single API call
const { data: allFetchedEvents, isValidating: isValidatingEvents } = useSWR<
Event[]
>(
allEventIds.length > 0
? ["event_ids", { ids: allEventIds.join(",") }]
: null,
);
// Create a Map for quick event lookup by ID
const eventsById = useMemo(() => {
if (!allFetchedEvents) return new Map<string, Event>();
const map = new Map<string, Event>();
allFetchedEvents.forEach((event) => {
map.set(event.id, event);
});
return map;
}, [allFetchedEvents]);
// Ensure we initialize the active review when reviewItems first arrive. // Ensure we initialize the active review when reviewItems first arrive.
// This helps when the component mounts while the video is already // This helps when the component mounts while the video is already
// playing — it guarantees the matching review is highlighted right // playing — it guarantees the matching review is highlighted right
@ -247,8 +216,6 @@ export default function DetailStream({
onActivate={() => setActiveReviewId(id)} onActivate={() => setActiveReviewId(id)}
onOpenUpload={(e) => setUpload(e)} onOpenUpload={(e) => setUpload(e)}
alwaysExpandActive={alwaysExpandActive} alwaysExpandActive={alwaysExpandActive}
eventsById={eventsById}
isValidatingEvents={isValidatingEvents}
/> />
); );
}) })
@ -312,8 +279,6 @@ type ReviewGroupProps = {
effectiveTime?: number; effectiveTime?: number;
annotationOffset: number; annotationOffset: number;
alwaysExpandActive?: boolean; alwaysExpandActive?: boolean;
eventsById: Map<string, Event>;
isValidatingEvents: boolean;
}; };
function ReviewGroup({ function ReviewGroup({
@ -327,8 +292,6 @@ function ReviewGroup({
effectiveTime, effectiveTime,
annotationOffset, annotationOffset,
alwaysExpandActive = false, alwaysExpandActive = false,
eventsById,
isValidatingEvents,
}: ReviewGroupProps) { }: ReviewGroupProps) {
const { t } = useTranslation("views/events"); const { t } = useTranslation("views/events");
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
@ -353,14 +316,13 @@ function ReviewGroup({
date_style: "medium", date_style: "medium",
}); });
const shouldFetchEvents = review?.data?.detections?.length > 0; const shouldFetchEvents = open && review?.data?.detections?.length > 0;
const fetchedEvents = useMemo(() => { const { data: fetchedEvents, isValidating } = useSWR<Event[]>(
if (!shouldFetchEvents || !review?.data?.detections) return undefined; shouldFetchEvents
return review.data.detections ? ["event_ids", { ids: review.data.detections.join(",") }]
.map((eventId) => eventsById.get(eventId)) : null,
.filter((event): event is Event => event !== undefined); );
}, [shouldFetchEvents, review?.data?.detections, eventsById]);
const rawIconLabels: string[] = [ const rawIconLabels: string[] = [
...(fetchedEvents ...(fetchedEvents
@ -483,7 +445,7 @@ function ReviewGroup({
{open && ( {open && (
<div className="space-y-0.5"> <div className="space-y-0.5">
{shouldFetchEvents && isValidatingEvents && !fetchedEvents ? ( {shouldFetchEvents && isValidating && !fetchedEvents ? (
<ActivityIndicator /> <ActivityIndicator />
) : ( ) : (
(fetchedEvents || []).map((event, index) => { (fetchedEvents || []).map((event, index) => {