Skip to content

Commit

Permalink
Debounce last notified
Browse files Browse the repository at this point in the history
Calling UserDefaults fast in a loop is not good
  • Loading branch information
jb55 committed Jul 28, 2023
1 parent 3ad0d4e commit 5d71b69
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 20 deletions.
17 changes: 10 additions & 7 deletions damus/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ extension UINavigationController: UIGestureRecognizerDelegate {
}

struct LastNotification {
let id: String
let id: NoteId
let created_at: Int64
}

Expand All @@ -698,17 +698,20 @@ func get_last_event(_ timeline: Timeline) -> LastNotification? {
let last = UserDefaults.standard.string(forKey: "last_\(str)")
let last_created = UserDefaults.standard.string(forKey: "last_\(str)_time")
.flatMap { Int64($0) }

return last.flatMap { id in
last_created.map { created in
return LastNotification(id: id, created_at: created)
}

guard let last,
let note_id = NoteId(hex: last),
let last_created
else {
return nil
}

return LastNotification(id: note_id, created_at: last_created)
}

func save_last_event(_ ev: NostrEvent, timeline: Timeline) {
let str = timeline.rawValue
UserDefaults.standard.set(ev.id, forKey: "last_\(str)")
UserDefaults.standard.set(ev.id.hex(), forKey: "last_\(str)")
UserDefaults.standard.set(String(ev.created_at), forKey: "last_\(str)_time")
}

Expand Down
27 changes: 17 additions & 10 deletions damus/Models/HomeModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class HomeModel {
var incoming_dms: [NostrEvent] = []
let dm_debouncer = Debouncer(interval: 0.5)
let resub_debouncer = Debouncer(interval: 3.0)
let save_last_event_debouncer = Debouncer(interval: 3.0)
var should_debounce_dms = true

let home_subid = UUID().description
Expand Down Expand Up @@ -231,7 +232,7 @@ class HomeModel {
return
}

guard let new_bits = handle_last_events(new_events: self.notification_status.new_events, ev: ev, timeline: .notifications, shouldNotify: true) else {
guard let new_bits = handle_last_events(debouncer: self.save_last_event_debouncer, new_events: self.notification_status.new_events, ev: ev, timeline: .notifications, shouldNotify: true) else {
return
}

Expand Down Expand Up @@ -592,7 +593,7 @@ class HomeModel {

@discardableResult
func handle_last_event(ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> Bool {
if let new_bits = handle_last_events(new_events: self.notification_status.new_events, ev: ev, timeline: timeline, shouldNotify: shouldNotify) {
if let new_bits = handle_last_events(debouncer: save_last_event_debouncer, new_events: self.notification_status.new_events, ev: ev, timeline: timeline, shouldNotify: shouldNotify) {
self.notification_status.new_events = new_bits
return true
} else {
Expand Down Expand Up @@ -643,7 +644,7 @@ class HomeModel {

if !should_debounce_dms {
self.incoming_dms.append(ev)
if let notifs = handle_incoming_dms(prev_events: notification_status.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
if let notifs = handle_incoming_dms(debouncer: save_last_event_debouncer, prev_events: notification_status.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
got_new_dm(notifs: notifs, ev: ev)
}
self.incoming_dms = []
Expand All @@ -653,7 +654,7 @@ class HomeModel {
incoming_dms.append(ev)

dm_debouncer.debounce { [self] in
if let notifs = handle_incoming_dms(prev_events: notification_status.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
if let notifs = handle_incoming_dms(debouncer: save_last_event_debouncer, prev_events: notification_status.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
got_new_dm(notifs: notifs, ev: ev)
}
self.incoming_dms = []
Expand Down Expand Up @@ -977,7 +978,7 @@ func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? {
}

@discardableResult
func handle_incoming_dm(ev: NostrEvent, our_pubkey: Pubkey, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) {
func handle_incoming_dm(debouncer: Debouncer?, ev: NostrEvent, our_pubkey: Pubkey, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) {
var inserted = false
var found = false

Expand Down Expand Up @@ -1014,20 +1015,20 @@ func handle_incoming_dm(ev: NostrEvent, our_pubkey: Pubkey, dms: DirectMessagesM

var new_bits: NewEventsBits? = nil
if inserted {
new_bits = handle_last_events(new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours)
new_bits = handle_last_events(debouncer: debouncer, new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours)
}

return (inserted, new_bits)
}

@discardableResult
func handle_incoming_dms(prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: Pubkey, evs: [NostrEvent]) -> NewEventsBits? {
func handle_incoming_dms(debouncer: Debouncer, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: Pubkey, evs: [NostrEvent]) -> NewEventsBits? {
var inserted = false

var new_events: NewEventsBits? = nil

for ev in evs {
let res = handle_incoming_dm(ev: ev, our_pubkey: our_pubkey, dms: dms, prev_events: prev_events)
let res = handle_incoming_dm(debouncer: debouncer, ev: ev, our_pubkey: our_pubkey, dms: dms, prev_events: prev_events)
inserted = res.0 || inserted
if let new = res.1 {
new_events = new
Expand Down Expand Up @@ -1086,11 +1087,17 @@ func timeline_to_notification_bits(_ timeline: Timeline, ev: NostrEvent?) -> New
}

/// A helper to determine if we need to notify the user of new events
func handle_last_events(new_events: NewEventsBits, ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> NewEventsBits? {
func handle_last_events(debouncer: Debouncer?, new_events: NewEventsBits, ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> NewEventsBits? {
let last_ev = get_last_event(timeline)

if last_ev == nil || last_ev!.created_at < ev.created_at {
save_last_event(ev, timeline: timeline)
if let debouncer {
debouncer.debounce {
save_last_event(ev, timeline: timeline)
}
} else {
save_last_event(ev, timeline: timeline)
}
if shouldNotify {
return new_events.union(timeline_to_notification_bits(timeline, ev: ev))
}
Expand Down
5 changes: 3 additions & 2 deletions damus/Nostr/Profiles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,16 @@ class Profiles {
}

func has_fresh_profile(id: Pubkey) -> Bool {
// check memory first
var profile: Profile?
profiles_queue.sync {
profile = profiles[id]?.profile
}
if profile != nil {
return true
}

// check memory first
return false

// then disk
guard let pull_date = database.get_network_pull_date(id: id) else {
return false
Expand Down
2 changes: 1 addition & 1 deletion damus/Views/DMChatView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ struct DMChatView: View, KeyboardReadable {

damus_state.postbox.send(dm)

handle_incoming_dm(ev: dm, our_pubkey: damus_state.pubkey, dms: damus_state.dms, prev_events: NewEventsBits())
handle_incoming_dm(debouncer: nil, ev: dm, our_pubkey: damus_state.pubkey, dms: damus_state.dms, prev_events: NewEventsBits())

end_editing()
}
Expand Down

0 comments on commit 5d71b69

Please sign in to comment.