debug: add comprehensive logging for profile loading states and article refresh

- Add logs to useProfileLabels for loading state tracking
- Add logs to markdown processing to track when content is cleared/reprocessed
- Add logs to article loader for refresh behavior
- Add logs to ResolvedMention and NostrMentionLink for loading detection
- Add logs to nostr URI resolver when loading state is shown
- All logs prefixed with meaningful tags for easy filtering
This commit is contained in:
Gigi
2025-11-02 22:39:07 +01:00
parent 7e5972a6e2
commit 51a4b545e9
6 changed files with 45 additions and 6 deletions

View File

@@ -45,15 +45,25 @@ const NostrMentionLink: React.FC<NostrMentionLinkProps> = ({
if (!pubkey) return false if (!pubkey) return false
// Check cache // Check cache
const cached = loadCachedProfiles([pubkey]) const cached = loadCachedProfiles([pubkey])
if (cached.has(pubkey)) return true if (cached.has(pubkey)) {
console.log(`[nostr-mention-link] ${nostrUri.slice(0, 30)}... in cache`)
return true
}
// Check eventStore // Check eventStore
const eventStoreProfile = eventStore?.getEvent(pubkey + ':0') const eventStoreProfile = eventStore?.getEvent(pubkey + ':0')
return !!eventStoreProfile const inStore = !!eventStoreProfile
}, [pubkey, eventStore]) if (inStore) {
console.log(`[nostr-mention-link] ${nostrUri.slice(0, 30)}... in eventStore`)
}
return inStore
}, [pubkey, eventStore, nostrUri])
// Show loading if profile doesn't exist and not in cache/store (for npub/nprofile) // Show loading if profile doesn't exist and not in cache/store (for npub/nprofile)
const isLoading = !profile && pubkey && !isInCacheOrStore && const isLoading = !profile && pubkey && !isInCacheOrStore &&
decoded && (decoded.type === 'npub' || decoded.type === 'nprofile') decoded && (decoded.type === 'npub' || decoded.type === 'nprofile')
if (isLoading) {
console.log(`[nostr-mention-link] ${nostrUri.slice(0, 30)}... isLoading=true (profile=${!!profile}, pubkey=${!!pubkey}, inCacheOrStore=${isInCacheOrStore})`)
}
// If decoding failed, show shortened identifier // If decoding failed, show shortened identifier
if (!decoded) { if (!decoded) {

View File

@@ -30,14 +30,24 @@ const ResolvedMention: React.FC<ResolvedMentionProps> = ({ encoded }) => {
if (!pubkey) return false if (!pubkey) return false
// Check cache // Check cache
const cached = loadCachedProfiles([pubkey]) const cached = loadCachedProfiles([pubkey])
if (cached.has(pubkey)) return true if (cached.has(pubkey)) {
console.log(`[resolved-mention] ${encoded?.slice(0, 16)}... in cache`)
return true
}
// Check eventStore // Check eventStore
const eventStoreProfile = eventStore?.getEvent(pubkey + ':0') const eventStoreProfile = eventStore?.getEvent(pubkey + ':0')
return !!eventStoreProfile const inStore = !!eventStoreProfile
}, [pubkey, eventStore]) if (inStore) {
console.log(`[resolved-mention] ${encoded?.slice(0, 16)}... in eventStore`)
}
return inStore
}, [pubkey, eventStore, encoded])
// Show loading if profile doesn't exist and not in cache/store // Show loading if profile doesn't exist and not in cache/store
const isLoading = !profile && pubkey && !isInCacheOrStore const isLoading = !profile && pubkey && !isInCacheOrStore
if (isLoading && encoded) {
console.log(`[resolved-mention] ${encoded.slice(0, 16)}... isLoading=true (profile=${!!profile}, pubkey=${!!pubkey}, inCacheOrStore=${isInCacheOrStore})`)
}
const display = pubkey ? getProfileDisplayName(profile, pubkey) : encoded const display = pubkey ? getProfileDisplayName(profile, pubkey) : encoded
const npub = pubkey ? npubEncode(pubkey) : undefined const npub = pubkey ? npubEncode(pubkey) : undefined

View File

@@ -264,8 +264,10 @@ export function useArticleLoader({
const loadArticle = async () => { const loadArticle = async () => {
const requestId = ++currentRequestIdRef.current const requestId = ++currentRequestIdRef.current
console.log(`[article-loader] Starting loadArticle requestId=${requestId} for naddr=${naddr.slice(0, 20)}...`)
if (!mountedRef.current) { if (!mountedRef.current) {
console.log(`[article-loader] Aborted loadArticle requestId=${requestId} - not mounted`)
return return
} }
@@ -282,6 +284,7 @@ export function useArticleLoader({
// At this point, we've checked EventStore and cache - neither had content // At this point, we've checked EventStore and cache - neither had content
// Only show loading skeleton if we also don't have preview data // Only show loading skeleton if we also don't have preview data
if (previewData) { if (previewData) {
console.log(`[article-loader] requestId=${requestId} has previewData, showing immediately`)
// If we have preview data from navigation, show it immediately (no skeleton!) // If we have preview data from navigation, show it immediately (no skeleton!)
setCurrentTitle(previewData.title) setCurrentTitle(previewData.title)
setReaderContent({ setReaderContent({
@@ -298,6 +301,7 @@ export function useArticleLoader({
// Preloading again would be redundant and could cause unnecessary network requests // Preloading again would be redundant and could cause unnecessary network requests
} else { } else {
// No cache, no EventStore, no preview data - need to load from relays // No cache, no EventStore, no preview data - need to load from relays
console.log(`[article-loader] requestId=${requestId} no previewData, setting loading=true, content=undefined`)
setReaderLoading(true) setReaderLoading(true)
setReaderContent(undefined) setReaderContent(undefined)
} }

View File

@@ -56,6 +56,8 @@ export const useMarkdownToHTML = (
// Process markdown with progressive profile labels and article titles // Process markdown with progressive profile labels and article titles
useEffect(() => { useEffect(() => {
console.log(`[markdown-to-html] Processing markdown, profileLabels=${profileLabels.size}, profileLoading=${profileLoading.size}, articleTitles=${articleTitles.size}`)
console.log(`[markdown-to-html] Clearing rendered HTML and processed markdown`)
// Always clear previous render immediately to avoid showing stale content while processing // Always clear previous render immediately to avoid showing stale content while processing
setRenderedHtml('') setRenderedHtml('')
setProcessedMarkdown('') setProcessedMarkdown('')
@@ -78,6 +80,7 @@ export const useMarkdownToHTML = (
if (isCancelled) return if (isCancelled) return
console.log(`[markdown-to-html] Processed markdown, loading states:`, Array.from(profileLoading.entries()).filter(([_, l]) => l).map(([e, _]) => e.slice(0, 16) + '...'))
setProcessedMarkdown(processed) setProcessedMarkdown(processed)
} catch (error) { } catch (error) {
console.error(`[markdown-to-html] Error processing markdown:`, error) console.error(`[markdown-to-html] Error processing markdown:`, error)

View File

@@ -207,6 +207,7 @@ export function useProfileLabels(
// Skip if already resolved from initial cache // Skip if already resolved from initial cache
if (labels.has(encoded)) { if (labels.has(encoded)) {
loading.set(encoded, false) loading.set(encoded, false)
console.log(`[profile-labels-loading] ${encoded.slice(0, 16)}... in cache, not loading`)
return return
} }
@@ -226,12 +227,14 @@ export function useProfileLabels(
labels.set(encoded, fallback) labels.set(encoded, fallback)
} }
loading.set(encoded, false) loading.set(encoded, false)
console.log(`[profile-labels-loading] ${encoded.slice(0, 16)}... in eventStore, not loading`)
} else { } else {
// No profile found yet, will use fallback after fetch or keep empty // No profile found yet, will use fallback after fetch or keep empty
// We'll set fallback labels for missing profiles at the end // We'll set fallback labels for missing profiles at the end
// Mark as loading since we'll fetch it // Mark as loading since we'll fetch it
pubkeysToFetch.push(pubkey) pubkeysToFetch.push(pubkey)
loading.set(encoded, true) loading.set(encoded, true)
console.log(`[profile-labels-loading] ${encoded.slice(0, 16)}... not found, SET LOADING=true`)
} }
}) })
@@ -245,9 +248,11 @@ export function useProfileLabels(
setProfileLabels(new Map(labels)) setProfileLabels(new Map(labels))
setProfileLoading(new Map(loading)) setProfileLoading(new Map(loading))
console.log(`[profile-labels-loading] Initial loading state:`, Array.from(loading.entries()).map(([e, l]) => `${e.slice(0, 16)}...=${l}`))
// Fetch missing profiles asynchronously with reactive updates // Fetch missing profiles asynchronously with reactive updates
if (pubkeysToFetch.length > 0 && relayPool && eventStore) { if (pubkeysToFetch.length > 0 && relayPool && eventStore) {
console.log(`[profile-labels-loading] Starting fetch for ${pubkeysToFetch.length} profiles:`, pubkeysToFetch.map(p => p.slice(0, 16) + '...'))
const pubkeysToFetchSet = new Set(pubkeysToFetch) const pubkeysToFetchSet = new Set(pubkeysToFetch)
// Create a map from pubkey to encoded identifier for quick lookup // Create a map from pubkey to encoded identifier for quick lookup
const pubkeyToEncoded = new Map<string, string>() const pubkeyToEncoded = new Map<string, string>()
@@ -274,6 +279,7 @@ export function useProfileLabels(
scheduleBatchedUpdate() scheduleBatchedUpdate()
// Clear loading state for this profile when it resolves // Clear loading state for this profile when it resolves
console.log(`[profile-labels-loading] Profile resolved for ${encoded.slice(0, 16)}..., CLEARING LOADING`)
setProfileLoading(prevLoading => { setProfileLoading(prevLoading => {
const updated = new Map(prevLoading) const updated = new Map(prevLoading)
updated.set(encoded, false) updated.set(encoded, false)
@@ -288,12 +294,17 @@ export function useProfileLabels(
applyPendingUpdates() applyPendingUpdates()
// Clear loading state for all fetched profiles // Clear loading state for all fetched profiles
console.log(`[profile-labels-loading] Fetch complete, clearing loading for all ${pubkeysToFetch.length} profiles`)
setProfileLoading(prevLoading => { setProfileLoading(prevLoading => {
const updated = new Map(prevLoading) const updated = new Map(prevLoading)
pubkeysToFetch.forEach(pubkey => { pubkeysToFetch.forEach(pubkey => {
const encoded = pubkeyToEncoded.get(pubkey) const encoded = pubkeyToEncoded.get(pubkey)
if (encoded) { if (encoded) {
const wasLoading = updated.get(encoded)
updated.set(encoded, false) updated.set(encoded, false)
if (wasLoading) {
console.log(`[profile-labels-loading] ${encoded.slice(0, 16)}... CLEARED loading after fetch complete`)
}
} }
}) })
return updated return updated

View File

@@ -340,6 +340,7 @@ export function replaceNostrUrisInMarkdownWithProfileLabels(
// For npub/nprofile, check if loading and show loading state // For npub/nprofile, check if loading and show loading state
if ((decoded.type === 'npub' || decoded.type === 'nprofile') && profileLoading.has(encoded) && profileLoading.get(encoded)) { if ((decoded.type === 'npub' || decoded.type === 'nprofile') && profileLoading.has(encoded) && profileLoading.get(encoded)) {
const label = getNostrUriLabel(encoded) const label = getNostrUriLabel(encoded)
console.log(`[nostr-uri-resolve] ${encoded.slice(0, 16)}... is LOADING, showing loading state`)
// Wrap in span with profile-loading class for CSS styling // Wrap in span with profile-loading class for CSS styling
return `[<span class="profile-loading">${label}</span>](${link})` return `[<span class="profile-loading">${label}</span>](${link})`
} }