import React, { useMemo, useState } from "react"; import { Stack, Typography, Divider, Chip, Tooltip, IconButton, alpha, Box } from "@mui/material"; import { OpenInNew as OpenInNewIcon, ContentCopy as ContentCopyIcon, ExpandMore as ExpandMoreIcon, ExpandLess as ExpandLessIcon } from "@mui/icons-material"; import { Fact } from "./types"; import { GlassyCard, glassyCardSx } from "./ui"; import { TextToSpeechButton } from "../shared/TextToSpeechButton"; interface FactCardProps { fact: Fact; } const MAX_PREVIEW_LENGTH = 200; // Characters to show before truncation export const FactCard: React.FC = ({ fact }) => { const [expanded, setExpanded] = useState(false); const hostname = useMemo(() => { try { return new URL(fact.url).hostname; } catch { return fact.url; } }, [fact.url]); const handleCopy = () => { navigator.clipboard.writeText(fact.quote); }; const shouldTruncate = fact.quote.length > MAX_PREVIEW_LENGTH; const previewText = shouldTruncate ? fact.quote.slice(0, MAX_PREVIEW_LENGTH).trim() + "..." : fact.quote; const fullText = fact.quote; return ( {/* Source Image */} {fact.image && ( )} {/* Quote Text - Truncated with expand option */} {expanded ? fullText : previewText} {/* Highlights */} {fact.highlights && fact.highlights.length > 0 && expanded && ( Highlights: {fact.highlights.slice(0, 2).map((highlight, idx) => ( "{highlight}" ))} )} {shouldTruncate && ( { e.stopPropagation(); setExpanded(!expanded); }} sx={{ p: 0.25, mt: 0.25, color: "#4f46e5", "&:hover": { background: alpha("#4f46e5", 0.1) }, }} > {expanded ? ( ) : ( )} )} {/* Source and Actions */} {hostname || "source"} { e.stopPropagation(); handleCopy(); }} sx={{ color: "rgba(15,23,42,0.6)", p: 0.5, "&:hover": { background: alpha("#4f46e5", 0.1) }, }} > {/* Confidence and Date */} {fact.date !== "Unknown" ? new Date(fact.date).toLocaleDateString("en-US", { month: "short", year: "numeric" }) : fact.date} ); };