import { Bookmark, Check, EyeOff, ListFilter } from "lucide-react"; import clsx from "clsx"; import type { Video } from "../lib/api"; import { formatDuration, formatViews, relativeTime } from "../lib/format"; function Actions({ video, onState, onChannelFilter, }: { video: Video; onState: (id: string, status: string) => void; onChannelFilter?: (channelId: string, channelName: string) => void; }) { const act = (status: string) => (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); onState(video.id, video.status === status ? "new" : status); }; return (
{onChannelFilter && ( )}
); } function Thumb({ video, className }: { video: Video; className?: string }) { return ( video.status === "new" && undefined} className={clsx( "block relative rounded-xl overflow-hidden bg-surface border border-border shadow-md group-hover:shadow-2xl transition-shadow", className )} > {video.thumbnail_url ? ( ) : (
)} {video.duration_seconds != null && ( {formatDuration(video.duration_seconds)} )} {video.live_status === "was_live" && ( stream )} {video.status === "saved" && ( )} ); } export default function VideoCard({ video, view, onState, onChannelFilter, }: { video: Video; view: "grid" | "list"; onState: (id: string, status: string) => void; onChannelFilter?: (channelId: string, channelName: string) => void; }) { const watched = video.status === "watched"; const meta = ( <> {video.view_count != null && <>{formatViews(video.view_count)} views ยท } {relativeTime(video.published_at)} ); const title = ( {video.title} ); if (view === "list") { return (
{title} e.stopPropagation()} className="text-sm text-muted truncate mt-0.5 block w-fit max-w-full hover:text-fg" > {video.channel_title}
{meta}
); } return (
{video.channel_thumbnail && ( )}
{title} e.stopPropagation()} className="text-sm text-muted truncate mt-0.5 block w-fit max-w-full hover:text-fg" > {video.channel_title}
{meta}
); }