Contacts.swift (2934B)
1 // 2 // Contacts.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-05-14. 6 // 7 8 import Foundation 9 10 class Contacts { 11 private var friends: Set<Pubkey> = Set() 12 private var friend_of_friends: Set<Pubkey> = Set() 13 /// Tracks which friends are friends of a given pubkey. 14 private var pubkey_to_our_friends = [Pubkey : Set<Pubkey>]() 15 16 let our_pubkey: Pubkey 17 var delegate: ContactsDelegate? = nil 18 var event: NostrEvent? { 19 didSet { 20 guard let event else { return } 21 self.delegate?.latest_contact_event_changed(new_event: event) 22 } 23 } 24 25 init(our_pubkey: Pubkey) { 26 self.our_pubkey = our_pubkey 27 } 28 29 func remove_friend(_ pubkey: Pubkey) { 30 friends.remove(pubkey) 31 32 pubkey_to_our_friends.forEach { 33 pubkey_to_our_friends[$0.key]?.remove(pubkey) 34 } 35 } 36 37 func get_friend_list() -> Set<Pubkey> { 38 return friends 39 } 40 41 func get_followed_hashtags() -> Set<String> { 42 guard let ev = self.event else { return Set() } 43 return Set(ev.referenced_hashtags.map({ $0.hashtag })) 44 } 45 46 func follows(hashtag: Hashtag) -> Bool { 47 guard let ev = self.event else { return false } 48 return ev.referenced_hashtags.first(where: { $0 == hashtag }) != nil 49 } 50 51 func add_friend_pubkey(_ pubkey: Pubkey) { 52 friends.insert(pubkey) 53 } 54 55 func add_friend_contact(_ contact: NostrEvent) { 56 friends.insert(contact.pubkey) 57 for pk in contact.referenced_pubkeys { 58 friend_of_friends.insert(pk) 59 60 // Exclude themself and us. 61 if contact.pubkey != our_pubkey && contact.pubkey != pk { 62 if pubkey_to_our_friends[pk] == nil { 63 pubkey_to_our_friends[pk] = Set<Pubkey>() 64 } 65 66 pubkey_to_our_friends[pk]?.insert(contact.pubkey) 67 } 68 } 69 } 70 71 func is_friend_of_friend(_ pubkey: Pubkey) -> Bool { 72 return friend_of_friends.contains(pubkey) 73 } 74 75 func is_in_friendosphere(_ pubkey: Pubkey) -> Bool { 76 return friends.contains(pubkey) || friend_of_friends.contains(pubkey) 77 } 78 79 func is_friend(_ pubkey: Pubkey) -> Bool { 80 return friends.contains(pubkey) 81 } 82 83 func is_friend_or_self(_ pubkey: Pubkey) -> Bool { 84 return pubkey == our_pubkey || is_friend(pubkey) 85 } 86 87 func follow_state(_ pubkey: Pubkey) -> FollowState { 88 return is_friend(pubkey) ? .follows : .unfollows 89 } 90 91 /// Gets the list of pubkeys of our friends who follow the given pubkey. 92 func get_friended_followers(_ pubkey: Pubkey) -> [Pubkey] { 93 return Array((pubkey_to_our_friends[pubkey] ?? Set())) 94 } 95 } 96 97 /// Delegate protocol for `Contacts`. Use this to listen to significant updates from a `Contacts` instance 98 protocol ContactsDelegate { 99 func latest_contact_event_changed(new_event: NostrEvent) 100 }