-
-
+
);
diff --git a/src/components/video/detectionLogs.tsx b/src/components/video/detectionLogs.tsx
index b2e6c5e..5a89a65 100644
--- a/src/components/video/detectionLogs.tsx
+++ b/src/components/video/detectionLogs.tsx
@@ -1,10 +1,13 @@
'use client';
import { useEffect, useRef } from 'react';
-import { Activity, Film, MapPin } from 'lucide-react';
+import { Activity, Film, ImageIcon, MapPin } from 'lucide-react';
+
import { ScrollArea } from '@/components/ui/scroll-area';
-import { DetectionResultLog } from '@/types';
+import { Skeleton } from '@/components/ui/skeleton';
+import { useProtectedMediaObjectUrl } from '@/hooks/useProtectedMedia';
import { cn } from '@/lib/utils';
+import type { DetectionResultLog } from '@/types';
interface DetectionLogsProps {
logs: DetectionResultLog[];
@@ -19,6 +22,47 @@ const formatVideoTime = (seconds: number) => {
return `${minutes}:${secs.toString().padStart(2, '0')}`;
};
+function DetectionLogThumbnail({
+ url,
+ label,
+}: {
+ url?: string | null;
+ label: string;
+}) {
+ const { objectUrl, isLoading, isError } = useProtectedMediaObjectUrl(url);
+
+ if (!url) {
+ return (
+
+
+
+ );
+ }
+
+ if (isLoading) {
+ return
;
+ }
+
+ if (isError || !objectUrl) {
+ return (
+
+ N/A
+
+ );
+ }
+
+ return (
+
+

+
+ );
+}
+
const DetectionLogs = ({ logs, activeLogId, onSeek }: DetectionLogsProps) => {
const activeLogRef = useRef
(null);
@@ -49,6 +93,7 @@ const DetectionLogs = ({ logs, activeLogId, onSeek }: DetectionLogsProps) => {
const timestampSeconds = log.frame.timestamp_seconds;
const { latitude, longitude } = log.location;
const isActive = activeLogId === log.id;
+ const label = log.detection.display_name;
return (