diff --git a/src/components/KindBadge.tsx b/src/components/KindBadge.tsx index 6e71c0d..1ab0857 100644 --- a/src/components/KindBadge.tsx +++ b/src/components/KindBadge.tsx @@ -28,7 +28,7 @@ export function KindBadge({ const Icon = kindInfo?.icon; const style = "inline-flex items-center gap-2 text-foreground"; - const interactiveStyle = clickable ? "cursor-pointer" : ""; + const interactiveStyle = clickable ? "cursor-crosshair" : ""; const handleClick = () => { if (clickable) { diff --git a/src/components/nostr/kinds/Kind9802Renderer.tsx b/src/components/nostr/kinds/Kind9802Renderer.tsx index b054d8e..315752d 100644 --- a/src/components/nostr/kinds/Kind9802Renderer.tsx +++ b/src/components/nostr/kinds/Kind9802Renderer.tsx @@ -5,17 +5,63 @@ import { getHighlightText, getHighlightSourceUrl, getHighlightComment, + getHighlightSourceEventPointer, + getHighlightSourceAddressPointer, } from "applesauce-core/helpers/highlight"; +import { UserName } from "../UserName"; +import { useNostrEvent } from "@/hooks/useNostrEvent"; +import { useGrimoire } from "@/core/state"; +import { RichText } from "../RichText"; +import { getArticleTitle } from "applesauce-core/helpers"; +import { KindBadge } from "@/components/KindBadge"; /** * Renderer for Kind 9802 - Highlight - * Displays highlighted text with optional comment and source URL + * Displays highlighted text with optional comment, compact source event preview, and source URL */ export function Kind9802Renderer({ event }: BaseEventProps) { + const { addWindow } = useGrimoire(); const highlightText = useMemo(() => getHighlightText(event), [event]); const sourceUrl = useMemo(() => getHighlightSourceUrl(event), [event]); const comment = useMemo(() => getHighlightComment(event), [event]); + // Get source event pointer (e tag) or address pointer (a tag) for Nostr event references + const eventPointer = useMemo( + () => getHighlightSourceEventPointer(event), + [event], + ); + const addressPointer = useMemo( + () => getHighlightSourceAddressPointer(event), + [event], + ); + + // Load the source event for preview + const sourceEvent = useNostrEvent(eventPointer || addressPointer); + + // Extract title or content preview from source event + const sourcePreview = useMemo(() => { + if (!sourceEvent) return null; + + const title = getArticleTitle(sourceEvent); + if (title) return title; + + // Fall back to content + return sourceEvent.content || null; + }, [sourceEvent]); + + // Handle click to open source event + const handleOpenEvent = () => { + if (eventPointer?.id) { + addWindow( + "open", + { pointer: eventPointer }, + `Event ${eventPointer.id.slice(0, 8)}...`, + ); + } else if (addressPointer) { + addWindow("open", { pointer: addressPointer }, `Event`); + } + }; + return (
@@ -29,8 +75,35 @@ export function Kind9802Renderer({ event }: BaseEventProps) { )} - {/* Source URL */} - {sourceUrl && ( + {/* Compact Source Event Preview - Clickable link with icon, author, and title/content */} + {sourceEvent && (eventPointer || addressPointer) && ( +
+ + + + + {/* Title or Content Preview */} + {sourcePreview && ( +
+ +
+ )} +
+ )} + + {/* Source URL - Show for external websites (non-Nostr sources) */} + {sourceUrl && !eventPointer && !addressPointer && (