File size: 2,299 Bytes
f59fbe2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import { IconX, IconPlayerPlay, IconLoader2 } from "@tabler/icons-react";
import { cn } from "@/lib/utils";
import { getMediaTypeFromDataUri } from "@/lib/media-utils";

interface ThumbnailWrapperProps {
  onClick?: () => void;
  onRemove?: () => void;
  sizeClass: string;
  children: React.ReactNode;
}

function ThumbnailWrapper({ onClick, onRemove, sizeClass, children }: ThumbnailWrapperProps) {
  return (
    <div className="relative group shrink-0">
      <div className={cn(sizeClass, "rounded-md cursor-pointer border border-border hover:border-primary/50 transition-colors overflow-hidden")} onClick={onClick}>
        {children}
      </div>
      {onRemove && (
        <button
          onClick={(e) => {
            e.stopPropagation();
            onRemove();
          }}
          className="absolute -top-1.5 -right-1.5 size-5 rounded-full text-red-500 bg-white border border-red-500 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer"
        >
          <IconX className="size-3" />
        </button>
      )}
    </div>
  );
}

interface MediaThumbnailProps {
  src?: string;
  onClick?: () => void;
  onRemove?: () => void;
  size?: "sm" | "md";
  className?: string;
}

export function MediaThumbnail({ src, onClick, onRemove, size = "md", className }: MediaThumbnailProps) {
  const sizeClass = size === "sm" ? "size-12" : "size-16";
  const isLoading = !src;
  const isVideo = src && getMediaTypeFromDataUri(src) === "video";

  return (
    <ThumbnailWrapper onClick={onClick} onRemove={onRemove} sizeClass={cn(sizeClass, className)}>
      {isLoading ? (
        <div className="w-full h-full bg-muted flex items-center justify-center">
          <IconLoader2 className="size-5 text-muted-foreground animate-spin" />
        </div>
      ) : isVideo ? (
        <div className="relative w-full h-full bg-black">
          <video src={src} className="w-full h-full object-cover" muted preload="metadata" />
          <div className="absolute inset-0 flex items-center justify-center bg-black/30">
            <IconPlayerPlay className="size-5 text-white" />
          </div>
        </div>
      ) : (
        <img src={src} alt="Media" className={cn(sizeClass, "object-cover")} />
      )}
    </ThumbnailWrapper>
  );
}