Browse Source

Load profiles everywhere

Fixes: #11
Changelog-Fixed: Missing profiles are now loaded everywhere
Signed-off-by: William Casarin <jb55@jb55.com>
profiles-everywhere
William Casarin 2 years ago
parent
commit
5c62a06618
  1. 2
      damus/ContentView.swift
  2. 33
      damus/Models/FollowersModel.swift
  3. 64
      damus/Models/SearchHomeModel.swift
  4. 5
      damus/Nostr/NostrResponse.swift
  5. 7
      damus/Nostr/RelayPool.swift
  6. 2
      damus/Views/SearchHomeView.swift

2
damus/ContentView.swift

@ -113,7 +113,7 @@ struct ContentView: View {
} }
switch selected_timeline { switch selected_timeline {
case .search: case .search:
SearchHomeView(damus_state: damus_state!, model: SearchHomeModel(pool: damus_state!.pool) ) SearchHomeView(damus_state: damus_state!, model: SearchHomeModel(pool: damus_state!.pool, profiles: damus_state!.profiles))
case .home: case .home:
PostingTimelineView PostingTimelineView

33
damus/Models/FollowersModel.swift

@ -16,6 +16,7 @@ class FollowersModel: ObservableObject {
var has_contact: Set<String> = Set() var has_contact: Set<String> = Set()
let sub_id: String = UUID().description let sub_id: String = UUID().description
let profiles_id: String = UUID().description
init(damus_state: DamusState, target: String) { init(damus_state: DamusState, target: String) {
self.damus_state = damus_state self.damus_state = damus_state
@ -52,20 +53,44 @@ class FollowersModel: ObservableObject {
has_contact.insert(ev.pubkey) has_contact.insert(ev.pubkey)
} }
func load_profiles(relay_id: String) {
var filter = NostrFilter.filter_profiles
let authors = find_profiles_to_fetch_pk(profiles: damus_state.profiles, event_pubkeys: contacts)
if authors.isEmpty {
return
}
filter.authors = authors
damus_state.pool.subscribe_to(sub_id: profiles_id, filters: [filter], to: [relay_id], handler: handle_event)
}
func handle_event(relay_id: String, ev: NostrConnectionEvent) { func handle_event(relay_id: String, ev: NostrConnectionEvent) {
switch ev { switch ev {
case .ws_event: case .ws_event:
break break
case .nostr_event(let nev): case .nostr_event(let nev):
switch nev { switch nev {
case .event(_, let ev): case .event(let sub_id, let ev):
if ev.kind == 3 { guard sub_id == self.sub_id || sub_id == self.profiles_id else {
return
}
if ev.known_kind == .contacts {
handle_contact_event(ev) handle_contact_event(ev)
} else if ev.known_kind == .metadata {
process_metadata_event(profiles: self.damus_state.profiles, ev: ev)
} }
case .notice(let msg): case .notice(let msg):
print("followingmodel notice: \(msg)") print("followingmodel notice: \(msg)")
case .eose:
break case .eose(let sub_id):
if sub_id == self.sub_id {
load_profiles(relay_id: relay_id)
} else if sub_id == self.profiles_id {
damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
}
} }
} }
} }

64
damus/Models/SearchHomeModel.swift

@ -14,16 +14,19 @@ class SearchHomeModel: ObservableObject {
@Published var loading: Bool = false @Published var loading: Bool = false
var seen_pubkey: Set<String> = Set() var seen_pubkey: Set<String> = Set()
let profiles: Profiles
let pool: RelayPool let pool: RelayPool
let sub_id = UUID().description let base_subid = UUID().description
let profiles_subid = UUID().description
let limit: UInt32 = 250 let limit: UInt32 = 250
init(pool: RelayPool) { init(pool: RelayPool, profiles: Profiles) {
self.pool = pool self.pool = pool
self.profiles = profiles
} }
func get_base_filter() -> NostrFilter { func get_base_filter() -> NostrFilter {
var filter = NostrFilter.filter_text var filter = NostrFilter.filter_kinds([1, 42])
filter.limit = self.limit filter.limit = self.limit
filter.until = Int64(Date.now.timeIntervalSince1970) filter.until = Int64(Date.now.timeIntervalSince1970)
return filter return filter
@ -31,12 +34,22 @@ class SearchHomeModel: ObservableObject {
func subscribe() { func subscribe() {
loading = true loading = true
pool.subscribe(sub_id: sub_id, filters: [get_base_filter()], handler: handle_event) pool.subscribe(sub_id: base_subid, filters: [get_base_filter()], handler: handle_event)
} }
func unsubscribe() { func unsubscribe() {
loading = false loading = false
pool.unsubscribe(sub_id: sub_id) pool.unsubscribe(sub_id: base_subid)
}
func load_profiles(relay_id: String) {
var filter = NostrFilter.filter_profiles
let authors = find_profiles_to_fetch(profiles: profiles, events: events)
filter.authors = authors
if !authors.isEmpty {
pool.subscribe(sub_id: profiles_subid, filters: [filter], handler: handle_event)
}
} }
func handle_event(relay_id: String, conn_ev: NostrConnectionEvent) { func handle_event(relay_id: String, conn_ev: NostrConnectionEvent) {
@ -46,7 +59,7 @@ class SearchHomeModel: ObservableObject {
case .nostr_event(let event): case .nostr_event(let event):
switch event { switch event {
case .event(let sub_id, let ev): case .event(let sub_id, let ev):
guard sub_id == self.sub_id else { guard sub_id == self.base_subid || sub_id == self.profiles_subid else {
return return
} }
if ev.kind == NostrKind.text.rawValue { if ev.kind == NostrKind.text.rawValue {
@ -57,13 +70,50 @@ class SearchHomeModel: ObservableObject {
let _ = insert_uniq_sorted_event(events: &events, new_ev: ev) { let _ = insert_uniq_sorted_event(events: &events, new_ev: ev) {
$0.created_at > $1.created_at $0.created_at > $1.created_at
} }
} else if ev.known_kind == .metadata {
process_metadata_event(profiles: self.profiles, ev: ev)
} }
case .notice(let msg): case .notice(let msg):
print("search home notice: \(msg)") print("search home notice: \(msg)")
case .eose: case .eose(let sub_id):
loading = false loading = false
if sub_id == self.base_subid {
load_profiles(relay_id: relay_id)
} else if sub_id == self.profiles_subid {
pool.unsubscribe(sub_id: self.profiles_subid)
}
break break
} }
} }
} }
} }
func find_profiles_to_fetch_pk(profiles: Profiles, event_pubkeys: [String]) -> [String] {
var pubkeys = Set<String>()
for pk in event_pubkeys {
if profiles.lookup(id: pk) != nil {
continue
}
pubkeys.insert(pk)
}
return Array(pubkeys)
}
func find_profiles_to_fetch(profiles: Profiles, events: [NostrEvent]) -> [String] {
var pubkeys = Set<String>()
for ev in events {
if profiles.lookup(id: ev.pubkey) != nil {
continue
}
pubkeys.insert(ev.pubkey)
}
return Array(pubkeys)
}

5
damus/Nostr/NostrResponse.swift

@ -10,7 +10,7 @@ import Foundation
enum NostrResponse: Decodable { enum NostrResponse: Decodable {
case event(String, NostrEvent) case event(String, NostrEvent)
case notice(String) case notice(String)
case eose case eose(String)
init(from decoder: Decoder) throws { init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer() var container = try decoder.unkeyedContainer()
@ -34,7 +34,8 @@ enum NostrResponse: Decodable {
self = .notice(msg) self = .notice(msg)
return return
} else if typ == "EOSE" { } else if typ == "EOSE" {
self = .eose let sub_id = try container.decode(String.self)
self = .eose(sub_id)
return return
} }

7
damus/Nostr/RelayPool.swift

@ -107,7 +107,7 @@ class RelayPool {
} }
} }
func unsubscribe(sub_id: String) { func unsubscribe(sub_id: String, to: [String]? = nil) {
self.remove_handler(sub_id: sub_id) self.remove_handler(sub_id: sub_id)
self.send(.unsubscribe(sub_id)) self.send(.unsubscribe(sub_id))
} }
@ -117,6 +117,11 @@ class RelayPool {
send(.subscribe(.init(filters: filters, sub_id: sub_id))) send(.subscribe(.init(filters: filters, sub_id: sub_id)))
} }
func subscribe_to(sub_id: String, filters: [NostrFilter], to: [String]?, handler: @escaping (String, NostrConnectionEvent) -> ()) {
register_handler(sub_id: sub_id, handler: handler)
send(.subscribe(.init(filters: filters, sub_id: sub_id)), to: to)
}
func send(_ req: NostrRequest, to: [String]? = nil) { func send(_ req: NostrRequest, to: [String]? = nil) {
let relays = to.map{ get_relays($0) } ?? self.relays let relays = to.map{ get_relays($0) } ?? self.relays

2
damus/Views/SearchHomeView.swift

@ -70,7 +70,7 @@ struct SearchHomeView_Previews: PreviewProvider {
let state = test_damus_state() let state = test_damus_state()
SearchHomeView( SearchHomeView(
damus_state: state, damus_state: state,
model: SearchHomeModel(pool: state.pool) model: SearchHomeModel(pool: state.pool, profiles: state.profiles)
) )
} }
} }

Loading…
Cancel
Save