perf: debounce incoming dms
This fixes perf issues on startup if you have lots of dms Changelog-Fixed: Fix lag on startup when you have lots of DMs Changelog-Fixed: Fix an issues where dm notifications appear without any new events
This commit is contained in:
@@ -42,6 +42,7 @@
|
|||||||
4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */; };
|
4C285C8A2838B985008A31F1 /* ProfilePictureSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */; };
|
||||||
4C285C8C28398BC7008A31F1 /* Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8B28398BC6008A31F1 /* Keys.swift */; };
|
4C285C8C28398BC7008A31F1 /* Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8B28398BC6008A31F1 /* Keys.swift */; };
|
||||||
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */; };
|
4C285C8E28399BFE008A31F1 /* SaveKeysView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */; };
|
||||||
|
4C2CDDF7299D4A5E00879FD5 /* Debouncer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C2CDDF6299D4A5E00879FD5 /* Debouncer.swift */; };
|
||||||
4C363A8428233689006E126D /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8328233689006E126D /* Parser.swift */; };
|
4C363A8428233689006E126D /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8328233689006E126D /* Parser.swift */; };
|
||||||
4C363A8828236948006E126D /* BlocksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8728236948006E126D /* BlocksView.swift */; };
|
4C363A8828236948006E126D /* BlocksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8728236948006E126D /* BlocksView.swift */; };
|
||||||
4C363A8A28236B57006E126D /* MentionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8928236B57006E126D /* MentionView.swift */; };
|
4C363A8A28236B57006E126D /* MentionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C363A8928236B57006E126D /* MentionView.swift */; };
|
||||||
@@ -312,6 +313,7 @@
|
|||||||
4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePictureSelector.swift; sourceTree = "<group>"; };
|
4C285C892838B985008A31F1 /* ProfilePictureSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfilePictureSelector.swift; sourceTree = "<group>"; };
|
||||||
4C285C8B28398BC6008A31F1 /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
|
4C285C8B28398BC6008A31F1 /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
|
||||||
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveKeysView.swift; sourceTree = "<group>"; };
|
4C285C8D28399BFD008A31F1 /* SaveKeysView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveKeysView.swift; sourceTree = "<group>"; };
|
||||||
|
4C2CDDF6299D4A5E00879FD5 /* Debouncer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debouncer.swift; sourceTree = "<group>"; };
|
||||||
4C363A8328233689006E126D /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
|
4C363A8328233689006E126D /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
|
||||||
4C363A8728236948006E126D /* BlocksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocksView.swift; sourceTree = "<group>"; };
|
4C363A8728236948006E126D /* BlocksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlocksView.swift; sourceTree = "<group>"; };
|
||||||
4C363A8928236B57006E126D /* MentionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionView.swift; sourceTree = "<group>"; };
|
4C363A8928236B57006E126D /* MentionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MentionView.swift; sourceTree = "<group>"; };
|
||||||
@@ -780,6 +782,7 @@
|
|||||||
4CB883A72975FC1800DC99E7 /* Zaps.swift */,
|
4CB883A72975FC1800DC99E7 /* Zaps.swift */,
|
||||||
4CB883B5297730E400DC99E7 /* LNUrls.swift */,
|
4CB883B5297730E400DC99E7 /* LNUrls.swift */,
|
||||||
3AB72AB8298ECF30004BB58C /* Translator.swift */,
|
3AB72AB8298ECF30004BB58C /* Translator.swift */,
|
||||||
|
4C2CDDF6299D4A5E00879FD5 /* Debouncer.swift */,
|
||||||
);
|
);
|
||||||
path = Util;
|
path = Util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1342,6 +1345,7 @@
|
|||||||
4CE879552996BAB900F758CC /* RelayPaidDetail.swift in Sources */,
|
4CE879552996BAB900F758CC /* RelayPaidDetail.swift in Sources */,
|
||||||
4CF0ABD42980996B00D66079 /* Report.swift in Sources */,
|
4CF0ABD42980996B00D66079 /* Report.swift in Sources */,
|
||||||
4C06670B28FDE64700038D2A /* damus.c in Sources */,
|
4C06670B28FDE64700038D2A /* damus.c in Sources */,
|
||||||
|
4C2CDDF7299D4A5E00879FD5 /* Debouncer.swift in Sources */,
|
||||||
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */,
|
3AAA95CC298E07E900F3D526 /* DeepLPlan.swift in Sources */,
|
||||||
4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */,
|
4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */,
|
||||||
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */,
|
3AA247FF297E3D900090C62D /* RepostsView.swift in Sources */,
|
||||||
|
|||||||
@@ -38,6 +38,9 @@ class HomeModel: ObservableObject {
|
|||||||
var channels: [String: NostrEvent] = [:]
|
var channels: [String: NostrEvent] = [:]
|
||||||
var last_event_of_kind: [String: [Int: NostrEvent]] = [:]
|
var last_event_of_kind: [String: [Int: NostrEvent]] = [:]
|
||||||
var done_init: Bool = false
|
var done_init: Bool = false
|
||||||
|
var incoming_dms: [NostrEvent] = []
|
||||||
|
let dm_debouncer = Debouncer(interval: 0.5)
|
||||||
|
var should_debounce_dms = true
|
||||||
|
|
||||||
let home_subid = UUID().description
|
let home_subid = UUID().description
|
||||||
let contacts_subid = UUID().description
|
let contacts_subid = UUID().description
|
||||||
@@ -56,16 +59,25 @@ class HomeModel: ObservableObject {
|
|||||||
init() {
|
init() {
|
||||||
self.damus_state = DamusState.empty
|
self.damus_state = DamusState.empty
|
||||||
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
|
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
|
||||||
|
self.setup_debouncer()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(damus_state: DamusState) {
|
init(damus_state: DamusState) {
|
||||||
self.damus_state = damus_state
|
self.damus_state = damus_state
|
||||||
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
|
self.dms = DirectMessagesModel(our_pubkey: damus_state.pubkey)
|
||||||
|
self.setup_debouncer()
|
||||||
}
|
}
|
||||||
|
|
||||||
var pool: RelayPool {
|
var pool: RelayPool {
|
||||||
return damus_state.pool
|
return damus_state.pool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setup_debouncer() {
|
||||||
|
// turn off debouncer after initial load
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
|
||||||
|
self.should_debounce_dms = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func has_sub_id_event(sub_id: String, ev_id: String) -> Bool {
|
func has_sub_id_event(sub_id: String, ev_id: String) -> Bool {
|
||||||
if !has_event.keys.contains(sub_id) {
|
if !has_event.keys.contains(sub_id) {
|
||||||
@@ -303,7 +315,8 @@ class HomeModel: ObservableObject {
|
|||||||
case .eose(let sub_id):
|
case .eose(let sub_id):
|
||||||
|
|
||||||
if sub_id == dms_subid {
|
if sub_id == dms_subid {
|
||||||
let dms = dms.dms.flatMap { $0.1.events }
|
var dms = dms.dms.flatMap { $0.1.events }
|
||||||
|
dms.append(contentsOf: incoming_dms)
|
||||||
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: dms, damus_state: damus_state)
|
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: dms, damus_state: damus_state)
|
||||||
} else if sub_id == notifications_subid {
|
} else if sub_id == notifications_subid {
|
||||||
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: notifications, damus_state: damus_state)
|
load_profiles(profiles_subid: profiles_subid, relay_id: relay_id, events: notifications, damus_state: damus_state)
|
||||||
@@ -477,10 +490,28 @@ class HomeModel: ObservableObject {
|
|||||||
handle_notification(ev: ev)
|
handle_notification(ev: ev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle_dm(_ ev: NostrEvent) {
|
func handle_dm(_ ev: NostrEvent) {
|
||||||
if let notifs = handle_incoming_dm(contacts: damus_state.contacts, prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, ev: ev) {
|
guard should_show_event(contacts: damus_state.contacts, ev: ev) else {
|
||||||
self.new_events = notifs
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !should_debounce_dms {
|
||||||
|
self.incoming_dms.append(ev)
|
||||||
|
if let notifs = handle_incoming_dms(contacts: self.damus_state.contacts, prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
|
||||||
|
self.new_events = notifs
|
||||||
|
}
|
||||||
|
self.incoming_dms = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
incoming_dms.append(ev)
|
||||||
|
|
||||||
|
dm_debouncer.debounce {
|
||||||
|
if let notifs = handle_incoming_dms(contacts: self.damus_state.contacts, prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
|
||||||
|
self.new_events = notifs
|
||||||
|
}
|
||||||
|
self.incoming_dms = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -761,14 +792,10 @@ func fetch_relay_metadata(relay_id: String) async throws -> RelayMetadata? {
|
|||||||
func process_relay_metadata() {
|
func process_relay_metadata() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func handle_incoming_dm(contacts: Contacts, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, ev: NostrEvent) -> NewEventsBits? {
|
func handle_incoming_dm(ev: NostrEvent, our_pubkey: String, dms: DirectMessagesModel, prev_events: NewEventsBits) -> (Bool, NewEventsBits?) {
|
||||||
// hide blocked users
|
|
||||||
guard should_show_event(contacts: contacts, ev: ev) else {
|
|
||||||
return prev_events
|
|
||||||
}
|
|
||||||
|
|
||||||
var inserted = false
|
var inserted = false
|
||||||
var found = false
|
var found = false
|
||||||
|
|
||||||
let ours = ev.pubkey == our_pubkey
|
let ours = ev.pubkey == our_pubkey
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
||||||
@@ -795,15 +822,32 @@ func handle_incoming_dm(contacts: Contacts, prev_events: NewEventsBits, dms: Dir
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
inserted = true
|
|
||||||
let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey)
|
let model = DirectMessageModel(events: [ev], our_pubkey: our_pubkey)
|
||||||
dms.dms.append((the_pk, model))
|
dms.dms.append((the_pk, model))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var new_bits: NewEventsBits? = nil
|
||||||
|
if inserted {
|
||||||
|
new_bits = handle_last_events(new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (inserted, new_bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handle_incoming_dms(contacts: Contacts, prev_events: NewEventsBits, dms: DirectMessagesModel, our_pubkey: String, evs: [NostrEvent]) -> NewEventsBits? {
|
||||||
|
var inserted = false
|
||||||
|
|
||||||
var new_events: NewEventsBits? = nil
|
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)
|
||||||
|
inserted = res.0 || inserted
|
||||||
|
if let new = res.1 {
|
||||||
|
new_events = new
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if inserted {
|
if inserted {
|
||||||
new_events = handle_last_events(new_events: prev_events, ev: ev, timeline: .dms, shouldNotify: !ours)
|
|
||||||
|
|
||||||
dms.dms = dms.dms.filter({ $0.1.events.count > 0 }).sorted { a, b in
|
dms.dms = dms.dms.filter({ $0.1.events.count > 0 }).sorted { a, b in
|
||||||
return a.1.events.last!.created_at > b.1.events.last!.created_at
|
return a.1.events.last!.created_at > b.1.events.last!.created_at
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user