diff options
| author | MohamedBassem <me@mbassem.com> | 2024-03-05 19:38:34 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-03-05 19:38:34 +0000 |
| commit | 2413f0efee2dcb4cd4c9389f5a496d4b3f71335c (patch) | |
| tree | 4ebc862412cb4f31cd94a7190cb610975210c461 /packages/web/app/dashboard | |
| parent | ed9874f4d0b327a09aaed28717d98be787f0ebf6 (diff) | |
| download | karakeep-2413f0efee2dcb4cd4c9389f5a496d4b3f71335c.tar.zst | |
fix: Show loading indicators in the bookmark preview page
Diffstat (limited to 'packages/web/app/dashboard')
4 files changed, 120 insertions, 84 deletions
diff --git a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx index 76d3f1b8..50f30e47 100644 --- a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx +++ b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx @@ -14,25 +14,11 @@ import BookmarkOptions from "./BookmarkOptions"; import { api } from "@/lib/trpc"; import { Maximize2, Star } from "lucide-react"; import TagList from "./TagList"; - -function isStillCrawling(bookmark: ZBookmark) { - return ( - bookmark.content.type == "link" && - !bookmark.content.crawledAt && - Date.now().valueOf() - bookmark.createdAt.valueOf() < 30 * 1000 - ); -} - -function isStillTagging(bookmark: ZBookmark) { - return ( - bookmark.taggingStatus == "pending" && - Date.now().valueOf() - bookmark.createdAt.valueOf() < 30 * 1000 - ); -} - -function isStillLoading(bookmark: ZBookmark) { - return isStillTagging(bookmark) || isStillCrawling(bookmark); -} +import { + isBookmarkStillCrawling, + isBookmarkStillLoading, + isBookmarkStillTagging, +} from "@/lib/bookmarkUtils"; export default function LinkCard({ bookmark: initialData, @@ -53,7 +39,7 @@ export default function LinkCard({ return false; } // If the link is not crawled or not tagged - if (isStillLoading(data)) { + if (isBookmarkStillLoading(data)) { return 1000; } return false; @@ -76,7 +62,7 @@ export default function LinkCard({ <ImageCard className={className}> <Link href={link.url}> <ImageCardBanner - src={isStillCrawling(bookmark) ? "/blur.avif" : image} + src={isBookmarkStillCrawling(bookmark) ? "/blur.avif" : image} /> </Link> <ImageCardContent> @@ -88,7 +74,10 @@ export default function LinkCard({ {/* There's a hack here. Every tag has the full hight of the container itself. That why, when we enable flex-wrap, the overflowed don't show up. */} <ImageCardBody className="flex h-full flex-wrap space-x-1 overflow-hidden"> - <TagList bookmark={bookmark} loading={isStillTagging(bookmark)} /> + <TagList + bookmark={bookmark} + loading={isBookmarkStillTagging(bookmark)} + /> </ImageCardBody> <ImageCardFooter> <div className="mt-1 flex justify-between text-gray-500"> diff --git a/packages/web/app/dashboard/bookmarks/components/TextCard.tsx b/packages/web/app/dashboard/bookmarks/components/TextCard.tsx index 5e0ba3f9..2565e69d 100644 --- a/packages/web/app/dashboard/bookmarks/components/TextCard.tsx +++ b/packages/web/app/dashboard/bookmarks/components/TextCard.tsx @@ -9,15 +9,8 @@ import TagList from "./TagList"; import Markdown from "react-markdown"; import { useState } from "react"; import { BookmarkedTextViewer } from "./BookmarkedTextViewer"; -import { Button } from "@/components/ui/button"; import Link from "next/link"; - -function isStillTagging(bookmark: ZBookmark) { - return ( - bookmark.taggingStatus == "pending" && - Date.now().valueOf() - bookmark.createdAt.valueOf() < 30 * 1000 - ); -} +import { isBookmarkStillTagging } from "@/lib/bookmarkUtils"; export default function TextCard({ bookmark: initialData, @@ -37,7 +30,7 @@ export default function TextCard({ if (!data) { return false; } - if (isStillTagging(data)) { + if (isBookmarkStillTagging(data)) { return 1000; } return false; @@ -69,7 +62,10 @@ export default function TextCard({ {bookmarkedText.text} </Markdown> <div className="mt-4 flex flex-none flex-wrap gap-1 overflow-hidden"> - <TagList bookmark={bookmark} loading={isStillTagging(bookmark)} /> + <TagList + bookmark={bookmark} + loading={isBookmarkStillTagging(bookmark)} + /> </div> <div className="flex w-full justify-between"> <div /> diff --git a/packages/web/app/dashboard/preview/[bookmarkId]/components/BookmarkPreview.tsx b/packages/web/app/dashboard/preview/[bookmarkId]/components/BookmarkPreview.tsx new file mode 100644 index 00000000..2a8ae1b1 --- /dev/null +++ b/packages/web/app/dashboard/preview/[bookmarkId]/components/BookmarkPreview.tsx @@ -0,0 +1,101 @@ +"use client"; + +import { BackButton } from "@/components/ui/back-button"; +import { Skeleton } from "@/components/ui/skeleton"; +import { isBookmarkStillCrawling } from "@/lib/bookmarkUtils"; +import { api } from "@/lib/trpc"; +import { ZBookmark } from "@hoarder/trpc/types/bookmarks"; +import { ArrowLeftCircle, CalendarDays, ExternalLink } from "lucide-react"; +import Link from "next/link"; +import Markdown from "react-markdown"; + +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; + }, + }, + ); + + const linkHeader = bookmark.content.type == "link" && ( + <div className="flex flex-col space-y-2"> + <p className="text-center text-3xl"> + {bookmark.content.title || bookmark.content.url} + </p> + <Link href={bookmark.content.url} className="mx-auto flex gap-2"> + <span className="my-auto">View Original</span> + <ExternalLink /> + </Link> + </div> + ); + + let content; + switch (bookmark.content.type) { + case "link": { + if (!bookmark.content.htmlContent) { + content = ( + <div className="text-red-500">Failed to fetch link content ...</div> + ); + } else { + content = ( + <div + dangerouslySetInnerHTML={{ + __html: bookmark.content.htmlContent || "", + }} + className="prose" + /> + ); + } + break; + } + case "text": { + content = <Markdown className="prose">{bookmark.content.text}</Markdown>; + break; + } + } + + return ( + <div className="bg-background m-4 min-h-screen space-y-4 rounded-md border p-4"> + <div className="flex justify-between"> + <BackButton className="ghost" variant="ghost"> + <ArrowLeftCircle /> + </BackButton> + <div className="my-auto"> + <span className="my-auto flex gap-2"> + <CalendarDays /> {bookmark.createdAt.toLocaleString()} + </span> + </div> + </div> + <hr /> + {linkHeader} + <div className="mx-auto flex h-full border-x p-2 px-4 lg:w-2/3"> + {isBookmarkStillCrawling(bookmark) ? ( + <div className="flex w-full flex-col gap-2"> + <Skeleton className="h-4" /> + <Skeleton className="h-4" /> + <Skeleton className="h-4" /> + </div> + ) : ( + content + )} + </div> + </div> + ); +} diff --git a/packages/web/app/dashboard/preview/[bookmarkId]/page.tsx b/packages/web/app/dashboard/preview/[bookmarkId]/page.tsx index 030ad2df..47aeb891 100644 --- a/packages/web/app/dashboard/preview/[bookmarkId]/page.tsx +++ b/packages/web/app/dashboard/preview/[bookmarkId]/page.tsx @@ -1,8 +1,5 @@ -import { BackButton } from "@/components/ui/back-button"; import { api } from "@/server/api/client"; -import { ArrowLeftCircle, CalendarDays, ExternalLink } from "lucide-react"; -import Link from "next/link"; -import Markdown from "react-markdown"; +import BookmarkPreview from "./components/BookmarkPreview"; export default async function BookmarkPreviewPage({ params, @@ -13,52 +10,5 @@ export default async function BookmarkPreviewPage({ bookmarkId: params.bookmarkId, }); - const linkHeader = bookmark.content.type == "link" && ( - <div className="flex flex-col space-y-2"> - <p className="text-center text-3xl">{bookmark.content.title}</p> - <Link href={bookmark.content.url} className="mx-auto flex gap-2"> - <span className="my-auto">View Original</span> - <ExternalLink /> - </Link> - </div> - ); - - let content; - switch (bookmark.content.type) { - case "link": { - content = ( - <div - dangerouslySetInnerHTML={{ - __html: bookmark.content.htmlContent || "", - }} - className="prose" - /> - ); - break; - } - case "text": { - content = <Markdown className="prose">{bookmark.content.text}</Markdown>; - break; - } - } - - return ( - <div className="bg-background m-4 min-h-screen space-y-4 rounded-md border p-4"> - <div className="flex justify-between"> - <BackButton className="ghost" variant="ghost"> - <ArrowLeftCircle /> - </BackButton> - <div className="my-auto"> - <span className="my-auto flex gap-2"> - <CalendarDays /> {bookmark.createdAt.toLocaleString()} - </span> - </div> - </div> - <hr /> - {linkHeader} - <div className="mx-auto flex h-full border-x p-2 px-4 lg:w-2/3"> - {content} - </div> - </div> - ); + return <BookmarkPreview initialData={bookmark} />; } |
