From 583c2651b68ad29f4c335bd004fa0c7dfa8f25b3 Mon Sep 17 00:00:00 2001 From: MaheshtheDev <38828053+MaheshtheDev@users.noreply.github.com> Date: Sat, 4 Oct 2025 21:38:13 +0000 Subject: [PATCH] feat: url cards as content preview with rich details (#452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improved memory detail UI with better document icons and layout and Added dark mode support to the Chrome extension button ### What changed? - Enhanced the WebsiteCard component with an `onOpenDetails` prop - Improved the MemoryDetail component with: - Better layout for document headers and source links - Enhanced content scrolling with proper height constraints - Improved spacing and padding in various sections - Added favicon support to document icons, showing website favicons for webpage documents - Fixed document type detection for webpages and URLs - Added dark mode support to the Chrome extension button component with appropriate color classes [Screen Recording 2025-10-03 at 11.34.01 PM.mov (uploaded via Graphite) ](https://app.graphite.dev/user-attachments/video/2f6ceef2-43a2-4e11-bafa-0f3ce614696b.mov) --- .../components/chrome-extension-button.tsx | 28 +-- apps/web/components/content-cards/website.tsx | 4 + apps/web/components/header.tsx | 6 +- apps/web/components/masonry-memory-list.tsx | 1 + .../memories-utils/memory-detail.tsx | 52 +++--- apps/web/components/memory-list-view.tsx | 5 +- apps/web/lib/document-icon.tsx | 176 ++++++++++++------ 7 files changed, 168 insertions(+), 104 deletions(-) diff --git a/apps/web/components/chrome-extension-button.tsx b/apps/web/components/chrome-extension-button.tsx index 5fd58cac..2b2ca713 100644 --- a/apps/web/components/chrome-extension-button.tsx +++ b/apps/web/components/chrome-extension-button.tsx @@ -130,42 +130,42 @@ export function ChromeExtensionButton() {
-
- +
+
-

+

Twitter Imports

-

+

Import your twitter timeline & save tweets.

-
- +
+
-

+

Save All Bookmarks

-

+

Instantly save any webpage to your memory.

-
- +
+
-

+

Charge Empty Memory

-

+

Automatically capture & organize your browsing history.

@@ -175,7 +175,7 @@ export function ChromeExtensionButton() {
- - )}
+ {document.url && ( +
+ +
+ )}
) @@ -227,10 +229,10 @@ export const MemoryDetail = memo(
{activeMemories.length > 0 && (
-
+
Active Memories ({activeMemories.length})
-
+
{activeMemories.map((memory) => (
@@ -281,7 +283,7 @@ export const MemoryDetail = memo( Content
-
+
@@ -324,8 +326,8 @@ export const MemoryDetail = memo(
-
-

+
+

Content

@@ -370,9 +372,9 @@ export const MemoryDetail = memo(

-
+
-
+
diff --git a/apps/web/components/memory-list-view.tsx b/apps/web/components/memory-list-view.tsx index c2b4b0c8..02667147 100644 --- a/apps/web/components/memory-list-view.tsx +++ b/apps/web/components/memory-list-view.tsx @@ -294,10 +294,7 @@ export const MemoryListView = ({ // Always render with consistent structure return ( <> -
+
{error ? (
diff --git a/apps/web/lib/document-icon.tsx b/apps/web/lib/document-icon.tsx index a0f56e63..edeaf76b 100644 --- a/apps/web/lib/document-icon.tsx +++ b/apps/web/lib/document-icon.tsx @@ -1,59 +1,119 @@ -import { MCPIcon } from '@/components/menu'; -import { colors } from '@repo/ui/memory-graph/constants'; +import { MCPIcon } from "@/components/menu" +import { colors } from "@repo/ui/memory-graph/constants" import { - GoogleDocs, - MicrosoftWord, - NotionDoc, - GoogleDrive, - GoogleSheets, - GoogleSlides, - PDF, - OneDrive, - MicrosoftOneNote, - MicrosoftPowerpoint, - MicrosoftExcel, -} from '@ui/assets/icons'; -import { FileText } from 'lucide-react'; - -export const getDocumentIcon = (type: string, className: string, source?: string) => { - const iconProps = { - className, - style: { color: colors.text.muted }, - }; - - if(source === "mcp") { - return ; - } - - switch (type) { - case 'google_doc': - return ; - case 'google_sheet': - return ; - case 'google_slide': - return ; - case 'google_drive': - return ; - case 'notion': - case 'notion_doc': - return ; - case 'word': - case 'microsoft_word': - return ; - case 'excel': - case 'microsoft_excel': - return ; - case 'powerpoint': - case 'microsoft_powerpoint': - return ; - case 'onenote': - case 'microsoft_onenote': - return ; - case 'onedrive': - return ; - case 'pdf': - return ; - default: - return ; - } -}; + GoogleDocs, + MicrosoftWord, + NotionDoc, + GoogleDrive, + GoogleSheets, + GoogleSlides, + PDF, + OneDrive, + MicrosoftOneNote, + MicrosoftPowerpoint, + MicrosoftExcel, +} from "@ui/assets/icons" +import { FileText, Globe } from "lucide-react" +import { useState } from "react" + +const getFaviconUrl = (url: string): string => { + try { + const domain = new URL(url).hostname + return `https://www.google.com/s2/favicons?domain=${domain}&sz=32` + } catch { + return "" + } +} + +const FaviconIcon = ({ + url, + className, + iconProps, +}: { + url: string + className: string + iconProps: { className: string; style: { color: string } } +}) => { + const [hasError, setHasError] = useState(false) + const faviconUrl = getFaviconUrl(url) + + if (hasError || !faviconUrl) { + return + } + + return ( + Website favicon setHasError(true)} + /> + ) +} + +export const getDocumentIcon = ( + type: string, + className: string, + source?: string, + url?: string, +) => { + const iconProps = { + className, + style: { color: colors.text.muted }, + } + + if (source === "mcp") { + return + } + + if ( + type === "webpage" || + type === "url" || + (url && (type === "unknown" || !type)) + ) { + if (url) { + return ( + + ) + } + + return + } + + switch (type) { + case "google_doc": + return + case "google_sheet": + return + case "google_slide": + return + case "google_drive": + return + case "notion": + case "notion_doc": + return + case "word": + case "microsoft_word": + return + case "excel": + case "microsoft_excel": + return + case "powerpoint": + case "microsoft_powerpoint": + return + case "onenote": + case "microsoft_onenote": + return + case "onedrive": + return + case "pdf": + return + default: + return + } +}