"use client"; import Image from "next/image"; import Link from "next/link"; import type { ZBookmarkTypeLink } from "@hoarder/shared/types/bookmarks"; import { getBookmarkLinkImageUrl, getSourceUrl, isBookmarkStillCrawling, } from "@hoarder/shared-react/utils/bookmarkUtils"; import { BookmarkLayoutAdaptingCard } from "./BookmarkLayoutAdaptingCard"; import FooterLinkURL from "./FooterLinkURL"; function LinkTitle({ bookmark }: { bookmark: ZBookmarkTypeLink }) { const link = bookmark.content; const parsedUrl = new URL(link.url); return ( {bookmark.title ?? link?.title ?? parsedUrl.host} ); } function LinkImage({ bookmark, className, }: { bookmark: ZBookmarkTypeLink; className?: string; }) { const link = bookmark.content; const imgComponent = (url: string, unoptimized: boolean) => ( card banner ); const imageDetails = getBookmarkLinkImageUrl(link); let img: React.ReactNode; if (isBookmarkStillCrawling(bookmark)) { img = imgComponent("/blur.avif", false); } else if (imageDetails) { img = imgComponent(imageDetails.url, !imageDetails.localAsset); } else { // No image found // A dummy white pixel for when there's no image. img = imgComponent( "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII=", true, ); } return (
{img}
); } export default function LinkCard({ bookmark: bookmarkLink, className, }: { bookmark: ZBookmarkTypeLink; className?: string; }) { return ( } footer={} bookmark={bookmarkLink} wrapTags={false} image={(_layout, className) => ( )} className={className} /> ); }