"use client"; import { useState } from "react"; import Link from "next/link"; import { BookmarkTagsEditor } from "@/components/dashboard/bookmarks/BookmarkTagsEditor"; import { FullPageSpinner } from "@/components/ui/full-page-spinner"; import { Separator } from "@/components/ui/separator"; import { Skeleton } from "@/components/ui/skeleton"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger, } from "@/components/ui/tooltip"; import useRelativeTime from "@/lib/hooks/relative-time"; import { useTranslation } from "@/lib/i18n/client"; import { api } from "@/lib/trpc"; import { Building, CalendarDays, ExternalLink, User } from "lucide-react"; import { BookmarkTypes, ZBookmark } from "@karakeep/shared/types/bookmarks"; import { getBookmarkRefreshInterval, getBookmarkTitle, getSourceUrl, isBookmarkStillCrawling, } from "@karakeep/shared/utils/bookmarkUtils"; import SummarizeBookmarkArea from "../bookmarks/SummarizeBookmarkArea"; import ActionBar from "./ActionBar"; import { AssetContentSection } from "./AssetContentSection"; import AttachmentBox from "./AttachmentBox"; import HighlightsBox from "./HighlightsBox"; import LinkContentSection from "./LinkContentSection"; import { NoteEditor } from "./NoteEditor"; import { TextContentSection } from "./TextContentSection"; function ContentLoading() { return (
); } function CreationTime({ createdAt }: { createdAt: Date }) { const { fromNow, localCreatedAt } = useRelativeTime(createdAt); return ( {fromNow} {localCreatedAt} ); } function BookmarkMetadata({ bookmark }: { bookmark: ZBookmark }) { if (bookmark.content.type !== BookmarkTypes.LINK) { return null; } const { author, publisher, datePublished } = bookmark.content; if (!author && !publisher && !datePublished) { return null; } return (
{author && (
By {author}
)} {publisher && (
{publisher}
)} {datePublished && }
); } function PublishedDate({ datePublished }: { datePublished: Date }) { const { fromNow, localCreatedAt } = useRelativeTime(datePublished); return (
Published {fromNow}
{localCreatedAt}
); } export default function BookmarkPreview({ bookmarkId, initialData, }: { bookmarkId: string; initialData?: ZBookmark; }) { const { t } = useTranslation(); const [activeTab, setActiveTab] = useState("content"); const { data: bookmark } = api.bookmarks.getBookmark.useQuery( { bookmarkId, }, { initialData, refetchInterval: (query) => { const data = query.state.data; if (!data) { return false; } return getBookmarkRefreshInterval(data); }, }, ); if (!bookmark) { return ; } let content; switch (bookmark.content.type) { case BookmarkTypes.LINK: { content = ; break; } case BookmarkTypes.TEXT: { content = ; break; } case BookmarkTypes.ASSET: { content = ; break; } } const sourceUrl = getSourceUrl(bookmark); const title = getBookmarkTitle(bookmark); // Common content for both layouts const contentSection = isBookmarkStillCrawling(bookmark) ? ( ) : ( content ); const detailsSection = (

{title === undefined || title === "" ? "Untitled" : title}

{sourceUrl && ( {t("preview.view_original")} )}

{t("common.tags")}

{t("common.note")}

); return ( <> {/* Render original layout for wide screens */}
{contentSection}
{detailsSection}
{/* Render tabbed layout for narrow/vertical screens */} {t("preview.tabs.content")} {t("preview.tabs.details")} {contentSection} {detailsSection} ); }