import { ArchivedFormat, CollectionIncludingMembersAndLinkCount, LinkIncludingShortenedCollectionAndTags, } from "@/types/global"; import { useEffect, useRef, useState } from "react"; import useLinkStore from "@/store/links"; import useCollectionStore from "@/store/collections"; import unescapeString from "@/lib/client/unescapeString"; import LinkActions from "@/components/LinkViews/LinkComponents/LinkActions"; import LinkDate from "@/components/LinkViews/LinkComponents/LinkDate"; import LinkCollection from "@/components/LinkViews/LinkComponents/LinkCollection"; import Image from "next/image"; import { previewAvailable } from "@/lib/shared/getArchiveValidity"; import Link from "next/link"; import LinkIcon from "./LinkComponents/LinkIcon"; import useOnScreen from "@/hooks/useOnScreen"; import { generateLinkHref } from "@/lib/client/generateLinkHref"; import useAccountStore from "@/store/account"; import usePermissions from "@/hooks/usePermissions"; import toast from "react-hot-toast"; import LinkTypeBadge from "./LinkComponents/LinkTypeBadge"; type Props = { link: LinkIncludingShortenedCollectionAndTags; count: number; className?: string; flipDropdown?: boolean; editMode?: boolean; }; export default function LinkMasonry({ link, flipDropdown, editMode }: Props) { const viewMode = localStorage.getItem("viewMode") || "card"; const { collections } = useCollectionStore(); const { account } = useAccountStore(); const { links, getLink, setSelectedLinks, selectedLinks } = useLinkStore(); useEffect(() => { if (!editMode) { setSelectedLinks([]); } }, [editMode]); const handleCheckboxClick = ( link: LinkIncludingShortenedCollectionAndTags ) => { if (selectedLinks.includes(link)) { setSelectedLinks(selectedLinks.filter((e) => e !== link)); } else { setSelectedLinks([...selectedLinks, link]); } }; let shortendURL; try { if (link.url) { shortendURL = new URL(link.url).host.toLowerCase(); } } catch (error) { console.log(error); } const [collection, setCollection] = useState( collections.find( (e) => e.id === link.collection.id ) as CollectionIncludingMembersAndLinkCount ); useEffect(() => { setCollection( collections.find( (e) => e.id === link.collection.id ) as CollectionIncludingMembersAndLinkCount ); }, [collections, links]); const ref = useRef(null); const isVisible = useOnScreen(ref); const permissions = usePermissions(collection?.id as number); useEffect(() => { let interval: any; if ( isVisible && !link.preview?.startsWith("archives") && link.preview !== "unavailable" ) { interval = setInterval(async () => { getLink(link.id as number); }, 5000); } return () => { if (interval) { clearInterval(interval); } }; }, [isVisible, link.preview]); const [showInfo, setShowInfo] = useState(false); const selectedStyle = selectedLinks.some( (selectedLink) => selectedLink.id === link.id ) ? "border-primary bg-base-300" : "border-neutral-content"; const selectable = editMode && (permissions === true || permissions?.canCreate || permissions?.canDelete); return (
selectable ? handleCheckboxClick(link) : editMode ? toast.error( "You don't have permission to edit or delete this item." ) : undefined } >
!editMode && window.open(generateLinkHref(link, account), "_blank") } >
{previewAvailable(link) ? ( { const target = e.target as HTMLElement; target.style.display = "none"; }} /> ) : link.preview === "unavailable" ? null : (
)}
{link.preview !== "unavailable" && (
)}

{unescapeString(link.name)}

{link.description && (

{unescapeString(link.description)}

)}
{link.tags[0] && (
{link.tags.map((e, i) => ( { e.stopPropagation(); }} className="btn btn-xs btn-ghost truncate max-w-[19rem]" > #{e.name} ))}
)}

{collection && ( )}
{showInfo && (
setShowInfo(!showInfo)} className=" float-right btn btn-sm outline-none btn-circle btn-ghost z-10" >

Description


{link.description ? ( unescapeString(link.description) ) : ( No description provided. )}

{link.tags[0] && ( <>

Tags


{link.tags.map((e, i) => ( { e.stopPropagation(); }} className="btn btn-xs btn-ghost truncate max-w-[19rem]" > #{e.name} ))}
)}
)} setShowInfo(!showInfo)} linkInfo={showInfo} flipDropdown={flipDropdown} />
); }