rcgit

/ karakeep

Commit 47939a54

SHA 47939a5409a0eb18b088c37b011ca6a3c4920746
Author MohamedBassem <me at mbassem dot com>
Author Date 2024-09-15 00:50 +0000
Committer MohamedBassem <me at mbassem dot com>
Commit Date 2024-09-15 00:50 +0000
Parent(s) f263f9e48a38 (diff)
Tree 75a3f6e18ca9

patch snapshot

feature(web): Add a compact layout. Fixes #379
File + - Graph
M apps/web/components/dashboard/ChangeLayout.tsx +8 -1
M apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx +56 -1
M apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx +1 -0
M apps/web/components/dashboard/bookmarks/EditorCard.tsx +1 -0
M apps/web/components/dashboard/bookmarks/TextCard.tsx +1 -0
M apps/web/lib/userLocalSettings/types.ts +1 -1
6 file(s) changed, 68 insertions(+), 3 deletions(-)

apps/web/components/dashboard/ChangeLayout.tsx

diff --git a/apps/web/components/dashboard/ChangeLayout.tsx b/apps/web/components/dashboard/ChangeLayout.tsx
index 7449bd2d..6ec38245 100644
--- a/apps/web/components/dashboard/ChangeLayout.tsx
+++ b/apps/web/components/dashboard/ChangeLayout.tsx
@@ -10,7 +10,13 @@ import {
 } from "@/components/ui/dropdown-menu";
 import { useBookmarkLayout } from "@/lib/userLocalSettings/bookmarksLayout";
 import { updateBookmarksLayout } from "@/lib/userLocalSettings/userLocalSettings";
-import { Check, LayoutDashboard, LayoutGrid, LayoutList } from "lucide-react";
+import {
+  Check,
+  LayoutDashboard,
+  LayoutGrid,
+  LayoutList,
+  List,
+} from "lucide-react";
 
 type LayoutType = "masonry" | "grid" | "list";
 
@@ -18,6 +24,7 @@ const iconMap = {
   masonry: LayoutDashboard,
   grid: LayoutGrid,
   list: LayoutList,
+  compact: List,
 };
 
 export default function ChangeLayout() {

apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx

diff --git a/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx b/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
index f5891f40..e11e4295 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
@@ -1,5 +1,6 @@
 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 {
@@ -8,11 +9,12 @@ import {
 } from "@/lib/userLocalSettings/bookmarksLayout";
 import { cn } from "@/lib/utils";
 import dayjs from "dayjs";
-import { Check } from "lucide-react";
+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";
@@ -187,6 +189,58 @@ function GridView({
   );
 }
 
+function CompactView({ bookmark, title, footer, className }: Props) {
+  return (
+    <div
+      className={cn(
+        "relative flex flex-col overflow-hidden rounded-lg shadow-md",
+        className,
+        "max-h-96",
+      )}
+    >
+      <MultiBookmarkSelector bookmark={bookmark} />
+      <div className="flex h-full justify-between gap-2 overflow-hidden p-2">
+        <div className="flex items-center gap-2">
+          {bookmark.content.type === BookmarkTypes.LINK &&
+            bookmark.content.favicon && (
+              <Image
+                src={bookmark.content.favicon}
+                alt="favicon"
+                width={5}
+                unoptimized
+                height={5}
+                className="size-5"
+              />
+            )}
+          {bookmark.content.type === BookmarkTypes.TEXT && (
+            <NotebookPen className="size-5" />
+          )}
+          {bookmark.content.type === BookmarkTypes.ASSET && (
+            <ImageIcon className="size-5" />
+          )}
+          {
+            <div className="shrink-1 text-md line-clamp-1 overflow-hidden text-ellipsis break-words">
+              {title ?? "Untitled"}
+            </div>
+          }
+          {footer && (
+            <p className="flex shrink-0 gap-2 text-gray-500">•{footer}</p>
+          )}
+          <p className="text-gray-500">•</p>
+          <Link
+            href={`/dashboard/preview/${bookmark.id}`}
+            suppressHydrationWarning
+            className="shrink-0 gap-2 text-gray-500"
+          >
+            {dayjs(bookmark.createdAt).format("MMM DD")}
+          </Link>
+        </div>
+        <BookmarkActionBar bookmark={bookmark} />
+      </div>
+    </div>
+  );
+}
+
 export function BookmarkLayoutAdaptingCard(props: Props) {
   const layout = useBookmarkLayout();
 
@@ -194,5 +248,6 @@ export function BookmarkLayoutAdaptingCard(props: Props) {
     masonry: <GridView layout={layout} {...props} />,
     grid: <GridView layout={layout} {...props} />,
     list: <ListView {...props} />,
+    compact: <CompactView {...props} />,
   });
 }

apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx

diff --git a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
index 540546fe..16c25850 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarksGrid.tsx
@@ -80,6 +80,7 @@ export default function BookmarksGrid({
           </Masonry>
         ),
         list: <div className="grid grid-cols-1">{children}</div>,
+        compact: <div className="grid grid-cols-1">{children}</div>,
       })}
       {hasNextPage && (
         <div className="flex justify-center">

apps/web/components/dashboard/bookmarks/EditorCard.tsx

diff --git a/apps/web/components/dashboard/bookmarks/EditorCard.tsx b/apps/web/components/dashboard/bookmarks/EditorCard.tsx
index 605fcf42..d1489b09 100644
--- a/apps/web/components/dashboard/bookmarks/EditorCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/EditorCard.tsx
@@ -147,6 +147,7 @@ export default function EditorCard({ className }: { className?: string }) {
     grid: "h-96",
     masonry: "h-96",
     list: undefined,
+    compact: undefined,
   });
 
   const handlePaste = async (

apps/web/components/dashboard/bookmarks/TextCard.tsx

diff --git a/apps/web/components/dashboard/bookmarks/TextCard.tsx b/apps/web/components/dashboard/bookmarks/TextCard.tsx
index 6fa2a1cf..9876d904 100644
--- a/apps/web/components/dashboard/bookmarks/TextCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/TextCard.tsx
@@ -31,6 +31,7 @@ export default function TextCard({
           bookmarkLayoutSwitch(layout, {
             grid: null,
             masonry: null,
+            compact: null,
             list: (
               <div
                 className={cn(

apps/web/lib/userLocalSettings/types.ts

diff --git a/apps/web/lib/userLocalSettings/types.ts b/apps/web/lib/userLocalSettings/types.ts
index 155469f5..08e38638 100644
--- a/apps/web/lib/userLocalSettings/types.ts
+++ b/apps/web/lib/userLocalSettings/types.ts
@@ -2,7 +2,7 @@ import { z } from "zod";
 
 export const USER_LOCAL_SETTINGS_COOKIE_NAME = "hoarder-user-local-settings";
 
-const zBookmarkGridLayout = z.enum(["grid", "list", "masonry"]);
+const zBookmarkGridLayout = z.enum(["grid", "list", "masonry", "compact"]);
 export type BookmarksLayoutTypes = z.infer<typeof zBookmarkGridLayout>;
 
 export const zUserLocalSettings = z.object({