From 33f407797213c56dd2f13e98228a5305efdf90fd Mon Sep 17 00:00:00 2001
From: xuatz <xzlow10@gmail.com>
Date: Mon, 3 Nov 2025 04:32:18 +0900
Subject: feat: display notes on bookmark card (#2083)

* feat: display notes on bookmark card

* apply styling

* include mobile impl

* apply pr comments

* add display options menu into PR

* put it under app setting

* cleanup

* address pr comments

* change the default for show notes to false

* make the in-card note font lighter

---------

Co-authored-by: Mohamed Bassem <me@mbassem.com>
---
 .../bookmarks/BookmarkLayoutAdaptingCard.tsx       | 28 +++++++++++++++-------
 1 file changed, 20 insertions(+), 8 deletions(-)

(limited to '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 4b511a3c..26c1c72b 100644
--- a/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
+++ b/apps/web/components/dashboard/bookmarks/BookmarkLayoutAdaptingCard.tsx
@@ -1,10 +1,14 @@
+"use client";
+
 import type { BookmarksLayoutTypes } from "@/lib/userLocalSettings/types";
-import React, { useEffect, useState } from "react";
+import type { ReactNode } from "react";
+import { useEffect, useState } from "react";
 import Image from "next/image";
 import Link from "next/link";
 import useBulkActionsStore from "@/lib/bulkActions";
 import {
   bookmarkLayoutSwitch,
+  useBookmarkDisplaySettings,
   useBookmarkLayout,
 } from "@/lib/userLocalSettings/bookmarksLayout";
 import { cn } from "@/lib/utils";
@@ -17,14 +21,15 @@ import { isBookmarkStillTagging } from "@karakeep/shared/utils/bookmarkUtils";
 
 import BookmarkActionBar from "./BookmarkActionBar";
 import BookmarkFormattedCreatedAt from "./BookmarkFormattedCreatedAt";
+import { NotePreview } from "./NotePreview";
 import TagList from "./TagList";
 
 interface Props {
   bookmark: ZBookmark;
-  image: (layout: BookmarksLayoutTypes, className: string) => React.ReactNode;
-  title?: React.ReactNode;
-  content?: React.ReactNode;
-  footer?: React.ReactNode;
+  image: (layout: BookmarksLayoutTypes, className: string) => ReactNode;
+  title?: ReactNode;
+  content?: ReactNode;
+  footer?: ReactNode;
   className?: string;
   fitHeight?: boolean;
   wrapTags: boolean;
@@ -34,7 +39,7 @@ function BottomRow({
   footer,
   bookmark,
 }: {
-  footer?: React.ReactNode;
+  footer?: ReactNode;
   bookmark: ZBookmark;
 }) {
   return (
@@ -112,6 +117,9 @@ function ListView({
   footer,
   className,
 }: Props) {
+  const { showNotes } = useBookmarkDisplaySettings();
+  const note = showNotes ? bookmark.note?.trim() : undefined;
+
   return (
     <div
       className={cn(
@@ -131,6 +139,7 @@ function ListView({
             </div>
           )}
           {content && <div className="shrink-1 overflow-hidden">{content}</div>}
+          {note && <NotePreview note={note} bookmarkId={bookmark.id} />}
           <div className="flex shrink-0 flex-wrap gap-1 overflow-hidden">
             <TagList
               bookmark={bookmark}
@@ -155,7 +164,9 @@ function GridView({
   layout,
   fitHeight = false,
 }: Props & { layout: BookmarksLayoutTypes }) {
-  const img = image("grid", "h-56 min-h-56 w-full object-cover rounded-t-lg");
+  const { showNotes } = useBookmarkDisplaySettings();
+  const note = showNotes ? bookmark.note?.trim() : undefined;
+  const img = image("grid", "h-52 min-h-52 w-full object-cover rounded-t-lg");
 
   return (
     <div
@@ -166,7 +177,7 @@ function GridView({
       )}
     >
       <MultiBookmarkSelector bookmark={bookmark} />
-      {img && <div className="h-56 w-full shrink-0 overflow-hidden">{img}</div>}
+      {img && <div className="h-52 w-full shrink-0 overflow-hidden">{img}</div>}
       <div className="flex h-full flex-col justify-between gap-2 overflow-hidden p-2">
         <div className="grow-1 flex flex-col gap-2 overflow-hidden">
           {title && (
@@ -175,6 +186,7 @@ function GridView({
             </div>
           )}
           {content && <div className="shrink-1 overflow-hidden">{content}</div>}
+          {note && <NotePreview note={note} bookmarkId={bookmark.id} />}
           <div className="flex shrink-0 flex-wrap gap-1 overflow-hidden">
             <TagList
               className={wrapTags ? undefined : "h-full"}
-- 
cgit v1.2.3-70-g09d2

