diff --git a/src/components/Debug.tsx b/src/components/Debug.tsx index 63b585d4..a03835ab 100644 --- a/src/components/Debug.tsx +++ b/src/components/Debug.tsx @@ -8,6 +8,7 @@ import { Accounts } from 'applesauce-accounts' import { NostrConnectSigner } from 'applesauce-signers' import { RelayPool } from 'applesauce-relay' import { Helpers } from 'applesauce-core' +import { nip19 } from 'nostr-tools' import { getDefaultBunkerPermissions } from '../services/nostrConnect' import { DebugBus, type DebugLogEntry } from '../utils/debugBus' import ThreePaneLayout from './ThreePaneLayout' @@ -16,6 +17,9 @@ import type { NostrEvent } from '../services/bookmarkHelpers' import { Bookmark } from '../types/bookmarks' import { useBookmarksUI } from '../hooks/useBookmarksUI' import { useSettings } from '../hooks/useSettings' +import { fetchHighlights, fetchHighlightsFromAuthors } from '../services/highlightService' +import { fetchNostrverseHighlights } from '../services/nostrverseService' +import { fetchContacts } from '../services/contactService' const defaultPayload = 'The quick brown fox jumps over the lazy dog.' @@ -99,6 +103,10 @@ const Debug: React.FC = ({ decryptBookmarks?: { startTime: number } loadHighlights?: { startTime: number } }>({}) + + // Web of Trust state + const [friendsPubkeys, setFriendsPubkeys] = useState>(new Set()) + const [friendsLoading, setFriendsLoading] = useState(false) useEffect(() => { return DebugBus.subscribe((e) => setLogs(prev => [...prev, e].slice(-300))) @@ -420,6 +428,119 @@ const Debug: React.FC = ({ DebugBus.info('debug', 'Cleared highlight data') } + const handleLoadMyHighlights = async () => { + if (!relayPool || !activeAccount?.pubkey) { + DebugBus.warn('debug', 'Please log in to load your highlights') + return + } + const start = performance.now() + setHighlightEvents([]) + setIsLoadingHighlights(true) + setTLoadHighlights(null) + setTFirstHighlight(null) + DebugBus.info('debug', 'Loading my highlights...') + try { + let firstEventTime: number | null = null + await fetchHighlights(relayPool, activeAccount.pubkey, (h) => { + if (firstEventTime === null) { + firstEventTime = performance.now() - start + setTFirstHighlight(Math.round(firstEventTime)) + } + setHighlightEvents(prev => { + if (prev.some(x => x.id === h.id)) return prev + const next = [...prev, { ...h, pubkey: h.pubkey, created_at: h.created_at, id: h.id, kind: 9802, tags: [], content: h.content, sig: '' } as NostrEvent] + return next.sort((a, b) => b.created_at - a.created_at) + }) + }, settings) + } finally { + setIsLoadingHighlights(false) + const elapsed = Math.round(performance.now() - start) + setTLoadHighlights(elapsed) + DebugBus.info('debug', `Loaded my highlights in ${elapsed}ms`) + } + } + + const handleLoadFriendsHighlights = async () => { + if (!relayPool || !activeAccount?.pubkey) { + DebugBus.warn('debug', 'Please log in to load friends highlights') + return + } + const start = performance.now() + setHighlightEvents([]) + setIsLoadingHighlights(true) + setTLoadHighlights(null) + setTFirstHighlight(null) + DebugBus.info('debug', 'Loading friends highlights...') + try { + const contacts = await fetchContacts(relayPool, activeAccount.pubkey) + DebugBus.info('debug', `Found ${contacts.size} friends`) + let firstEventTime: number | null = null + await fetchHighlightsFromAuthors(relayPool, Array.from(contacts), (h) => { + if (firstEventTime === null) { + firstEventTime = performance.now() - start + setTFirstHighlight(Math.round(firstEventTime)) + } + setHighlightEvents(prev => { + if (prev.some(x => x.id === h.id)) return prev + const next = [...prev, { ...h, pubkey: h.pubkey, created_at: h.created_at, id: h.id, kind: 9802, tags: [], content: h.content, sig: '' } as NostrEvent] + return next.sort((a, b) => b.created_at - a.created_at) + }) + }) + } finally { + setIsLoadingHighlights(false) + const elapsed = Math.round(performance.now() - start) + setTLoadHighlights(elapsed) + DebugBus.info('debug', `Loaded friends highlights in ${elapsed}ms`) + } + } + + const handleLoadNostrverseHighlights = async () => { + if (!relayPool) { + DebugBus.warn('debug', 'Relay pool not available') + return + } + const start = performance.now() + setHighlightEvents([]) + setIsLoadingHighlights(true) + setTLoadHighlights(null) + setTFirstHighlight(null) + DebugBus.info('debug', 'Loading nostrverse highlights...') + try { + const all = await fetchNostrverseHighlights(relayPool, 100) + setHighlightEvents(all.map(h => ({ ...h, pubkey: h.pubkey, created_at: h.created_at, id: h.id, kind: 9802, tags: [], content: h.content, sig: '' } as NostrEvent))) + } finally { + setIsLoadingHighlights(false) + const elapsed = Math.round(performance.now() - start) + setTLoadHighlights(elapsed) + DebugBus.info('debug', `Loaded nostrverse highlights in ${elapsed}ms`) + } + } + + const handleLoadFriendsList = async () => { + if (!relayPool || !activeAccount?.pubkey) { + DebugBus.warn('debug', 'Please log in to load friends list') + return + } + setFriendsLoading(true) + setFriendsPubkeys(new Set()) + DebugBus.info('debug', 'Loading friends list...') + try { + const final = await fetchContacts( + relayPool, + activeAccount.pubkey, + (partial) => setFriendsPubkeys(new Set(partial)) + ) + setFriendsPubkeys(new Set(final)) + DebugBus.info('debug', `Loaded ${final.size} friends`) + } finally { + setFriendsLoading(false) + } + } + + const friendsNpubs = useMemo(() => { + return Array.from(friendsPubkeys).map(pk => nip19.npubEncode(pk)) + }, [friendsPubkeys]) + const handleBunkerLogin = async () => { if (!bunkerUri.trim()) { setBunkerError('Please enter a bunker URI') @@ -845,6 +966,31 @@ const Debug: React.FC = ({ +
Quick load options:
+
+ + + +
+
@@ -890,6 +1036,42 @@ const Debug: React.FC = ({ )}
+ {/* Web of Trust Section */} +
+

Web of Trust

+
Load your followed contacts (friends) for highlight fetching:
+ +
+ +
+ + {friendsPubkeys.size > 0 && ( +
+
Friends Count: {friendsNpubs.length}
+
+ {friendsNpubs.map(npub => ( +
+ {npub} +
+ ))} +
+
+ )} +
+ {/* Debug Logs Section */}

Debug Logs