Ensure mention profiles render with display names

Co-authored-by: Daniel D’Aquino <daniel@daquino.me>
Closes: https://github.com/damus-io/damus/issues/3331
Changelog-Fixed: Fix mention pills falling back to @npub text when profile metadata is missing
Signed-off-by: alltheseas <64376233+alltheseas@users.noreply.github.com>
This commit is contained in:
alltheseas
2025-11-17 22:39:03 -06:00
committed by Daniel D’Aquino
parent 44071e9d75
commit 7eafe973d9
2 changed files with 56 additions and 0 deletions

View File

@@ -101,6 +101,10 @@ extension NostrNetworkManager {
relevantStream.continuation.yield(profile) relevantStream.continuation.yield(profile)
} }
} }
// Notify the rest of the app so views that rely on rendered text (like mention strings)
// can reload and pick up the freshly fetched profile metadata.
notify(.profile_updated(.remote(pubkey: metadataEvent.pubkey)))
} }

View File

@@ -45,6 +45,7 @@ struct NoteContentView: View {
let event: NostrEvent let event: NostrEvent
@State var blur_images: Bool @State var blur_images: Bool
@State var load_media: Bool = false @State var load_media: Bool = false
@State private var requestedMentionProfiles: Set<Pubkey> = []
let size: EventViewKind let size: EventViewKind
let preview_height: CGFloat? let preview_height: CGFloat?
let options: EventViewOptions let options: EventViewOptions
@@ -273,11 +274,62 @@ struct NoteContentView: View {
.padding(.horizontal) .padding(.horizontal)
} }
func ensureMentionProfilesAreFetchingIfNeeded() {
guard let blockGroup = try? NdbBlockGroup.from(event: event, using: damus_state.ndb, and: damus_state.keypair) else {
return
}
var mentionPubkeys: Set<Pubkey> = []
let _: ()? = try? blockGroup.forEachBlock({ _, block in
switch block {
case .mention(let mentionBlock):
if let mention = MentionRef(block: mentionBlock),
let pubkey = mention.pubkey {
mentionPubkeys.insert(pubkey)
}
default:
break
}
return .loopContinue
})
guard !mentionPubkeys.isEmpty else { return }
var toFetch: [Pubkey] = []
for pubkey in mentionPubkeys {
if requestedMentionProfiles.contains(pubkey) {
continue
}
requestedMentionProfiles.insert(pubkey)
if let txn = damus_state.ndb.lookup_profile(pubkey),
damus_state.profiles.has_fresh_profile(id: pubkey, txn: txn) {
continue
}
toFetch.append(pubkey)
}
guard !toFetch.isEmpty else { return }
// Kick off metadata fetches for any missing mention profiles so their names can render once loaded.
for pubkey in toFetch {
Task {
for await _ in await damus_state.nostrNetwork.profilesManager.streamProfile(pubkey: pubkey) {
// NO-OP, we will receive the update via `notify`
break
}
}
}
}
func load(force_artifacts: Bool = false) { func load(force_artifacts: Bool = false) {
if case .loading = damus_state.events.get_cache_data(event.id).artifacts_model.state { if case .loading = damus_state.events.get_cache_data(event.id).artifacts_model.state {
return return
} }
ensureMentionProfilesAreFetchingIfNeeded()
// always reload artifacts on load // always reload artifacts on load
let plan = get_preload_plan(evcache: damus_state.events, ev: event, our_keypair: damus_state.keypair, settings: damus_state.settings) let plan = get_preload_plan(evcache: damus_state.events, ev: event, our_keypair: damus_state.keypair, settings: damus_state.settings)