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 { Switch } from "@/components/ui/switch";
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 { PiSlidersHorizontalBold } from "react-icons/pi";
import { MdAutoAwesome } from "react-icons/md";
@ -67,37 +67,6 @@ export default function DetailStream({
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.
// This helps when the component mounts while the video is already
// playing — it guarantees the matching review is highlighted right
@ -247,8 +216,6 @@ export default function DetailStream({
onActivate={() => setActiveReviewId(id)}
onOpenUpload={(e) => setUpload(e)}
alwaysExpandActive={alwaysExpandActive}
eventsById={eventsById}
isValidatingEvents={isValidatingEvents}
/>
);
})
@ -312,8 +279,6 @@ type ReviewGroupProps = {
effectiveTime?: number;
annotationOffset: number;
alwaysExpandActive?: boolean;
eventsById: Map<string, Event>;
isValidatingEvents: boolean;
};
function ReviewGroup({
@ -327,8 +292,6 @@ function ReviewGroup({
effectiveTime,
annotationOffset,
alwaysExpandActive = false,
eventsById,
isValidatingEvents,
}: ReviewGroupProps) {
const { t } = useTranslation("views/events");
const [open, setOpen] = useState(false);
@ -353,14 +316,13 @@ function ReviewGroup({
date_style: "medium",
});
const shouldFetchEvents = review?.data?.detections?.length > 0;
const shouldFetchEvents = open && review?.data?.detections?.length > 0;
const fetchedEvents = useMemo(() => {
if (!shouldFetchEvents || !review?.data?.detections) return undefined;
return review.data.detections
.map((eventId) => eventsById.get(eventId))
.filter((event): event is Event => event !== undefined);
}, [shouldFetchEvents, review?.data?.detections, eventsById]);
const { data: fetchedEvents, isValidating } = useSWR<Event[]>(
shouldFetchEvents
? ["event_ids", { ids: review.data.detections.join(",") }]
: null,
);
const rawIconLabels: string[] = [
...(fetchedEvents
@ -483,7 +445,7 @@ function ReviewGroup({
{open && (
<div className="space-y-0.5">
{shouldFetchEvents && isValidatingEvents && !fetchedEvents ? (
{shouldFetchEvents && isValidating && !fetchedEvents ? (
<ActivityIndicator />
) : (
(fetchedEvents || []).map((event, index) => {