Load profiles everywhere
Fixes: #11 Changelog-Fixed: Missing profiles are now loaded everywhere Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -113,7 +113,7 @@ struct ContentView: View {
|
||||
}
|
||||
switch selected_timeline {
|
||||
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:
|
||||
PostingTimelineView
|
||||
|
||||
@@ -16,6 +16,7 @@ class FollowersModel: ObservableObject {
|
||||
var has_contact: Set<String> = Set()
|
||||
|
||||
let sub_id: String = UUID().description
|
||||
let profiles_id: String = UUID().description
|
||||
|
||||
init(damus_state: DamusState, target: String) {
|
||||
self.damus_state = damus_state
|
||||
@@ -52,20 +53,44 @@ class FollowersModel: ObservableObject {
|
||||
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) {
|
||||
switch ev {
|
||||
case .ws_event:
|
||||
break
|
||||
case .nostr_event(let nev):
|
||||
switch nev {
|
||||
case .event(_, let ev):
|
||||
if ev.kind == 3 {
|
||||
handle_contact_event(ev)
|
||||
case .event(let sub_id, let ev):
|
||||
guard sub_id == self.sub_id || sub_id == self.profiles_id else {
|
||||
return
|
||||
}
|
||||
|
||||
if ev.known_kind == .contacts {
|
||||
handle_contact_event(ev)
|
||||
} else if ev.known_kind == .metadata {
|
||||
process_metadata_event(profiles: self.damus_state.profiles, ev: ev)
|
||||
}
|
||||
|
||||
case .notice(let 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])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,19 @@ class SearchHomeModel: ObservableObject {
|
||||
@Published var loading: Bool = false
|
||||
|
||||
var seen_pubkey: Set<String> = Set()
|
||||
let profiles: Profiles
|
||||
let pool: RelayPool
|
||||
let sub_id = UUID().description
|
||||
let base_subid = UUID().description
|
||||
let profiles_subid = UUID().description
|
||||
let limit: UInt32 = 250
|
||||
|
||||
init(pool: RelayPool) {
|
||||
init(pool: RelayPool, profiles: Profiles) {
|
||||
self.pool = pool
|
||||
self.profiles = profiles
|
||||
}
|
||||
|
||||
func get_base_filter() -> NostrFilter {
|
||||
var filter = NostrFilter.filter_text
|
||||
var filter = NostrFilter.filter_kinds([1, 42])
|
||||
filter.limit = self.limit
|
||||
filter.until = Int64(Date.now.timeIntervalSince1970)
|
||||
return filter
|
||||
@@ -31,12 +34,22 @@ class SearchHomeModel: ObservableObject {
|
||||
|
||||
func subscribe() {
|
||||
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() {
|
||||
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) {
|
||||
@@ -46,7 +59,7 @@ class SearchHomeModel: ObservableObject {
|
||||
case .nostr_event(let event):
|
||||
switch event {
|
||||
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
|
||||
}
|
||||
if ev.kind == NostrKind.text.rawValue {
|
||||
@@ -57,13 +70,50 @@ class SearchHomeModel: ObservableObject {
|
||||
let _ = insert_uniq_sorted_event(events: &events, new_ev: ev) {
|
||||
$0.created_at > $1.created_at
|
||||
}
|
||||
} else if ev.known_kind == .metadata {
|
||||
process_metadata_event(profiles: self.profiles, ev: ev)
|
||||
}
|
||||
case .notice(let msg):
|
||||
print("search home notice: \(msg)")
|
||||
case .eose:
|
||||
case .eose(let sub_id):
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
enum NostrResponse: Decodable {
|
||||
case event(String, NostrEvent)
|
||||
case notice(String)
|
||||
case eose
|
||||
case eose(String)
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
var container = try decoder.unkeyedContainer()
|
||||
@@ -34,7 +34,8 @@ enum NostrResponse: Decodable {
|
||||
self = .notice(msg)
|
||||
return
|
||||
} else if typ == "EOSE" {
|
||||
self = .eose
|
||||
let sub_id = try container.decode(String.self)
|
||||
self = .eose(sub_id)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -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.send(.unsubscribe(sub_id))
|
||||
}
|
||||
@@ -117,6 +117,11 @@ class RelayPool {
|
||||
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) {
|
||||
let relays = to.map{ get_relays($0) } ?? self.relays
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ struct SearchHomeView_Previews: PreviewProvider {
|
||||
let state = test_damus_state()
|
||||
SearchHomeView(
|
||||
damus_state: state,
|
||||
model: SearchHomeModel(pool: state.pool)
|
||||
model: SearchHomeModel(pool: state.pool, profiles: state.profiles)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user