import "./LinkPreview.css"; import { useEffect, useState } from "react"; import { LRUCache } from "typescript-lru-cache"; import { MediaElement } from "@/Components/Embed/MediaElement"; import Spinner from "@/Components/Icons/Spinner"; import { LinkPreviewData, NostrServices } from "@/External/NostrServices"; import { ProxyImg } from "../ProxyImg"; import GenericPlayer from "./GenericPlayer"; async function fetchUrlPreviewInfo(url: string) { const api = new NostrServices("https://nostr.api.v0l.io"); try { return await api.linkPreview(url.endsWith(")") ? url.slice(0, -1) : url); } catch (e) { console.warn(`Failed to load link preview`, url); } } const cache = new LRUCache({ maxSize: 100, }); const LinkPreview = ({ url }: { url: string }) => { const [preview, setPreview] = useState(cache.get(url)); useEffect(() => { (async () => { if (preview) return; const data = await fetchUrlPreviewInfo(url); if (data) { const type = data.og_tags?.find(a => a[0].toLowerCase() === "og:type"); const canPreviewType = type?.[1].startsWith("image") || type?.[1].startsWith("video") || false; if (canPreviewType || data.image) { setPreview(data); cache.set(url, data); return; } } setPreview(null); })(); }, [url]); if (preview === null) return ( e.stopPropagation()} target="_blank" rel="noreferrer" className="ext"> {url} ); function previewElement() { const type = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:type")?.[1]; if (type?.startsWith("video")) { const urlTags = ["og:video:secure_url", "og:video:url", "og:video"]; const link = preview?.og_tags?.find(a => urlTags.includes(a[0].toLowerCase()))?.[1]; const videoType = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:video:type")?.[1] ?? "video/mp4"; if (link && videoType.startsWith("video/")) { return ; } if (link && videoType.startsWith("text/html") && preview?.image) { return ; } } if (type?.startsWith("image")) { const urlTags = ["og:image:secure_url", "og:image:url", "og:image"]; const link = preview?.og_tags?.find(a => urlTags.includes(a[0].toLowerCase()))?.[1]; const videoType = preview?.og_tags?.find(a => a[0].toLowerCase() === "og:image:type")?.[1] ?? "image/png"; if (link) { return ; } } if (preview?.image) { return ; } return null; } return ( ); }; export default LinkPreview;