mirror of
git://jb55.com/damus
synced 2024-09-18 19:23:49 +00:00
home: debounce last notified
Calling UserDefaults fast in a loop is not good
This commit is contained in:
parent
2b99f94d13
commit
a9b4cfd424
@ -72,6 +72,7 @@ class HomeModel {
|
|||||||
var incoming_dms: [NostrEvent] = []
|
var incoming_dms: [NostrEvent] = []
|
||||||
let dm_debouncer = Debouncer(interval: 0.5)
|
let dm_debouncer = Debouncer(interval: 0.5)
|
||||||
let resub_debouncer = Debouncer(interval: 3.0)
|
let resub_debouncer = Debouncer(interval: 3.0)
|
||||||
|
let save_last_event_debouncer = Debouncer(interval: 3.0)
|
||||||
var should_debounce_dms = true
|
var should_debounce_dms = true
|
||||||
|
|
||||||
let home_subid = UUID().description
|
let home_subid = UUID().description
|
||||||
@ -237,7 +238,7 @@ class HomeModel {
|
|||||||
return
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,7 +609,7 @@ class HomeModel {
|
|||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func handle_last_event(ev: NostrEvent, timeline: Timeline, shouldNotify: Bool = true) -> Bool {
|
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
|
self.notification_status.new_events = new_bits
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
@ -659,7 +660,7 @@ class HomeModel {
|
|||||||
|
|
||||||
if !should_debounce_dms {
|
if !should_debounce_dms {
|
||||||
self.incoming_dms.append(ev)
|
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)
|
got_new_dm(notifs: notifs, ev: ev)
|
||||||
}
|
}
|
||||||
self.incoming_dms = []
|
self.incoming_dms = []
|
||||||
@ -669,7 +670,7 @@ class HomeModel {
|
|||||||
incoming_dms.append(ev)
|
incoming_dms.append(ev)
|
||||||
|
|
||||||
dm_debouncer.debounce { [self] in
|
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)
|
got_new_dm(notifs: notifs, ev: ev)
|
||||||
}
|
}
|
||||||
self.incoming_dms = []
|
self.incoming_dms = []
|
||||||
@ -992,7 +993,7 @@ func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, 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 inserted = false
|
||||||
var found = false
|
var found = false
|
||||||
|
|
||||||
@ -1029,20 +1030,20 @@ func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesM
|
|||||||
|
|
||||||
var new_bits: NewEventsBits? = nil
|
var new_bits: NewEventsBits? = nil
|
||||||
if inserted {
|
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)
|
return (inserted, new_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func handle_incoming_dms(prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, evs: [NostrEvent]) -> NewEventsBits? {
|
func handle_incoming_dms(debouncer: Debouncer, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: Pubkey, evs: [NostrEvent]) -> NewEventsBits? {
|
||||||
var inserted = false
|
var inserted = false
|
||||||
|
|
||||||
var new_events: NewEventsBits? = nil
|
var new_events: NewEventsBits? = nil
|
||||||
|
|
||||||
for ev in evs {
|
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
|
inserted = res.0 || inserted
|
||||||
if let new = res.1 {
|
if let new = res.1 {
|
||||||
new_events = new
|
new_events = new
|
||||||
@ -1101,11 +1102,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
|
/// 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)
|
let last_ev = get_last_event(timeline)
|
||||||
|
|
||||||
if last_ev == nil || last_ev!.created_at < ev.created_at {
|
if last_ev == nil || last_ev!.created_at < ev.created_at {
|
||||||
|
if let debouncer {
|
||||||
|
debouncer.debounce {
|
||||||
save_last_event(ev, timeline: timeline)
|
save_last_event(ev, timeline: timeline)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
save_last_event(ev, timeline: timeline)
|
||||||
|
}
|
||||||
if shouldNotify {
|
if shouldNotify {
|
||||||
return new_events.union(timeline_to_notification_bits(timeline, ev: ev))
|
return new_events.union(timeline_to_notification_bits(timeline, ev: ev))
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ struct DMChatView: View, KeyboardReadable {
|
|||||||
|
|
||||||
damus_state.postbox.send(dm)
|
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()
|
end_editing()
|
||||||
}
|
}
|
||||||
|
@ -48,55 +48,56 @@ final class DMTests: XCTestCase {
|
|||||||
let now = UInt32(Date().timeIntervalSince1970)
|
let now = UInt32(Date().timeIntervalSince1970)
|
||||||
|
|
||||||
let alice_to_bob = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now)!
|
let alice_to_bob = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
|
let debouncer = Debouncer(interval: 3.0)
|
||||||
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 1)
|
XCTAssertEqual(model.dms.count, 1)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
||||||
|
|
||||||
let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 1)!
|
let bob_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 1)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 1)
|
XCTAssertEqual(model.dms.count, 1)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
||||||
|
|
||||||
let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now + 2)!
|
let alice_to_bob_2 = create_dm("hi bob", to_pk: bob.pubkey, tags: [["p", bob.pubkey]], keypair: alice, created_at: now + 2)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [alice_to_bob_2])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 1)
|
XCTAssertEqual(model.dms.count, 1)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
||||||
|
|
||||||
let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: fiatjaf, created_at: now+5)!
|
let fiatjaf_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: fiatjaf, created_at: now+5)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [fiatjaf_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 2)
|
XCTAssertEqual(model.dms.count, 2)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, fiatjaf.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, fiatjaf.pubkey)
|
||||||
|
|
||||||
let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: dave, created_at: now + 10)!
|
let dave_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: dave, created_at: now + 10)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [dave_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 3)
|
XCTAssertEqual(model.dms.count, 3)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, dave.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, dave.pubkey)
|
||||||
|
|
||||||
let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 15)!
|
let bob_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 15)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_2])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 3)
|
XCTAssertEqual(model.dms.count, 3)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
||||||
|
|
||||||
let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 20)!
|
let charlie_to_alice = create_dm("hi alice", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 20)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 4)
|
XCTAssertEqual(model.dms.count, 4)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
|
||||||
|
|
||||||
let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 25)!
|
let bob_to_alice_3 = create_dm("hi alice 3", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: bob, created_at: now + 25)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [bob_to_alice_3])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 4)
|
XCTAssertEqual(model.dms.count, 4)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, bob.pubkey)
|
||||||
|
|
||||||
let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 30)!
|
let charlie_to_alice_2 = create_dm("hi alice 2", to_pk: alice.pubkey, tags: [["p", alice.pubkey]], keypair: charlie, created_at: now + 30)!
|
||||||
handle_incoming_dms(prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2])
|
handle_incoming_dms(debouncer: debouncer, prev_events: notif, dms: model, our_pubkey: alice.pubkey, evs: [charlie_to_alice_2])
|
||||||
|
|
||||||
XCTAssertEqual(model.dms.count, 4)
|
XCTAssertEqual(model.dms.count, 4)
|
||||||
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
|
XCTAssertEqual(model.dms[0].pubkey, charlie.pubkey)
|
||||||
|
Loading…
Reference in New Issue
Block a user