Merge branch 'master' into improve-wallet-selector

This commit is contained in:
Suhail Saqan
2022-12-30 01:41:05 -06:00
committed by GitHub
17 changed files with 310 additions and 88 deletions

View File

@@ -139,16 +139,12 @@ func decode_json_relays(_ content: String) -> [String: RelayInfo]? {
return decode_json(content)
}
func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) != nil else {
return nil
}
func remove_relay(ev: NostrEvent, current_relays: [RelayDescriptor], privkey: String, relay: String) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
relays.removeValue(forKey: relay)
print("remove_relay \(relays)")
guard let content = encode_json(relays) else {
return nil
}
@@ -159,10 +155,9 @@ func remove_relay(ev: NostrEvent, privkey: String, relay: String) -> NostrEvent?
return new_ev
}
func add_relay(ev: NostrEvent, privkey: String, relay: String, info: RelayInfo) -> NostrEvent? {
let damus_relay = RelayDescriptor(url: URL(string: "wss://relay.damus.io")!, info: .rw)
func add_relay(ev: NostrEvent, privkey: String, current_relays: [RelayDescriptor], relay: String, info: RelayInfo) -> NostrEvent? {
var relays = ensure_relay_info(relays: current_relays, content: ev.content)
var relays = ensure_relay_info(relays: [damus_relay], content: ev.content)
guard relays.index(forKey: relay) == nil else {
return nil
}

View File

@@ -260,6 +260,9 @@ class HomeModel: ObservableObject {
var contacts_filter = NostrFilter.filter_kinds([0])
contacts_filter.authors = friends
var our_contacts_filter = NostrFilter.filter_kinds([3, 0])
our_contacts_filter.authors = [damus_state.pubkey]
var dms_filter = NostrFilter.filter_kinds([
NostrKind.dm.rawValue,
@@ -297,7 +300,7 @@ class HomeModel: ObservableObject {
var home_filters = [home_filter]
var notifications_filters = [notifications_filter]
var contacts_filters = [contacts_filter]
var contacts_filters = [contacts_filter, our_contacts_filter]
var dms_filters = [dms_filter, our_dms_filter]
let last_of_kind = relay_id.flatMap { last_event_of_kind[$0] } ?? [:]
@@ -443,18 +446,33 @@ func add_contact_if_friend(contacts: Contacts, ev: NostrEvent) {
contacts.add_friend_contact(ev)
}
func load_our_contacts(contacts: Contacts, our_pubkey: String, ev: NostrEvent) {
guard ev.pubkey == our_pubkey else {
return
}
contacts.event = ev
func load_our_contacts(contacts: Contacts, our_pubkey: String, m_old_ev: NostrEvent?, ev: NostrEvent) {
var new_pks = Set<String>()
// our contacts
for tag in ev.tags {
if tag.count > 1 && tag[0] == "p" {
// TODO: validate pubkey?
contacts.add_friend_pubkey(tag[1])
if tag.count >= 2 && tag[0] == "p" {
new_pks.insert(tag[1])
}
}
var old_pks = Set<String>()
// find removed contacts
if let old_ev = m_old_ev {
for tag in old_ev.tags {
if tag.count >= 2 && tag[0] == "p" {
old_pks.insert(tag[1])
}
}
}
let diff = new_pks.symmetricDifference(old_pks)
for pk in diff {
if new_pks.contains(pk) {
notify(.followed, pk)
contacts.add_friend_pubkey(pk)
} else {
notify(.unfollowed, pk)
contacts.remove_friend(pk)
}
}
}
@@ -540,51 +558,68 @@ func robohash(_ pk: String) -> String {
return "https://robohash.org/" + pk
}
func load_our_stuff(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
guard ev.pubkey == pubkey else {
return
}
// only use new stuff
if let current_ev = contacts.event {
guard ev.created_at > current_ev.created_at else {
return
}
}
let m_old_ev = contacts.event
contacts.event = ev
load_our_contacts(contacts: contacts, our_pubkey: pubkey, m_old_ev: m_old_ev, ev: ev)
load_our_relays(contacts: contacts, our_pubkey: pubkey, pool: pool, m_old_ev: m_old_ev, ev: ev)
}
func process_contact_event(pool: RelayPool, contacts: Contacts, pubkey: String, ev: NostrEvent) {
load_our_contacts(contacts: contacts, our_pubkey: pubkey, ev: ev)
load_our_relays(our_pubkey: pubkey, pool: pool, ev: ev)
load_our_stuff(pool: pool, contacts: contacts, pubkey: pubkey, ev: ev)
add_contact_if_friend(contacts: contacts, ev: ev)
}
func load_our_relays(our_pubkey: String, pool: RelayPool, ev: NostrEvent) {
guard ev.pubkey == our_pubkey else {
return
func load_our_relays(contacts: Contacts, our_pubkey: String, pool: RelayPool, m_old_ev: NostrEvent?, ev: NostrEvent) {
let bootstrap_dict: [String: RelayInfo] = [:]
let old_decoded = m_old_ev.flatMap { decode_json_relays($0.content) } ?? BOOTSTRAP_RELAYS.reduce(into: bootstrap_dict) { (d, r) in
d[r] = .rw
}
guard let decoded = decode_json_relays(ev.content) else {
return
}
var changed = false
var new = Set<String>()
for key in decoded.keys {
if let url = URL(string: key) {
if let _ = try? pool.add_relay(url, info: decoded[key]!) {
pool.connect(to: [key])
new.insert(key)
}
var old = Set<String>()
for key in old_decoded.keys {
old.insert(key)
}
let diff = old.symmetricDifference(new)
for d in diff {
changed = true
if new.contains(d) {
if let url = URL(string: d) {
try? pool.add_relay(url, info: decoded[d] ?? .rw)
}
} else {
pool.remove_relay(d)
}
}
if changed {
notify(.relays_changed, ())
}
}
func remove_bootstrap_nodes(_ damus_state: DamusState) {
guard let contacts = damus_state.contacts.event else {
return
}
guard let relays = decode_json_relays(contacts.content) else {
return
}
let descriptors = relays.reduce(into: []) { arr, kv in
guard let url = URL(string: kv.key) else {
return
}
arr.append(RelayDescriptor(url: url, info: kv.value))
}
for relay in BOOTSTRAP_RELAYS {
if !(descriptors.contains { ($0 as! RelayDescriptor).url.absoluteString == relay }) {
damus_state.pool.remove_relay(relay)
}
}
}

View File

@@ -11,6 +11,7 @@ class ProfileModel: ObservableObject, Equatable {
@Published var events: [NostrEvent] = []
@Published var contacts: NostrEvent? = nil
@Published var following: Int = 0
@Published var relays: [String: RelayInfo]? = nil
let pubkey: String
let damus: DamusState
@@ -71,6 +72,7 @@ class ProfileModel: ObservableObject, Equatable {
func handle_profile_contact_event(_ ev: NostrEvent) {
self.contacts = ev
self.following = count_pubkeys(ev.tags)
self.relays = decode_json_relays(ev.content)
if damus.contacts.is_friend(ev.pubkey) {
self.damus.contacts.add_friend_contact(ev)
}