From 2ac3c39a9c80305bb959d88561e78f65a1cd1be1 Mon Sep 17 00:00:00 2001
From: MohamedBassem <me@mbassem.com>
Date: Thu, 22 Feb 2024 17:33:12 +0000
Subject: feature: Adding some loading card while the link is getting crawled

---
 .../dashboard/bookmarks/components/LinkCard.tsx    | 85 +++++++++++++++++-----
 1 file changed, 67 insertions(+), 18 deletions(-)

(limited to 'packages/web/app/dashboard/bookmarks/components/LinkCard.tsx')

diff --git a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx
index 7413c2fe..35696134 100644
--- a/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx
+++ b/packages/web/app/dashboard/bookmarks/components/LinkCard.tsx
@@ -1,3 +1,5 @@
+"use client";
+
 import { Badge } from "@/components/ui/badge";
 import {
   ImageCard,
@@ -10,9 +12,71 @@ import {
 import { ZBookmark } from "@/lib/types/api/bookmarks";
 import Link from "next/link";
 import BookmarkOptions from "./BookmarkOptions";
+import { api } from "@/lib/trpc";
+import { Skeleton } from "@/components/ui/skeleton";
+
+function isStillCrawling(bookmark: ZBookmark) {
+  return (
+    !bookmark.content.crawledAt && Date.now() - bookmark.createdAt < 30 * 1000
+  );
+}
 
-export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
+function TagList(bookmark: ZBookmark, stillCrawling: boolean) {
+  if (stillCrawling) {
+    return (
+      <ImageCardBody className="space-y-2">
+        <Skeleton className="h-4 w-full" />
+        <Skeleton className="h-4 w-full" />
+        <Skeleton className="h-4 w-full" />
+      </ImageCardBody>
+    );
+  }
+  return (
+    <ImageCardBody className="flex h-full flex-wrap space-x-1 overflow-hidden">
+      {bookmark.tags.map((t) => (
+        <Link
+          className="flex h-full flex-col justify-end"
+          key={t.id}
+          href={`/dashboard/tags/${t.name}`}
+        >
+          <Badge
+            variant="default"
+            className="text-nowrap bg-gray-300 text-gray-500 hover:text-white"
+          >
+            #{t.name}
+          </Badge>
+        </Link>
+      ))}
+    </ImageCardBody>
+  );
+}
+
+export default function LinkCard({
+  bookmark: initialData,
+}: {
+  bookmark: ZBookmark;
+}) {
+  const { data: bookmark } = api.bookmarks.getBookmark.useQuery(
+    {
+      id: initialData.id,
+    },
+    {
+      initialData,
+      refetchInterval: (query) => {
+        const data = query.state.data;
+        if (!data) {
+          return false;
+        }
+        // If the link is not crawled and
+        if (isStillCrawling(data)) {
+          return 1000;
+        }
+        return false;
+      },
+    },
+  );
   const link = bookmark.content;
+  const isCrawling = isStillCrawling(bookmark);
   const parsedUrl = new URL(link.url);
 
   // A dummy white pixel for when there's no image.
@@ -28,7 +92,7 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
       }
     >
       <Link href={link.url}>
-        <ImageCardBanner src={image} />
+        <ImageCardBanner src={isCrawling ? "/blur.avif" : image} />
       </Link>
       <ImageCardContent>
         <ImageCardTitle>
@@ -38,22 +102,7 @@ export default function LinkCard({ bookmark }: { bookmark: ZBookmark }) {
         </ImageCardTitle>
         {/* 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">
-          {bookmark.tags.map((t) => (
-            <Link
-              className="flex h-full flex-col justify-end"
-              key={t.id}
-              href={`/dashboard/tags/${t.name}`}
-            >
-              <Badge
-                variant="default"
-                className="text-nowrap bg-gray-300 text-gray-500 hover:text-white"
-              >
-                #{t.name}
-              </Badge>
-            </Link>
-          ))}
-        </ImageCardBody>
+        {TagList(bookmark, isCrawling)}
         <ImageCardFooter>
           <div className="flex justify-between text-gray-500">
             <div className="my-auto">
-- 
cgit v1.2.3-70-g09d2

