diff --git a/src/components/NostrMentionLink.tsx b/src/components/NostrMentionLink.tsx index f7788f56..6c765435 100644 --- a/src/components/NostrMentionLink.tsx +++ b/src/components/NostrMentionLink.tsx @@ -46,24 +46,16 @@ const NostrMentionLink: React.FC = ({ // Check cache const cached = loadCachedProfiles([pubkey]) if (cached.has(pubkey)) { - console.log(`[profile-loading-debug][nostr-mention-link] ${nostrUri.slice(0, 30)}... in cache`) return true } // Check eventStore const eventStoreProfile = eventStore?.getEvent(pubkey + ':0') - const inStore = !!eventStoreProfile - if (inStore) { - console.log(`[profile-loading-debug][nostr-mention-link] ${nostrUri.slice(0, 30)}... in eventStore`) - } - return inStore - }, [pubkey, eventStore, nostrUri]) + return !!eventStoreProfile + }, [pubkey, eventStore]) // Show loading if profile doesn't exist and not in cache/store (for npub/nprofile) const isLoading = !profile && pubkey && !isInCacheOrStore && decoded && (decoded.type === 'npub' || decoded.type === 'nprofile') - if (isLoading) { - console.log(`[profile-loading-debug][nostr-mention-link] ${nostrUri.slice(0, 30)}... isLoading=true (profile=${!!profile}, pubkey=${!!pubkey}, inCacheOrStore=${isInCacheOrStore})`) - } // If decoding failed, show shortened identifier if (!decoded) { diff --git a/src/components/ResolvedMention.tsx b/src/components/ResolvedMention.tsx index d8fee2b3..37c96b63 100644 --- a/src/components/ResolvedMention.tsx +++ b/src/components/ResolvedMention.tsx @@ -31,23 +31,15 @@ const ResolvedMention: React.FC = ({ encoded }) => { // Check cache const cached = loadCachedProfiles([pubkey]) if (cached.has(pubkey)) { - console.log(`[profile-loading-debug][resolved-mention] ${encoded?.slice(0, 16)}... in cache`) return true } // Check eventStore const eventStoreProfile = eventStore?.getEvent(pubkey + ':0') - const inStore = !!eventStoreProfile - if (inStore) { - console.log(`[profile-loading-debug][resolved-mention] ${encoded?.slice(0, 16)}... in eventStore`) - } - return inStore - }, [pubkey, eventStore, encoded]) + return !!eventStoreProfile + }, [pubkey, eventStore]) // Show loading if profile doesn't exist and not in cache/store const isLoading = !profile && pubkey && !isInCacheOrStore - if (isLoading && encoded) { - console.log(`[profile-loading-debug][resolved-mention] ${encoded.slice(0, 16)}... isLoading=true (profile=${!!profile}, pubkey=${!!pubkey}, inCacheOrStore=${isInCacheOrStore})`) - } const display = pubkey ? getProfileDisplayName(profile, pubkey) : encoded const npub = pubkey ? npubEncode(pubkey) : undefined diff --git a/src/hooks/useArticleLoader.ts b/src/hooks/useArticleLoader.ts index a5e090d3..49a8abe2 100644 --- a/src/hooks/useArticleLoader.ts +++ b/src/hooks/useArticleLoader.ts @@ -264,10 +264,8 @@ export function useArticleLoader({ const loadArticle = async () => { const requestId = ++currentRequestIdRef.current - console.log(`[profile-loading-debug][article-loader] Starting loadArticle requestId=${requestId} for naddr=${naddr.slice(0, 20)}...`) if (!mountedRef.current) { - console.log(`[profile-loading-debug][article-loader] Aborted loadArticle requestId=${requestId} - not mounted`) return } @@ -284,7 +282,6 @@ export function useArticleLoader({ // At this point, we've checked EventStore and cache - neither had content // Only show loading skeleton if we also don't have preview data if (previewData) { - console.log(`[profile-loading-debug][article-loader] requestId=${requestId} has previewData, showing immediately`) // If we have preview data from navigation, show it immediately (no skeleton!) setCurrentTitle(previewData.title) setReaderContent({ @@ -301,7 +298,6 @@ export function useArticleLoader({ // Preloading again would be redundant and could cause unnecessary network requests } else { // No cache, no EventStore, no preview data - need to load from relays - console.log(`[profile-loading-debug][article-loader] requestId=${requestId} no previewData, setting loading=true, content=undefined`) setReaderLoading(true) setReaderContent(undefined) } diff --git a/src/hooks/useMarkdownToHTML.ts b/src/hooks/useMarkdownToHTML.ts index b8320a01..f32df3b4 100644 --- a/src/hooks/useMarkdownToHTML.ts +++ b/src/hooks/useMarkdownToHTML.ts @@ -28,10 +28,6 @@ export const useMarkdownToHTML = ( // This prevents unnecessary reprocessing when Maps are recreated with same content const profileLabelsKey = useMemo(() => { const key = Array.from(profileLabels.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${k}:${v}`).join('|') - console.log(`[shimmer-debug][markdown-to-html] profileLabelsKey computed, profileLabels.size=${profileLabels.size}, key length=${key.length}`) - if (profileLabels.size > 0) { - console.log(`[shimmer-debug][markdown-to-html] Profile labels in key:`, Array.from(profileLabels.entries()).slice(0, 3).map(([k, v]) => `${k.slice(0, 16)}...="${v}"`)) - } return key }, [profileLabels]) @@ -102,11 +98,6 @@ export const useMarkdownToHTML = ( // Process markdown with progressive profile labels and article titles // Use stable string keys instead of Map objects to prevent excessive reprocessing useEffect(() => { - const labelsSize = profileLabelsRef.current.size - const loadingSize = profileLoadingRef.current.size - const titlesSize = articleTitlesRef.current.size - console.log(`[profile-loading-debug][markdown-to-html] Processing markdown, profileLabels=${labelsSize}, profileLoading=${loadingSize}, articleTitles=${titlesSize}`) - if (!markdown) { setRenderedHtml('') setProcessedMarkdown('') @@ -130,11 +121,6 @@ export const useMarkdownToHTML = ( if (isCancelled) return - const loadingStates = Array.from(profileLoadingRef.current.entries()) - .filter(([, l]) => l) - .map(([e]) => e.slice(0, 16) + '...') - console.log(`[profile-loading-debug][markdown-to-html] Processed markdown, loading states:`, loadingStates) - console.log(`[shimmer-debug][markdown-to-html] Setting processedMarkdown, length=${processed.length}`) setProcessedMarkdown(processed) processedMarkdownRef.current = processed // HTML extraction will happen in separate useEffect that watches processedMarkdown @@ -153,7 +139,6 @@ export const useMarkdownToHTML = ( previousMarkdownRef.current = markdown if (isMarkdownChange || !processedMarkdownRef.current) { - console.log(`[profile-loading-debug][markdown-to-html] Clearing rendered HTML and processed markdown (markdown changed: ${isMarkdownChange})`) setRenderedHtml('') setProcessedMarkdown('') processedMarkdownRef.current = '' @@ -175,8 +160,6 @@ export const useMarkdownToHTML = ( let isCancelled = false - console.log(`[shimmer-debug][markdown-to-html] processedMarkdown changed, scheduling HTML extraction`) - // Use double RAF to ensure ReactMarkdown has finished rendering: // First RAF: let React complete its render cycle // Second RAF: extract HTML after DOM has updated @@ -184,30 +167,10 @@ export const useMarkdownToHTML = ( htmlExtractionRafIdRef.current = requestAnimationFrame(() => { if (previewRef.current && !isCancelled) { let html = previewRef.current.innerHTML - console.log(`[shimmer-debug][markdown-to-html] Extracted HTML after processedMarkdown change, length=${html.length}, loading profiles=${profileLoadingRef.current.size}`) - - // Check if HTML actually contains the updated content by looking for resolved names - const hasResolvedNames = Array.from(profileLabelsRef.current.entries()).some(([, label]) => { - // Check if label is a resolved name (starts with @ and isn't a fallback npub) - return label.startsWith('@') && !label.startsWith('@npub') && html.includes(label) - }) - console.log(`[shimmer-debug][markdown-to-html] HTML contains resolved names: ${hasResolvedNames}`) - - if (html.length === 0) { - console.log(`[shimmer-debug][markdown-to-html] Warning: HTML is empty, ReactMarkdown may not have rendered yet`) - } // Post-process HTML to add loading class to profile links - const htmlBefore = html html = addLoadingClassToProfileLinks(html, profileLoadingRef.current) - if (html !== htmlBefore) { - console.log(`[shimmer-debug][markdown-to-html] HTML changed after post-processing`) - // Count how many profile-loading classes are in the HTML - const loadingClassCount = (html.match(/profile-loading/g) || []).length - console.log(`[shimmer-debug][markdown-to-html] Found ${loadingClassCount} profile-loading classes in final HTML`) - } - setRenderedHtml(html) } else if (!isCancelled && processedMarkdown) { console.warn('⚠️ markdownPreviewRef.current is null but processedMarkdown exists') diff --git a/src/hooks/useProfileLabels.ts b/src/hooks/useProfileLabels.ts index 5bedb7d6..0806b4dc 100644 --- a/src/hooks/useProfileLabels.ts +++ b/src/hooks/useProfileLabels.ts @@ -89,9 +89,7 @@ export function useProfileLabels( */ const applyPendingUpdates = () => { const pendingUpdates = pendingUpdatesRef.current - console.log(`[shimmer-debug][profile-labels] applyPendingUpdates called, pendingUpdates.size=${pendingUpdates.size}`) if (pendingUpdates.size === 0) { - console.log(`[shimmer-debug][profile-labels] No pending updates to apply`) return } @@ -104,13 +102,9 @@ export function useProfileLabels( // Apply all pending updates in one batch setProfileLabels(prevLabels => { const updatedLabels = new Map(prevLabels) - const updatesList: string[] = [] for (const [pubkey, label] of pendingUpdates.entries()) { updatedLabels.set(pubkey, label) - updatesList.push(`${pubkey.slice(0, 16)}...="${label}"`) } - console.log(`[shimmer-debug][profile-labels] Applying ${updatesList.length} pending updates:`, updatesList) - console.log(`[shimmer-debug][profile-labels] Profile labels before: ${prevLabels.size}, after: ${updatedLabels.size}`) pendingUpdates.clear() return updatedLabels }) @@ -123,14 +117,10 @@ export function useProfileLabels( */ const scheduleBatchedUpdate = useCallback(() => { if (rafScheduledRef.current === null) { - console.log(`[shimmer-debug][profile-labels] Scheduling batched update via RAF`) rafScheduledRef.current = requestAnimationFrame(() => { - console.log(`[shimmer-debug][profile-labels] RAF fired, calling applyPendingUpdates`) applyPendingUpdates() rafScheduledRef.current = null }) - } else { - console.log(`[shimmer-debug][profile-labels] RAF already scheduled, skipping`) } }, []) // Empty deps: only uses refs which are stable @@ -142,15 +132,12 @@ export function useProfileLabels( const currentPubkeys = new Set(Array.from(prevLabels.keys())) const newPubkeys = new Set(profileData.map(p => p.pubkey)) - console.log(`[shimmer-debug][profile-labels] useEffect sync: prevLabels.size=${prevLabels.size}, initialLabels.size=${initialLabels.size}, profileData.length=${profileData.length}`) - // If the content changed significantly (different set of profiles), reset state const hasDifferentProfiles = currentPubkeys.size !== newPubkeys.size || !Array.from(newPubkeys).every(pk => currentPubkeys.has(pk)) if (hasDifferentProfiles) { - console.log(`[shimmer-debug][profile-labels] useEffect: Different profiles detected, resetting state`) // Clear pending updates and cancel RAF for old profiles pendingUpdatesRef.current.clear() if (rafScheduledRef.current !== null) { @@ -170,7 +157,6 @@ export function useProfileLabels( merged.set(pubkey, label) } } - console.log(`[shimmer-debug][profile-labels] useEffect: Merged labels, before=${prevLabels.size}, after=${merged.size}`) return merged } }) @@ -228,7 +214,6 @@ export function useProfileLabels( // Skip if already resolved from initial cache if (labels.has(pubkey)) { loading.set(pubkey, false) - console.log(`[profile-loading-debug][profile-labels-loading] ${pubkey.slice(0, 16)}... in cache, not loading`) return } @@ -248,15 +233,12 @@ export function useProfileLabels( labels.set(pubkey, fallback) } loading.set(pubkey, false) - console.log(`[profile-loading-debug][profile-labels-loading] ${pubkey.slice(0, 16)}... in eventStore, not loading`) } else { // No profile found yet, will use fallback after fetch or keep empty // We'll set fallback labels for missing profiles at the end // Mark as loading since we'll fetch it pubkeysToFetch.push(pubkey) loading.set(pubkey, true) - console.log(`[profile-loading-debug][profile-labels-loading] ${pubkey.slice(0, 16)}... not found, SET LOADING=true`) - console.log(`[shimmer-debug][profile-labels] Marking profile as loading: ${pubkey.slice(0, 16)}..., will need to fetch`) } }) @@ -265,12 +247,9 @@ export function useProfileLabels( setProfileLabels(new Map(labels)) setProfileLoading(new Map(loading)) - console.log(`[profile-loading-debug][profile-labels-loading] Initial loading state:`, Array.from(loading.entries()).map(([pk, l]) => `${pk.slice(0, 16)}...=${l}`)) - console.log(`[shimmer-debug][profile-labels] Set initial loading state, loading count=${Array.from(loading.values()).filter(l => l).length}, total profiles=${loading.size}`) // Fetch missing profiles asynchronously with reactive updates if (pubkeysToFetch.length > 0 && relayPool && eventStore) { - console.log(`[profile-loading-debug][profile-labels-loading] Starting fetch for ${pubkeysToFetch.length} profiles:`, pubkeysToFetch.map(p => p.slice(0, 16) + '...')) // Reactive callback: collects profile updates and batches them via RAF to prevent flicker // Strategy: Apply label immediately when profile resolves, but still batch for multiple profiles @@ -284,7 +263,6 @@ export function useProfileLabels( // Apply label immediately to prevent race condition with loading state // This ensures labels are available when isLoading becomes false - console.log(`[shimmer-debug][profile-labels] Applying label immediately: ${pubkey.slice(0, 16)}...="${label}"`) setProfileLabels(prevLabels => { const updated = new Map(prevLabels) updated.set(pubkey, label) @@ -292,13 +270,9 @@ export function useProfileLabels( }) // Clear loading state for this profile when it resolves - console.log(`[profile-loading-debug][profile-labels-loading] Profile resolved for ${pubkey.slice(0, 16)}..., CLEARING LOADING`) - console.log(`[shimmer-debug][profile-labels] Profile resolved: ${pubkey.slice(0, 16)}..., setting loading=false, label="${label}"`) setProfileLoading(prevLoading => { const updated = new Map(prevLoading) - const wasLoading = updated.get(pubkey) === true updated.set(pubkey, false) - console.log(`[shimmer-debug][profile-labels] Updated loading state: ${pubkey.slice(0, 16)}... wasLoading=${wasLoading}, nowLoading=${updated.get(pubkey)}`) return updated }) } @@ -310,20 +284,11 @@ export function useProfileLabels( applyPendingUpdates() // Clear loading state for all fetched profiles - console.log(`[profile-loading-debug][profile-labels-loading] Fetch complete, clearing loading for all ${pubkeysToFetch.length} profiles`) - console.log(`[shimmer-debug][profile-labels] Fetch complete, clearing loading for ${pubkeysToFetch.length} profiles`) setProfileLoading(prevLoading => { const updated = new Map(prevLoading) - const loadingCountBefore = Array.from(updated.values()).filter(l => l).length pubkeysToFetch.forEach(pubkey => { - const wasLoading = updated.get(pubkey) updated.set(pubkey, false) - if (wasLoading) { - console.log(`[profile-loading-debug][profile-labels-loading] ${pubkey.slice(0, 16)}... CLEARED loading after fetch complete`) - } }) - const loadingCountAfter = Array.from(updated.values()).filter(l => l).length - console.log(`[shimmer-debug][profile-labels] Loading state after fetch complete: ${loadingCountBefore} -> ${loadingCountAfter} loading profiles`) return updated }) }) diff --git a/src/utils/nostrUriResolver.tsx b/src/utils/nostrUriResolver.tsx index 83aa4ddb..6c2e41eb 100644 --- a/src/utils/nostrUriResolver.tsx +++ b/src/utils/nostrUriResolver.tsx @@ -320,9 +320,6 @@ export function replaceNostrUrisInMarkdownWithProfileLabels( articleTitles: Map = new Map(), profileLoading: Map = new Map() ): string { - console.log(`[profile-loading-debug][nostr-uri-resolve] Processing markdown, profileLabels=${profileLabels.size}, profileLoading=${profileLoading.size}`) - console.log(`[profile-loading-debug][nostr-uri-resolve] Loading keys:`, Array.from(profileLoading.entries()).filter(([, l]) => l).map(([k]) => k.slice(0, 16) + '...')) - return replaceNostrUrisSafely(markdown, (encoded) => { const link = createNostrLink(encoded) @@ -342,20 +339,17 @@ export function replaceNostrUrisInMarkdownWithProfileLabels( // Use the label if: 1) we have a label, AND 2) profile is not currently loading (false or undefined) const isLoading = profileLoading.get(pubkey) const hasLabel = profileLabels.has(pubkey) - console.log(`[shimmer-debug][markdown-replace] ${decoded.type} pubkey=${pubkey.slice(0, 16)}..., isLoading=${isLoading}, hasLabel=${hasLabel}`) // Use resolved label if we have one and profile is not loading // isLoading can be: true (loading), false (loaded), or undefined (never was loading) // We only avoid using the label if isLoading === true if (isLoading !== true && hasLabel) { const displayName = profileLabels.get(pubkey)! - console.log(`[shimmer-debug][markdown-replace] Using resolved name: ${displayName}`) return `[${displayName}](${link})` } // If loading or no resolved label yet, use fallback (will show loading via post-processing) const label = getNostrUriLabel(encoded) - console.log(`[shimmer-debug][markdown-replace] Using fallback label: ${label} (isLoading=${isLoading})`) return `[${label}](${link})` } } catch (error) { @@ -379,65 +373,45 @@ export function addLoadingClassToProfileLinks( html: string, profileLoading: Map ): string { - console.log(`[shimmer-debug][post-process] Starting post-process, profileLoading.size=${profileLoading.size}`) - console.log(`[shimmer-debug][post-process] Loading pubkeys:`, Array.from(profileLoading.entries()).filter(([, l]) => l).map(([k]) => k.slice(0, 16) + '...')) - if (profileLoading.size === 0) { - console.log(`[shimmer-debug][post-process] No loading profiles, skipping`) return html } - let linksProcessed = 0 - let linksWithLoadingClass = 0 - // Find all tags with href starting with /p/ (profile links) const result = html.replace(/]*?href="\/p\/([^"]+)"[^>]*?>/g, (match, npub) => { - linksProcessed++ try { // Decode npub to get pubkey const decoded = decode(npub) if (decoded.type !== 'npub') { - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: decoded type is ${decoded.type}, not npub`) return match } const pubkey = decoded.data - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: npub=${npub.slice(0, 20)}..., pubkey=${pubkey.slice(0, 16)}...`) // Check if this profile is loading const isLoading = profileLoading.get(pubkey) - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: isLoading=${isLoading}, type=${typeof isLoading}`) if (isLoading === true) { - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Profile is loading, adding class`) // Add profile-loading class if not already present if (!match.includes('profile-loading')) { - linksWithLoadingClass++ // Insert class before the closing > const classMatch = /class="([^"]*)"/.exec(match) if (classMatch) { const updated = match.replace(/class="([^"]*)"/, `class="$1 profile-loading"`) - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Updated existing class, result="${updated.slice(0, 60)}..."`) return updated } else { const updated = match.replace(/(]*?)>/, '$1 class="profile-loading">') - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Added new class attribute, result="${updated.slice(0, 60)}..."`) return updated } - } else { - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Already has profile-loading class`) } - } else { - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Profile not loading, skipping`) } } catch (error) { - console.log(`[shimmer-debug][post-process] Link ${linksProcessed}: Error processing link:`, error) + // Ignore processing errors } return match }) - console.log(`[shimmer-debug][post-process] Finished: processed ${linksProcessed} links, added class to ${linksWithLoadingClass} links`) return result }