damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit d1cced8d5424ae893c6a75a324ce6a0720a01c6c
parent 8849b6105c21089b6d42d3ac0dc8fad75bf59b96
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Fri, 28 Mar 2025 11:25:11 -0300

Fetch NIP-65 relay lists from profile view

Changelog-Fixed: Fixed issue where profiles with a NIP-65 relay list would not display on Damus
Closes: https://github.com/damus-io/damus/issues/2120
Signed-off-by: Daniel D’Aquino <daniel@daquino.me>

Diffstat:
Mdamus/Models/ProfileModel.swift | 24+++++++++++++++++++-----
Mdamus/Views/Profile/ProfileView.swift | 8++++----
2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/damus/Models/ProfileModel.swift b/damus/Models/ProfileModel.swift @@ -10,8 +10,18 @@ import Foundation class ProfileModel: ObservableObject, Equatable { @Published var contacts: NostrEvent? = nil @Published var following: Int = 0 - @Published var relays: [RelayURL: LegacyKind3RelayRWConfiguration]? = nil + @Published var relay_list: NIP65.RelayList? = nil + @Published var legacy_relay_list: [RelayURL: LegacyKind3RelayRWConfiguration]? = nil @Published var progress: Int = 0 + var relay_urls: [RelayURL]? { + if let relay_list { + return relay_list.relays.values.map({ $0.url }) + } + if let legacy_relay_list { + return Array(legacy_relay_list.keys) + } + return nil + } private let MAX_SHARE_RELAYS = 4 @@ -69,6 +79,7 @@ class ProfileModel: ObservableObject, Equatable { func subscribe() { var text_filter = NostrFilter(kinds: [.text, .longform, .highlight]) var profile_filter = NostrFilter(kinds: [.contacts, .metadata, .boost]) + var relay_list_filter = NostrFilter(kinds: [.relay_list], authors: [pubkey]) profile_filter.authors = [pubkey] @@ -78,7 +89,7 @@ class ProfileModel: ObservableObject, Equatable { print("subscribing to textlike events from profile \(pubkey) with sub_id \(sub_id)") //print_filters(relay_id: "profile", filters: [[text_filter], [profile_filter]]) damus.nostrNetwork.pool.subscribe(sub_id: sub_id, filters: [text_filter], handler: handle_event) - damus.nostrNetwork.pool.subscribe(sub_id: prof_subid, filters: [profile_filter], handler: handle_event) + damus.nostrNetwork.pool.subscribe(sub_id: prof_subid, filters: [profile_filter, relay_list_filter], handler: handle_event) subscribe_to_conversations() } @@ -109,7 +120,7 @@ class ProfileModel: ObservableObject, Equatable { self.contacts = ev self.following = count_pubkeys(ev.tags) - self.relays = decode_json_relays(ev.content) + self.legacy_relay_list = decode_json_relays(ev.content) } private func add_event(_ ev: NostrEvent) { @@ -120,6 +131,9 @@ class ProfileModel: ObservableObject, Equatable { } else if ev.known_kind == .contacts { handle_profile_contact_event(ev) } + else if ev.known_kind == .relay_list { + self.relay_list = try? NIP65.RelayList(event: ev) // Whether another user's list is malformatted is something beyond our control. Probably best to suppress errors + } seen_event.insert(ev.id) } @@ -192,7 +206,7 @@ class ProfileModel: ObservableObject, Equatable { private func findRelaysHandler(relay_id: RelayURL, ev: NostrConnectionEvent) { if case .nostr_event(let resp) = ev, case .event(_, let event) = resp, case .contacts = event.known_kind { - self.relays = decode_json_relays(event.content) + self.legacy_relay_list = decode_json_relays(event.content) } } @@ -208,7 +222,7 @@ class ProfileModel: ObservableObject, Equatable { } func getCappedRelayStrings() -> [String] { - return relays?.keys.prefix(MAX_SHARE_RELAYS).map { $0.absoluteString } ?? [] + return self.relay_urls?.prefix(MAX_SHARE_RELAYS).map { $0.absoluteString } ?? [] } } diff --git a/damus/Views/Profile/ProfileView.swift b/damus/Views/Profile/ProfileView.swift @@ -396,18 +396,18 @@ struct ProfileView: View { } } - if let relays = profile.relays { + if let relays = profile.relay_urls { // Only open relay config view if the user is logged in with private key and they are looking at their own profile. - let noun_string = pluralizedString(key: "relays_count", count: relays.keys.count) + let noun_string = pluralizedString(key: "relays_count", count: relays.count) let noun_text = Text(noun_string).font(.subheadline).foregroundColor(.gray) - let relay_text = Text("\(Text(verbatim: relays.keys.count.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many relay servers a user is connected. In source English, the first variable is the number of relay servers, and the second variable is 'Relay' or 'Relays'.") + let relay_text = Text("\(Text(verbatim: relays.count.formatted()).font(.subheadline.weight(.medium))) \(noun_text)", comment: "Sentence composed of 2 variables to describe how many relay servers a user is connected. In source English, the first variable is the number of relay servers, and the second variable is 'Relay' or 'Relays'.") if profile.pubkey == damus_state.pubkey && damus_state.is_privkey_user { NavigationLink(value: Route.RelayConfig) { relay_text } .buttonStyle(PlainButtonStyle()) } else { - NavigationLink(value: Route.UserRelays(relays: Array(relays.keys).sorted())) { + NavigationLink(value: Route.UserRelays(relays: relays.sorted())) { relay_text } .buttonStyle(PlainButtonStyle())