mirror of
git://jb55.com/damus
synced 2024-09-29 16:30:44 +00:00
contacts: save the users' latest contact event ID
... to a persistent setting, and try to load it from NostrDB on app start. This commit causes the user's contact list event ID to be saved persistently as a user-specific setting, and to be loaded immediately after startup from the local NostrDB instance. This helps improve reliability around contact lists, since we previously relied on fetching that contact list from other relays. Eventually we will not need the event ID to be stored at all, as we will be able to query NostrDB, but for now having the latest event ID persistently stored will allow us to get around this limitation in the cleanest possible way (i.e. without having to store the event itself into another mechanism, and migrating it later to NostrDB) Other notes: - It uses a mechanism similar to other user settings, so it is pubkey-specific and should handle login/logout cases Signed-off-by: Daniel D’Aquino <daniel@daquino.me> Reviewed-by: William Casarin <jb55@jb55.com> Link: 20240422230912.65056-2-daniel@daquino.me Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
ada99418f6
commit
bb321b6e8a
@ -7,7 +7,6 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
class Contacts {
|
||||
private var friends: Set<Pubkey> = Set()
|
||||
private var friend_of_friends: Set<Pubkey> = Set()
|
||||
@ -15,7 +14,13 @@ class Contacts {
|
||||
private var pubkey_to_our_friends = [Pubkey : Set<Pubkey>]()
|
||||
|
||||
let our_pubkey: Pubkey
|
||||
var event: NostrEvent?
|
||||
var delegate: ContactsDelegate? = nil
|
||||
var event: NostrEvent? {
|
||||
didSet {
|
||||
guard let event else { return }
|
||||
self.delegate?.latest_contact_event_changed(new_event: event)
|
||||
}
|
||||
}
|
||||
|
||||
init(our_pubkey: Pubkey) {
|
||||
self.our_pubkey = our_pubkey
|
||||
@ -88,3 +93,8 @@ class Contacts {
|
||||
return Array((pubkey_to_our_friends[pubkey] ?? Set()))
|
||||
}
|
||||
}
|
||||
|
||||
/// Delegate protocol for `Contacts`. Use this to listen to significant updates from a `Contacts` instance
|
||||
protocol ContactsDelegate {
|
||||
func latest_contact_event_changed(new_event: NostrEvent)
|
||||
}
|
||||
|
@ -41,11 +41,15 @@ enum HomeResubFilter {
|
||||
}
|
||||
}
|
||||
|
||||
class HomeModel {
|
||||
class HomeModel: ContactsDelegate {
|
||||
// Don't trigger a user notification for events older than a certain age
|
||||
static let event_max_age_for_notification: TimeInterval = EVENT_MAX_AGE_FOR_NOTIFICATION
|
||||
|
||||
var damus_state: DamusState
|
||||
var damus_state: DamusState {
|
||||
didSet {
|
||||
self.load_our_stuff_from_damus_state()
|
||||
}
|
||||
}
|
||||
|
||||
// NDBTODO: let's get rid of this entirely, let nostrdb handle it
|
||||
var has_event: [String: Set<NoteId>] = [:]
|
||||
@ -108,6 +112,32 @@ class HomeModel {
|
||||
self.should_debounce_dms = false
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Loading items from DamusState
|
||||
|
||||
/// This is called whenever DamusState gets set. This function is used to load or setup anything we need from the new DamusState
|
||||
func load_our_stuff_from_damus_state() {
|
||||
self.load_latest_contact_event_from_damus_state()
|
||||
}
|
||||
|
||||
/// This loads the latest contact event we have on file from NostrDB. This should be called as soon as we get the new DamusState
|
||||
/// Loading the latest contact list event into our `Contacts` instance from storage is important to avoid getting into weird states when the network is unreliable or when relays delete such information
|
||||
func load_latest_contact_event_from_damus_state() {
|
||||
guard let latest_contact_event_id_hex = damus_state.settings.latest_contact_event_id_hex else { return }
|
||||
guard let latest_contact_event_id = NoteId(hex: latest_contact_event_id_hex) else { return }
|
||||
guard let latest_contact_event: NdbNote = damus_state.ndb.lookup_note( latest_contact_event_id)?.unsafeUnownedValue?.to_owned() else { return }
|
||||
process_contact_event(state: damus_state, ev: latest_contact_event)
|
||||
damus_state.contacts.delegate = self
|
||||
}
|
||||
|
||||
// MARK: - ContactsDelegate functions
|
||||
|
||||
func latest_contact_event_changed(new_event: NostrEvent) {
|
||||
// When the latest user contact event has changed, save its ID so we know exactly where to find it next time
|
||||
damus_state.settings.latest_contact_event_id_hex = new_event.id.hex()
|
||||
}
|
||||
|
||||
// MARK: - Nostr event and subscription handling
|
||||
|
||||
func resubscribe(_ resubbing: Resubscribe) {
|
||||
if self.should_debounce_dms {
|
||||
|
@ -312,6 +312,12 @@ class UserSettingsStore: ObservableObject {
|
||||
return internal_winetranslate_api_key != nil
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Internal, hidden settings
|
||||
|
||||
@Setting(key: "latest_contact_event_id", default_value: nil)
|
||||
var latest_contact_event_id_hex: String?
|
||||
|
||||
}
|
||||
|
||||
func pk_setting_key(_ pubkey: Pubkey, key: String) -> String {
|
||||
|
Loading…
Reference in New Issue
Block a user