diff --git a/src/lib/components/Notifications.svelte b/src/lib/components/Notifications.svelte index 062ecd4..1604532 100644 --- a/src/lib/components/Notifications.svelte +++ b/src/lib/components/Notifications.svelte @@ -17,6 +17,22 @@ const { event } = $props<{ event: NDKEvent }>(); + // Handle navigation events from quoted messages + $effect(() => { + if (typeof window !== 'undefined') { + const handleJumpToMessage = (e: Event) => { + const customEvent = e as CustomEvent; + jumpToMessageInFeed(customEvent.detail); + }; + + window.addEventListener('jump-to-message', handleJumpToMessage); + + return () => { + window.removeEventListener('jump-to-message', handleJumpToMessage); + }; + } + }); + // Component state let notifications = $state([]); let publicMessages = $state([]); @@ -76,7 +92,9 @@ function getNeventUrl(event: NDKEvent): string { const relays = getAvailableRelays(); - return neventEncode(event, relays); + const nevent = neventEncode(event, relays); + console.log('Generated nevent for event:', event.id, '→', nevent); + return nevent; } function formatDate(timestamp: number): string { @@ -97,15 +115,28 @@ } function renderContentWithLinks(content: string): string { - console.log("[Notifications] Rendering content:", content); - // Parse markdown links [text](url) and convert to HTML let rendered = content.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); - // Also handle the new quote format: "> LINK: nevent://..." and convert to button - rendered = rendered.replace(/> LINK: (nevent:\/\/[^\s\n]+)/g, '> '); + // Handle quote format and convert to small gray bars like Jumble + const patterns = [ + /> QUOTED: ([^•]*?) • LINK:\s*\n(nevent[^\s]*)/g, + /> QUOTED: ([^\n]*?)\n> LINK: (nevent[^\s]*)/g, + /> QUOTED: ([^•]*?) • LINK:\s*(nevent[^\s]*)/g, + ]; + + for (const pattern of patterns) { + const beforeReplace = rendered; + rendered = rendered.replace(pattern, (match, quotedText, neventUrl) => { + const encodedUrl = neventUrl.replace(/'/g, '''); + const cleanQuotedText = quotedText.trim(); + return `
${cleanQuotedText}
`; + }); + if (beforeReplace !== rendered) { + break; + } + } - console.log("[Notifications] Rendered content:", rendered); return rendered; } @@ -122,9 +153,43 @@ } function navigateToEvent(nevent: string) { + // Navigate to the events search page with this specific event goto(`/events?id=${nevent}`); } + function jumpToMessageInFeed(nevent: string) { + // Switch to public messages tab and scroll to the specific message + notificationMode = "public-messages"; + + // Try to find and scroll to the specific message + setTimeout(() => { + try { + // Decode the nevent to get the event ID + const decoded = nip19.decode(nevent); + if (decoded.type === 'nevent' && decoded.data.id) { + const eventId = decoded.data.id; + + // Find the message in our public messages + const targetMessage = publicMessages.find(msg => msg.id === eventId); + if (targetMessage) { + // Try to scroll to the element if it exists in the DOM + const element = document.querySelector(`[data-event-id="${eventId}"]`); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'center' }); + // Briefly highlight the message + element.classList.add('ring-2', 'ring-blue-500'); + setTimeout(() => { + element.classList.remove('ring-2', 'ring-blue-500'); + }, 2000); + } + } + } + } catch (error) { + console.warn('Failed to jump to message:', error); + } + }, 100); + } + function filterByUser(pubkey: string) { filteredByUser = filteredByUser === pubkey ? null : pubkey; } @@ -256,9 +321,7 @@ .filter(relay => replyRelaySet.has(relay)) .slice(0, 3); - console.log('[Notifications] Got relay set:', result); - console.log('[Notifications] Filtered sender outbox relays:', senderOutboxRelays); - console.log('[Notifications] Filtered recipient inbox relays:', recipientInboxRelays); + } } catch (error) { console.error("Error getting relay information:", error); @@ -545,7 +608,7 @@ {#each filteredMessages.slice(0, 20) as message} {@const authorProfile = authorProfiles.get(message.pubkey)} {@const isFromUser = message.pubkey === $userStore.pubkey} -
+
@@ -602,6 +665,13 @@ {message.created_at ? formatDate(message.created_at) : "Unknown date"} +
@@ -622,17 +692,7 @@
{/if} -
- - - {getNeventUrl(message).slice(0, 16)}... - -
+
@@ -676,7 +736,7 @@
{#if replyRelays.length > 0} - {@const debugInfo = console.log('[Notifications] Rendering RelayInfoList with:', { replyRelays, recipientInboxRelays, senderOutboxRelays })} + {notification.created_at ? formatDate(notification.created_at) : "Unknown date"} +
@@ -763,17 +830,7 @@ {/if} -
- - - {getNeventUrl(notification).slice(0, 16)}... - -
+ diff --git a/src/lib/components/RelayInfoList.svelte b/src/lib/components/RelayInfoList.svelte index 0443453..62d6b8b 100644 --- a/src/lib/components/RelayInfoList.svelte +++ b/src/lib/components/RelayInfoList.svelte @@ -25,18 +25,10 @@ label: string; }; - // AI-NOTE: Updated to show only top-3 inboxes and top-3 outboxes as intended + // Categorize relays by their function (inbox/outbox/both) const categorizedRelays = $derived(() => { const inbox = new Set(inboxRelays); const outbox = new Set(outboxRelays); - - console.log('[RelayInfoList] Categorizing relays:', { - relays: relays.length, - inboxRelays: inboxRelays.length, - outboxRelays: outboxRelays.length - }); - - // Create a map of all relays with their categories const relayCategories = new Map(); // Process inbox relays (up to top 3) @@ -58,29 +50,19 @@ } }); - // Only include relays that are actually in the top-3 lists - // This ensures we only show the intended top-3 inboxes and top-3 outboxes - const categorized = Array.from(relayCategories.values()); - console.log('[RelayInfoList] Categorized relays count:', categorized.length); - return categorized; + return Array.from(relayCategories.values()); }); - // Group by category + // Group by category for display const groupedRelays = $derived(() => { const categorized = categorizedRelays(); - console.log('[RelayInfoList] Grouping categorized relays'); - const groups = { + return { both: categorized.filter((r: CategorizedRelay) => r.category === 'both'), inbox: categorized.filter((r: CategorizedRelay) => r.category === 'inbox'), outbox: categorized.filter((r: CategorizedRelay) => r.category === 'outbox'), other: categorized.filter((r: CategorizedRelay) => r.category === 'other') }; - - console.log('[RelayInfoList] Grouped relays:', Object.fromEntries( - Object.entries(groups).map(([key, relays]) => [key, relays.length]) - )); - return groups; }); async function loadRelayInfos() { @@ -99,12 +81,6 @@ // Load relay info when categorized relays change $effect(() => { const categorized = categorizedRelays(); - console.log('[RelayInfoList] Categorized relays changed:', { - total: categorized.length, - byCategory: Object.fromEntries( - Object.entries(groupedRelays()).map(([key, relays]) => [key, relays.length]) - ) - }); if (categorized.length > 0) { loadRelayInfos(); } @@ -134,7 +110,6 @@
{#if showLabels && !compact} {@const categorizedCount = categorizedRelays().length} - {@const debugCategorized = console.log('[RelayInfoList] Debug - categorized relays:', categorizedRelays())}
Publishing to {categorizedCount} relay(s):
@@ -147,7 +122,6 @@
{:else} {@const categorized = categorizedRelays()} - {@const debugCategorized = console.log('[RelayInfoList] Debug - categorized relays:', categorized)}
{#each categorized as { relay, category, label }} diff --git a/src/lib/utils/kind24_utils.ts b/src/lib/utils/kind24_utils.ts index e3b6e14..62a27d0 100644 --- a/src/lib/utils/kind24_utils.ts +++ b/src/lib/utils/kind24_utils.ts @@ -13,7 +13,7 @@ import { nip19 } from "nostr-tools"; */ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise { try { - console.debug('[kind24_utils] Fetching outbox relays for user:', user.pubkey); + const relayList = await ndk.fetchEvent( { kinds: [10002], @@ -22,16 +22,11 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise { ); if (!relayList) { - console.debug('[kind24_utils] No relay list found for user'); return []; } - console.debug('[kind24_utils] Found relay list event:', relayList.id); - console.debug('[kind24_utils] Relay list tags:', relayList.tags); - const outboxRelays: string[] = []; relayList.tags.forEach((tag) => { - console.debug('[kind24_utils] Processing tag:', tag); if (tag[0] === 'r' && tag[1]) { // NIP-65: r tags with optional inbox/outbox markers const marker = tag[2]; @@ -39,15 +34,15 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise { // If no marker or marker is 'outbox', it's a outbox relay // If marker is 'inbox', it's also a outbox relay (NIP-65 allows both) outboxRelays.push(tag[1]); - console.debug('[kind24_utils] Added outbox relay:', tag[1]); + } } }); - console.debug('[kind24_utils] Final outbox relays:', outboxRelays); + return outboxRelays; } catch (error) { - console.info('[kind24_utils] Error fetching user outbox relays:', error); + return []; } } @@ -60,7 +55,7 @@ async function getUseroutboxRelays(ndk: NDK, user: NDKUser): Promise { */ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise { try { - console.debug('[kind24_utils] Fetching inbox relays for user:', user.pubkey); + const relayList = await ndk.fetchEvent( { kinds: [10002], @@ -69,16 +64,11 @@ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise { ); if (!relayList) { - console.debug('[kind24_utils] No relay list found for user'); return []; } - console.debug('[kind24_utils] Found relay list event:', relayList.id); - console.debug('[kind24_utils] Relay list tags:', relayList.tags); - const inboxRelays: string[] = []; relayList.tags.forEach((tag) => { - console.debug('[kind24_utils] Processing tag:', tag); if (tag[0] === 'r' && tag[1]) { // NIP-65: r tags with optional inbox/outbox markers const marker = tag[2]; @@ -86,15 +76,15 @@ async function getUserinboxRelays(ndk: NDK, user: NDKUser): Promise { // If no marker or marker is 'inbox', it's a inbox relay // If marker is 'outbox', it's also a inbox relay (NIP-65 allows both) inboxRelays.push(tag[1]); - console.debug('[kind24_utils] Added inbox relay:', tag[1]); + } } }); - console.debug('[kind24_utils] Final inbox relays:', inboxRelays); + return inboxRelays; } catch (error) { - console.info('[kind24_utils] Error fetching user inbox relays:', error); + return []; } } @@ -165,7 +155,7 @@ export async function createKind24Reply( const quotedContent = originalEvent.content ? originalEvent.content.slice(0, 200) : "No content"; // Use a more visible quote format with a clickable link finalContent = `> QUOTED: ${quotedContent}\n> LINK: ${nevent}\n\n${content}`; - console.log("[kind24_utils] Reply content:", finalContent); + } event.content = finalContent;