damus

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

commit 1a2ac976a33eb21ff54e8d82801a14695afc966f
parent d4faacb99f81c639b3341712d8c102da11d4c13b
Author: William Casarin <jb55@jb55.com>
Date:   Sun,  6 Aug 2023 09:20:18 -0700

Fix old notifications always appearing on first start

Revert "home: debounce last notified"

This is technically incorrect, as debouncing can prevent saving
important events.

The proper way to do this is to save it locally in memory, and then
debouncing the saving itself. Will do this soon.

Reverts: a9b4cfd4241f3d4a6fb2c1ee2e2ce1de33eae4d4
Fixes: https://github.com/damus-io/damus/issues/1439
Changelog-Fixed: Fixed old notifications always appearing on first start

Diffstat:
Mdamus/Models/HomeModel.swift | 27++++++++++-----------------
Mdamus/Views/DMChatView.swift | 2+-
MdamusTests/DMTests.swift | 18+++++++++---------
3 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -70,7 +70,6 @@ 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 @@ -232,7 +231,7 @@ class HomeModel { return } - 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 { + guard let new_bits = handle_last_events(new_events: self.notification_status.new_events, ev: ev, timeline: .notifications, shouldNotify: true) else { return } @@ -593,7 +592,7 @@ class HomeModel { @discardableResult func handle_last_event(ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> Bool { - 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) { + if let new_bits = handle_last_events(new_events: self.notification_status.new_events, ev: ev, timeline: timeline, shouldNotify: shouldNotify) { self.notification_status.new_events = new_bits return true } else { @@ -644,7 +643,7 @@ class HomeModel { if !should_debounce_dms { self.incoming_dms.append(ev) - 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) { + 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) { got_new_dm(notifs: notifs, ev: ev) } self.incoming_dms = [] @@ -654,7 +653,7 @@ class HomeModel { incoming_dms.append(ev) dm_debouncer.debounce { [self] in - 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) { + 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) { got_new_dm(notifs: notifs, ev: ev) } self.incoming_dms = [] @@ -972,7 +971,7 @@ func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? { } @discardableResult -func handle_incoming_dm(debouncer: Debouncer?, ev: NostrEvent, our_pubkey: Pubkey, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) { +func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) { var inserted = false var found = false @@ -1009,20 +1008,20 @@ func handle_incoming_dm(debouncer: Debouncer?, ev: NostrEvent, our_pubkey: Pubke var new_bits: NewEventsBits? = nil if inserted { - new_bits = handle_last_events(debouncer: debouncer, new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours) + new_bits = handle_last_events(new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours) } return (inserted, new_bits) } @discardableResult -func handle_incoming_dms(debouncer: Debouncer, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: Pubkey, evs: [NostrEvent]) -> NewEventsBits? { +func handle_incoming_dms(prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, evs: [NostrEvent]) -> NewEventsBits? { var inserted = false var new_events: NewEventsBits? = nil for ev in evs { - let res = handle_incoming_dm(debouncer: debouncer, ev: ev, our_pubkey: our_pubkey, dms: dms, prev_events: prev_events) + let res = handle_incoming_dm(ev: ev, our_pubkey: our_pubkey, dms: dms, prev_events: prev_events) inserted = res.0 || inserted if let new = res.1 { new_events = new @@ -1081,17 +1080,11 @@ 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(debouncer: Debouncer?, new_events: NewEventsBits, ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> NewEventsBits? { +func handle_last_events(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 { - if let debouncer { - debouncer.debounce { - save_last_event(ev, timeline: timeline) - } - } else { - save_last_event(ev, timeline: timeline) - } + save_last_event(ev, timeline: timeline) if shouldNotify { return new_events.union(timeline_to_notification_bits(timeline, ev: ev)) } diff --git a/damus/Views/DMChatView.swift b/damus/Views/DMChatView.swift @@ -141,7 +141,7 @@ struct DMChatView: View, KeyboardReadable { damus_state.postbox.send(dm) - handle_incoming_dm(debouncer: nil, ev: dm, our_pubkey: damus_state.pubkey, dms: damus_state.dms, prev_events: NewEventsBits()) + handle_incoming_dm(ev: dm, our_pubkey: damus_state.pubkey, dms: damus_state.dms, prev_events: NewEventsBits()) end_editing() } diff --git a/damusTests/DMTests.swift b/damusTests/DMTests.swift @@ -49,55 +49,55 @@ final class DMTests: XCTestCase { let now = UInt32(Date().timeIntervalSince1970) let alice_to_bob = create_dm("hi bob", to_pk: bob.pubkey, tags: [bob.pubkey.tag], keypair: alice, created_at: now)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob]) XCTAssertEqual(model.dms.count, 1) XCTAssertEqual(model.dms[0].pubkey, bob.pubkey) let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 1)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice]) XCTAssertEqual(model.dms.count, 1) XCTAssertEqual(model.dms[0].pubkey, bob.pubkey) let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [bob.pubkey.tag], keypair: alice, created_at: now + 2)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2]) XCTAssertEqual(model.dms.count, 1) XCTAssertEqual(model.dms[0].pubkey, bob.pubkey) let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: fiatjaf, created_at: now+5)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice]) XCTAssertEqual(model.dms.count, 2) XCTAssertEqual(model.dms[0].pubkey, fiatjaf.pubkey) let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: dave, created_at: now + 10)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice]) XCTAssertEqual(model.dms.count, 3) XCTAssertEqual(model.dms[0].pubkey, dave.pubkey) let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 15)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2]) XCTAssertEqual(model.dms.count, 3) XCTAssertEqual(model.dms[0].pubkey, bob.pubkey) let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: charlie, created_at: now + 20)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice]) XCTAssertEqual(model.dms.count, 4) XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey) let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: bob, created_at: now + 25)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3]) XCTAssertEqual(model.dms.count, 4) XCTAssertEqual(model.dms[0].pubkey, bob.pubkey) let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [alice.pubkey.tag], keypair: charlie, created_at: now + 30)! - handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2]) + handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2]) XCTAssertEqual(model.dms.count, 4) XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)