import type { BookmarksLayoutTypes } from "@/lib/userLocalSettings/types"; import React, { useEffect, useState } from "react"; import Image from "next/image"; import Link from "next/link"; import useBulkActionsStore from "@/lib/bulkActions"; import { bookmarkLayoutSwitch, useBookmarkLayout, } from "@/lib/userLocalSettings/bookmarksLayout"; import { cn } from "@/lib/utils"; import dayjs from "dayjs"; import { Check, Image as ImageIcon, NotebookPen } from "lucide-react"; import { useTheme } from "next-themes"; import type { ZBookmark } from "@hoarder/shared/types/bookmarks"; import { isBookmarkStillTagging } from "@hoarder/shared-react/utils/bookmarkUtils"; import { BookmarkTypes } from "@hoarder/shared/types/bookmarks"; import BookmarkActionBar from "./BookmarkActionBar"; import TagList from "./TagList"; interface Props { bookmark: ZBookmark; image: (layout: BookmarksLayoutTypes, className: string) => React.ReactNode; title?: React.ReactNode; content?: React.ReactNode; footer?: React.ReactNode; className?: string; fitHeight?: boolean; wrapTags: boolean; } function BottomRow({ footer, bookmark, }: { footer?: React.ReactNode; bookmark: ZBookmark; }) { return (
{footer && <>{footer}•} {dayjs(bookmark.createdAt).format("MMM DD")}
); } function MultiBookmarkSelector({ bookmark }: { bookmark: ZBookmark }) { const { selectedBookmarks, isBulkEditEnabled } = useBulkActionsStore(); const toggleBookmark = useBulkActionsStore((state) => state.toggleBookmark); const [isSelected, setIsSelected] = useState(false); const { theme } = useTheme(); useEffect(() => { setIsSelected(selectedBookmarks.some((item) => item.id === bookmark.id)); }, [selectedBookmarks]); if (!isBulkEditEnabled) return null; const getIconColor = () => { if (theme === "dark") { return isSelected ? "black" : "white"; } return isSelected ? "white" : "black"; }; const getIconBackgroundColor = () => { if (theme === "dark") { return isSelected ? "bg-white" : "bg-white bg-opacity-10"; } return isSelected ? "bg-black" : "bg-white bg-opacity-40"; }; return ( ); } function ListView({ bookmark, image, title, content, footer, className, }: Props) { return (
{image("list", "object-cover rounded-lg size-32")}
{title && (
{title}
)} {content &&
{content}
}
); } function GridView({ bookmark, image, title, content, footer, className, wrapTags, layout, fitHeight = false, }: Props & { layout: BookmarksLayoutTypes }) { const img = image("grid", "h-56 min-h-56 w-full object-cover rounded-t-lg"); return (
{img &&
{img}
}
{title && (
{title}
)} {content &&
{content}
}
); } function CompactView({ bookmark, title, footer, className }: Props) { return (
{bookmark.content.type === BookmarkTypes.LINK && bookmark.content.favicon && ( favicon )} {bookmark.content.type === BookmarkTypes.TEXT && ( )} {bookmark.content.type === BookmarkTypes.ASSET && ( )} {
{title ?? "Untitled"}
} {footer && (

•{footer}

)}

{dayjs(bookmark.createdAt).format("MMM DD")}
); } export function BookmarkLayoutAdaptingCard(props: Props) { const layout = useBookmarkLayout(); return bookmarkLayoutSwitch(layout, { masonry: , grid: , list: , compact: , }); }