import "./Text.css"; import { useState } from "react"; import { HexKey, ParsedFragment } from "@snort/system"; import Invoice from "Element/Embed/Invoice"; import Hashtag from "Element/Embed/Hashtag"; import HyperText from "Element/HyperText"; import CashuNuts from "Element/Embed/CashuNuts"; import RevealMedia from "./Event/RevealMedia"; import { ProxyImg } from "./ProxyImg"; import { SpotlightMediaModal } from "./Deck/SpotlightMedia"; import HighlightedText from "./HighlightedText"; import { useTextTransformer } from "Hooks/useTextTransformCache"; export interface TextProps { id: string; content: string; creator: HexKey; tags: Array>; disableMedia?: boolean; disableMediaSpotlight?: boolean; disableLinkPreview?: boolean; depth?: number; truncate?: number; className?: string; highlighText?: string; onClick?: (e: React.MouseEvent) => void; } export default function Text({ id, content, tags, creator, disableMedia, depth, disableMediaSpotlight, disableLinkPreview, truncate, className, highlighText, onClick, }: TextProps) { const [showSpotlight, setShowSpotlight] = useState(false); const [imageIdx, setImageIdx] = useState(0); const elements = useTextTransformer(id, content, tags); const images = elements.filter(a => a.type === "media" && a.mimeType?.startsWith("image")).map(a => a.content); function renderContentWithHighlightedText(content: string, textToHighlight: string) { const textToHighlightArray = textToHighlight.trim().toLowerCase().split(" "); const re = new RegExp(`(${textToHighlightArray.join("|")})`, "gi"); const splittedContent = content.split(re); const fragments = splittedContent.map(c => { if (textToHighlightArray.includes(c.toLowerCase())) { return { type: "highlighted_text", content: c, } as ParsedFragment; } return c; }); return ( <> {fragments.map(f => { if (typeof f === "string") { return f; } return ; })} ); } const renderContent = () => { let lenCtr = 0; function renderChunk(a: ParsedFragment) { if (truncate) { if (lenCtr > truncate) { return null; } else if (lenCtr + a.content.length > truncate) { lenCtr += a.content.length; return
{a.content.slice(0, truncate - lenCtr)}...
; } else { lenCtr += a.content.length; } } if (a.type === "media" && !a.mimeType?.startsWith("unknown")) { if (disableMedia ?? false) { return ( e.stopPropagation()} target="_blank" rel="noreferrer" className="ext"> {a.content} ); } return ( { if (!disableMediaSpotlight) { e.stopPropagation(); e.preventDefault(); setShowSpotlight(true); const selected = images.findIndex(b => b === a.content); setImageIdx(selected === -1 ? 0 : selected); } }} /> ); } else { switch (a.type) { case "invoice": return ; case "hashtag": return ; case "cashu": return ; case "media": case "link": return ; case "custom_emoji": return ; default: return (
{highlighText ? renderContentWithHighlightedText(a.content, highlighText) : a.content}
); } } } return elements.map(a => renderChunk(a)); }; return (
{renderContent()} {showSpotlight && setShowSpotlight(false)} idx={imageIdx} />}
); }