damus

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

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 }