From 8a27b692b8930fc766e129f037ef311e1b9ac7e1 Mon Sep 17 00:00:00 2001 From: Krishna Kumar Date: Tue, 16 Jun 2026 14:20:28 -0500 Subject: [PATCH] feat(BookmarkRow): show a content excerpt under each bookmark title MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface a bit of the page content in the list without fetching/parsing pages ourselves — linkding already returns the scraped metadata in the bookmark payload. Add Bookmark.contentExcerpt (website_description, falling back to the user's note) and render it under the title: AI summary takes priority and stays italic, otherwise the scraped excerpt shows. Rows with neither degrade to the existing favicon + title layout. Co-Authored-By: Claude Opus 4.8 (1M context) --- Marks/Models/Bookmark.swift | 11 +++++++++++ Marks/Views/BookmarkRow.swift | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Marks/Models/Bookmark.swift b/Marks/Models/Bookmark.swift index 725ba1a..e06e772 100644 --- a/Marks/Models/Bookmark.swift +++ b/Marks/Models/Bookmark.swift @@ -41,6 +41,17 @@ struct Bookmark: Codable, Identifiable, Sendable, Hashable { var domain: String { URL(string: url)?.host ?? url } + + /// A short content snippet for list previews: the page's scraped meta + /// description, falling back to the user's own note. nil when neither exists. + var contentExcerpt: String? { + for candidate in [websiteDescription, description] { + if let c = candidate?.trimmingCharacters(in: .whitespacesAndNewlines), !c.isEmpty { + return c + } + } + return nil + } } struct BookmarkResponse: Codable, Sendable { diff --git a/Marks/Views/BookmarkRow.swift b/Marks/Views/BookmarkRow.swift index 2c595e5..98b3c3b 100644 --- a/Marks/Views/BookmarkRow.swift +++ b/Marks/Views/BookmarkRow.swift @@ -55,10 +55,10 @@ struct BookmarkRow: View { } } - if let summary = bookmark.aiSummary { - Text(summary) + if let excerpt = rowExcerpt { + Text(excerpt.text) .font(.subheadline) - .italic() + .italic(excerpt.isAI) .foregroundStyle(.secondary) .lineLimit(2) .padding(.leading, 44) @@ -106,6 +106,18 @@ struct BookmarkRow: View { } } + /// Excerpt shown under the title: prefer the AI summary (italic), else the + /// page's scraped description / user note. nil hides the line entirely. + private var rowExcerpt: (text: String, isAI: Bool)? { + if let s = bookmark.aiSummary?.trimmingCharacters(in: .whitespacesAndNewlines), !s.isEmpty { + return (s, true) + } + if let e = bookmark.contentExcerpt { + return (e, false) + } + return nil + } + private var effectiveTags: [String] { let base = bookmark.tagNames let ai = bookmark.aiTags ?? []