feat(results): replace video playback with detection image preview and map

This commit is contained in:
2026-07-07 15:36:27 +05:30
parent d88978a830
commit fb9a654aea
13 changed files with 433 additions and 36 deletions

View File

@@ -0,0 +1,69 @@
'use client';
import { AlertTriangle, ImageIcon, Loader2 } from 'lucide-react';
import Image from 'next/image';
import { useProtectedMediaObjectUrl } from '@/hooks/useProtectedMedia';
import type { DetectionResultLog } from '@/types';
import BoundingBoxOverlay from '@/components/annotation/boundingBoxOverlay';
interface AnnotatedDetectionImageProps {
detection?: DetectionResultLog;
videoWidth: number;
videoHeight: number;
}
export default function AnnotatedDetectionImage({
detection,
videoWidth,
videoHeight,
}: AnnotatedDetectionImageProps) {
const { objectUrl, isLoading, isError } = useProtectedMediaObjectUrl(
detection?.detection.context_image_url,
);
const aspectRatio =
videoWidth > 0 && videoHeight > 0
? `${videoWidth} / ${videoHeight}`
: '16 / 9';
return (
<div
className="relative flex w-full items-center justify-center overflow-hidden rounded-lg border bg-black"
style={{ aspectRatio }}
>
{!detection ? (
<div className="flex flex-col items-center gap-2 text-muted-foreground">
<ImageIcon className="size-7" />
<p className="text-sm">Select a detection to view its image.</p>
</div>
) : isLoading ? (
<div className="flex flex-col items-center gap-2 text-muted-foreground">
<Loader2 className="size-7 animate-spin text-primary" />
<p className="text-sm">Loading detection image...</p>
</div>
) : isError || !objectUrl ? (
<div className="flex flex-col items-center gap-2 text-destructive">
<AlertTriangle className="size-7" />
<p className="text-sm">Failed to load the detection image.</p>
</div>
) : (
<>
<Image
src={objectUrl}
alt={`${detection.detection.display_name} detection`}
fill
unoptimized
className="object-contain"
/>
<BoundingBoxOverlay
detections={[detection]}
videoWidth={videoWidth}
videoHeight={videoHeight}
/>
</>
)}
</div>
);
}