diff --git a/src/hooks/useProfileLabels.ts b/src/hooks/useProfileLabels.ts index 95428a0e..5bedb7d6 100644 --- a/src/hooks/useProfileLabels.ts +++ b/src/hooks/useProfileLabels.ts @@ -273,7 +273,7 @@ export function useProfileLabels( 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: Collect updates in ref, schedule RAF on first update, apply all in batch + // Strategy: Apply label immediately when profile resolves, but still batch for multiple profiles const handleProfileEvent = (event: NostrEvent) => { // Use pubkey directly as the key const pubkey = event.pubkey @@ -282,10 +282,14 @@ export function useProfileLabels( const displayName = extractProfileDisplayName(event) const label = displayName ? (displayName.startsWith('@') ? displayName : `@${displayName}`) : getNpubFallbackDisplay(pubkey) - // Add to pending updates and schedule batched application - console.log(`[shimmer-debug][profile-labels] Adding to pending updates: ${pubkey.slice(0, 16)}...="${label}", pendingUpdates.size=${pendingUpdatesRef.current.size + 1}`) - pendingUpdatesRef.current.set(pubkey, label) - scheduleBatchedUpdate() + // 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) + return updated + }) // 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`) diff --git a/src/utils/nostrUriResolver.tsx b/src/utils/nostrUriResolver.tsx index 740371c6..83aa4ddb 100644 --- a/src/utils/nostrUriResolver.tsx +++ b/src/utils/nostrUriResolver.tsx @@ -339,12 +339,15 @@ export function replaceNostrUrisInMarkdownWithProfileLabels( const pubkey = decoded.type === 'npub' ? decoded.data : decoded.data.pubkey // Check if we have a resolved profile name using pubkey as key - // Only use Map value if profile is not loading (meaning it's actually resolved) + // 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}`) - if (!isLoading && 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})`