{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "media-card",
  "type": "registry:block",
  "title": "Media Card",
  "description": "A card component for displaying media with video hover previews and engagement stats.",
  "dependencies": [
    "react-player"
  ],
  "registryDependencies": [
    "post-engagement"
  ],
  "files": [
    {
      "path": "src/components/deso/media-card.tsx",
      "content": "import * as React from 'react';\nimport { cn, formatCount } from '@/lib/utils/deso';\nimport { ImageIcon, PlayCircle, ImagesIcon, Music } from 'lucide-react';\nimport { UserInfo } from './user-info';\nimport { ProfilePicture } from './profile-picture';\nimport { Timestamp } from './timestamp';\nimport { PostText } from './post-text';\nimport { PostEngagement } from './post-engagement';\nimport { Profile } from '@/lib/schemas/deso';\nimport ReactPlayer from 'react-player/lazy';\n\nexport type MediaType = 'image' | 'video' | 'audio' | 'carousel';\n\nexport interface MediaCardProps {\n  id: string;\n  imageUrl: string;\n  mediaType: MediaType;\n  viewCount: number;\n  duration?: string; \n  showStats?: boolean;\n  showDuration?: boolean;\n  videoUrl?: string;\n  publicKey: string;\n  profile?: Profile;\n  timestamp: Date | string;\n  title: string;\n  description?: string;\n  compact?: boolean;\n  showIcon?: boolean;\n  onClick?: () => void;\n  className?: string;\n}\n\nconst mediaTypeConfig: {\n  [key in MediaType]: {\n    Icon: React.ComponentType<{ className?: string }>;\n  };\n} = {\n  image: { Icon: ImageIcon },\n  video: { Icon: PlayCircle },\n  audio: { Icon: Music },\n  carousel: { Icon: ImagesIcon },\n};\n\nexport const MediaCard = ({\n  id,\n  imageUrl,\n  mediaType,\n  viewCount,\n  duration,\n  showStats = true,\n  showDuration = true,\n  videoUrl,\n  publicKey,\n  profile,\n  timestamp,\n  title,\n  description,\n  onClick,\n  className,\n  compact = false,\n  showIcon = false,\n}: MediaCardProps) => {\n  const [isHovered, setIsHovered] = React.useState(false);\n  const [showVideo, setShowVideo] = React.useState(false);\n  const [fadeState, setFadeState] = React.useState<'thumbnail' | 'transitioning' | 'video'>('thumbnail');\n  const { Icon } = mediaTypeConfig[mediaType];\n\n  // Handle fade transitions when hovering\n  React.useEffect(() => {\n    let timeoutId: NodeJS.Timeout;\n    \n    if (isHovered && videoUrl && mediaType === 'video') {\n      // Start fade out of thumbnail\n      setFadeState('transitioning');\n      timeoutId = setTimeout(() => {\n        // Show video and fade in\n        setShowVideo(true);\n        setFadeState('video');\n      }, 200); // 200ms for fade out, then show video\n    } else {\n      // Fade out video and show thumbnail\n      if (showVideo) {\n        setFadeState('transitioning');\n        setTimeout(() => {\n          setShowVideo(false);\n          setFadeState('thumbnail');\n        }, 200); // 200ms fade out before switching back\n      } else {\n        setFadeState('thumbnail');\n      }\n    }\n\n    return () => {\n      if (timeoutId) {\n        clearTimeout(timeoutId);\n      }\n    };\n  }, [isHovered, videoUrl, mediaType, showVideo]);\n\n  return (\n    <div className={cn('flex flex-col gap-3', compact ? 'flex-row' : 'flex-col', className)}>\n      {/* Media Thumbnail */}\n      <div \n        className={cn(\"relative cursor-pointer\", compact ? 'max-w-[240px]' : 'w-fit')} \n        onMouseEnter={() => setIsHovered(true)}\n        onMouseLeave={() => setIsHovered(false)}\n        onClick={onClick}\n      >\n        <div className=\"relative aspect-video rounded-lg overflow-hidden\">\n          {/* Video Player - with fade transition */}\n          {(showVideo || fadeState === 'transitioning') && videoUrl && mediaType === 'video' && (\n            <div \n              className={cn(\n                \"absolute inset-0 bg-black group shadow-md transition-all duration-100 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\",\n                fadeState === 'video' ? 'opacity-100' : 'opacity-0'\n              )}\n            >\n              <ReactPlayer\n                url={videoUrl}\n                width=\"100%\"\n                height=\"100%\"\n                playing={showVideo}\n                muted={true}\n                controls={false}\n                loop={true}\n                className=\"absolute inset-0\"\n                style={{ \n                  objectFit: 'cover',\n                }}\n              />\n              \n              {/* Duration Overlay */}\n              {showDuration && duration && (\n                <div className=\"absolute top-2 right-2 bg-black/40 backdrop-blur-sm text-white text-xs px-2 py-1 rounded-full\">\n                  {duration}\n                </div>\n              )}\n              \n              {/* View Count Overlay */}\n              {showStats && viewCount > 0 && (\n                <div className=\"absolute bottom-4 right-4 z-10 opacity-100 transition-opacity\">\n                  <PostEngagement\n                    variant=\"view\"\n                    count={viewCount}\n                    className=\"text-white drop-shadow-md\"\n                  />\n                </div>\n              )}\n            </div>\n          )}\n\n          {/* Static Thumbnail - with fade transition */}\n          <div \n            className={cn(\n              \"group relative w-full h-full shadow-md transition-all duration-300 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\",\n              fadeState === 'thumbnail' ? 'opacity-100' : 'opacity-0'\n            )}\n          >\n            <img\n              src={imageUrl}\n              alt=\"Media content\"\n              className=\"h-full w-full object-cover transition-opacity duration-200 group-hover:opacity-90\"\n            />\n            <div className=\"absolute inset-0 bg-gradient-to-t from-black/50 to-transparent opacity-100 transition-opacity\" />\n\n            {showIcon && (\n              <div className=\"absolute bottom-4 left-4 z-10 opacity-100 transition-opacity\">\n                <Icon className=\"h-5 w-5 text-white drop-shadow-md\" />\n              </div>\n            )}\n\n            {showStats && (\n              <div className=\"absolute bottom-4 right-4 z-10 opacity-100 transition-opacity\">\n                <PostEngagement\n                  variant=\"view\"\n                  count={viewCount}\n                  className=\"text-white drop-shadow-md\"\n                />\n              </div>\n            )}\n            \n            {/* Duration Overlay */}\n            {showDuration && duration && mediaType === 'video' && (\n              <div className=\"absolute top-2 right-2 bg-black/40 backdrop-blur-sm text-white text-xs px-2 py-1 rounded-full\">\n                {duration}\n              </div>\n            )}\n          </div>\n        </div>\n      </div>\n      \n      {/* Content Below */}\n      <div className={cn(\"flex gap-3\", compact ? 'mt-0' : 'mt-2')}>\n        \n        {/* Text Content */}\n        <div className=\"flex-1 min-w-0\">\n          <div className=\"flex items-start justify-between gap-2 mb-1\">\n            <h3 className=\"font-bold text-sm leading-tight line-clamp-2\">\n              {title}\n            </h3>\n          </div>                 \n          \n          {/* Description */}\n          {description && (\n            <PostText\n              text={description}\n              variant=\"simple\"\n              className=\"text-sm text-muted-foreground [&_p]:!text-muted-foreground\"\n              lineClamp={2}\n            />\n          )}\n\n           {/* Channel Name and Timestamp */}\n           <div className=\"items-center gap-1 text-xs text-muted-foreground mt-3 mb-2\">\n            <UserInfo\n              publicKey={publicKey}\n              profile={profile}\n              pictureSize=\"sm\"\n              showVerification={true}\n              gap=\"md\"\n              className=\"text-xs\"\n              usernameClassName=\"text-muted-foreground hover:text-foreground\"\n            >\n              <div className=\"flex items-center gap-1\"> \n                <Timestamp timestamp={timestamp} className=\"text-muted-foreground\" />• <span className=\"text-muted-foreground\"> {formatCount(viewCount)} views</span>\n              </div>\n            </UserInfo>\n          </div>\n        </div>\n      </div>\n    </div>\n  );\n}; ",
      "type": "registry:component",
      "target": "src/components/deso-ui/media-card.tsx"
    }
  ]
}