fix: resolve race condition in profile label updates

Fix regression where npubs/nprofiles weren't being replaced with profile names.
The issue was a race condition: loading state was cleared immediately, but labels
were applied asynchronously via RAF, causing the condition check to fail.

Changes:
- Apply profile labels immediately when profiles resolve, instead of batching via RAF
- Update condition check to explicitly handle undefined loading state (isLoading !== true)
- This ensures labels are available in the Map when loading becomes false
This commit is contained in:
Gigi
2025-11-02 23:08:20 +01:00
parent 945b9502bc
commit f417ed8210
2 changed files with 14 additions and 7 deletions

View File

@@ -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) + '...')) 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 // 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) => { const handleProfileEvent = (event: NostrEvent) => {
// Use pubkey directly as the key // Use pubkey directly as the key
const pubkey = event.pubkey const pubkey = event.pubkey
@@ -282,10 +282,14 @@ export function useProfileLabels(
const displayName = extractProfileDisplayName(event) const displayName = extractProfileDisplayName(event)
const label = displayName ? (displayName.startsWith('@') ? displayName : `@${displayName}`) : getNpubFallbackDisplay(pubkey) const label = displayName ? (displayName.startsWith('@') ? displayName : `@${displayName}`) : getNpubFallbackDisplay(pubkey)
// Add to pending updates and schedule batched application // Apply label immediately to prevent race condition with loading state
console.log(`[shimmer-debug][profile-labels] Adding to pending updates: ${pubkey.slice(0, 16)}...="${label}", pendingUpdates.size=${pendingUpdatesRef.current.size + 1}`) // This ensures labels are available when isLoading becomes false
pendingUpdatesRef.current.set(pubkey, label) console.log(`[shimmer-debug][profile-labels] Applying label immediately: ${pubkey.slice(0, 16)}...="${label}"`)
scheduleBatchedUpdate() setProfileLabels(prevLabels => {
const updated = new Map(prevLabels)
updated.set(pubkey, label)
return updated
})
// Clear loading state for this profile when it resolves // 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(`[profile-loading-debug][profile-labels-loading] Profile resolved for ${pubkey.slice(0, 16)}..., CLEARING LOADING`)

View File

@@ -339,12 +339,15 @@ export function replaceNostrUrisInMarkdownWithProfileLabels(
const pubkey = decoded.type === 'npub' ? decoded.data : decoded.data.pubkey const pubkey = decoded.type === 'npub' ? decoded.data : decoded.data.pubkey
// Check if we have a resolved profile name using pubkey as key // 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 isLoading = profileLoading.get(pubkey)
const hasLabel = profileLabels.has(pubkey) const hasLabel = profileLabels.has(pubkey)
console.log(`[shimmer-debug][markdown-replace] ${decoded.type} pubkey=${pubkey.slice(0, 16)}..., isLoading=${isLoading}, hasLabel=${hasLabel}`) 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)! const displayName = profileLabels.get(pubkey)!
console.log(`[shimmer-debug][markdown-replace] Using resolved name: ${displayName}`) console.log(`[shimmer-debug][markdown-replace] Using resolved name: ${displayName}`)
return `[${displayName}](${link})` return `[${displayName}](${link})`