From 7d7d3754d33b41478fea2d2d7ed902d665a9e03d Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Thu, 21 Mar 2024 02:15:56 +0000 Subject: feature: A better looking bookmark preview page --- .../dashboard/bookmarks/BookmarkPreview.tsx | 204 +++++++++++++++------ 1 file changed, 145 insertions(+), 59 deletions(-) (limited to 'apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx') diff --git a/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx b/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx index 4209192e..632422c4 100644 --- a/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx +++ b/apps/web/components/dashboard/bookmarks/BookmarkPreview.tsx @@ -2,58 +2,98 @@ import Image from "next/image"; import Link from "next/link"; -import { BackButton } from "@/components/ui/back-button"; +import { ScrollArea } from "@/components/ui/scroll-area"; import { Skeleton } from "@/components/ui/skeleton"; -import { isBookmarkStillCrawling } from "@/lib/bookmarkUtils"; +import { + Tooltip, + TooltipContent, + TooltipPortal, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { + isBookmarkStillCrawling, + isBookmarkStillLoading, +} from "@/lib/bookmarkUtils"; import { api } from "@/lib/trpc"; -import { ArrowLeftCircle, CalendarDays, ExternalLink } from "lucide-react"; +import dayjs from "dayjs"; +import relativeTime from "dayjs/plugin/relativeTime"; +import { CalendarDays, ExternalLink } from "lucide-react"; import Markdown from "react-markdown"; import type { ZBookmark } from "@hoarder/trpc/types/bookmarks"; -export default function BookmarkPreview({ - initialData, -}: { - initialData: ZBookmark; -}) { - const { data: bookmark } = api.bookmarks.getBookmark.useQuery( - { - bookmarkId: initialData.id, - }, - { - initialData, - refetchInterval: (query) => { - const data = query.state.data; - if (!data) { - return false; - } - // If the link is not crawled or not tagged - if (isBookmarkStillCrawling(data)) { - return 1000; - } - return false; - }, - }, +import { TagsEditor } from "./TagsEditor"; + +dayjs.extend(relativeTime); + +function ContentLoading() { + return ( +
+ + + +
); +} - const linkHeader = bookmark.content.type == "link" && ( -
-

- {bookmark.content.title ?? bookmark.content.url} -

- +function CreationTime({ createdAt }: { createdAt: Date }) { + return ( + + + + + {dayjs(createdAt).fromNow()} + + + {createdAt.toLocaleString()} + + + ); +} + +function LinkHeader({ bookmark }: { bookmark: ZBookmark }) { + if (bookmark.content.type !== "link") { + throw new Error("Unexpected content type"); + } + + const title = bookmark.content.title ?? bookmark.content.url; + + return ( +
+ + + +

{title}

+
+ + + {title} + + +
+
+ View Original +
); +} +function TextContentSection({ bookmark }: { bookmark: ZBookmark }) { let content; switch (bookmark.content.type) { case "link": { if (!bookmark.content.htmlContent) { content = ( -
Failed to fetch link content ...
+
+ Failed to fetch link content ... +
); } else { content = ( @@ -61,24 +101,39 @@ export default function BookmarkPreview({ dangerouslySetInnerHTML={{ __html: bookmark.content.htmlContent || "", }} - className="prose" + className="prose mx-auto" /> ); } break; } case "text": { - content = {bookmark.content.text}; + content = ( + {bookmark.content.text} + ); break; } - case "asset": { + } + + return {content}; +} + +function AssetContentSection({ bookmark }: { bookmark: ZBookmark }) { + if (bookmark.content.type != "asset") { + throw new Error("Invalid content type"); + } + + let content; + switch (bookmark.content.assetType) { + case "image": { switch (bookmark.content.assetType) { case "image": { content = ( -
+
asset
@@ -88,31 +143,62 @@ export default function BookmarkPreview({ break; } } + return content; +} + +export default function BookmarkPreview({ + initialData, +}: { + initialData: ZBookmark; +}) { + const { data: bookmark } = api.bookmarks.getBookmark.useQuery( + { + bookmarkId: initialData.id, + }, + { + initialData, + refetchInterval: (query) => { + const data = query.state.data; + if (!data) { + return false; + } + // If the link is not crawled or not tagged + if (isBookmarkStillLoading(data)) { + return 1000; + } + return false; + }, + }, + ); + + let content; + switch (bookmark.content.type) { + case "link": + case "text": { + content = ; + break; + } + case "asset": { + content = ; + break; + } + } + + const linkHeader = bookmark.content.type == "link" && ( + + ); return ( -
-
- - - -
- - {bookmark.createdAt.toLocaleString()} - -
+
+
+ {isBookmarkStillCrawling(bookmark) ? : content}
-
- {linkHeader} -
- {isBookmarkStillCrawling(bookmark) ? ( -
- - - -
- ) : ( - content - )} +
+ {linkHeader} + +
+ +
); -- cgit v1.2.3-70-g09d2