Prevent publishing changes to Observable outside the main thread

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
This commit is contained in:
Daniel D’Aquino
2025-08-29 15:57:25 -07:00
parent 9709e69dda
commit 0f26d50e08
6 changed files with 30 additions and 11 deletions

View File

@@ -78,7 +78,11 @@ class EventsModel: ObservableObject {
event = ev.toOwned() event = ev.toOwned()
} }
guard let event else { return } guard let event else { return }
if events.insert(event) { objectWillChange.send() } Task {
if await events.insert(event) {
DispatchQueue.main.async { self.objectWillChange.send() }
}
}
case .eose: case .eose:
break break
} }
@@ -93,6 +97,7 @@ class EventsModel: ObservableObject {
loadingTask?.cancel() loadingTask?.cancel()
} }
@MainActor
private func handle_event(relay_id: RelayURL, ev: NostrEvent) { private func handle_event(relay_id: RelayURL, ev: NostrEvent) {
if events.insert(ev) { if events.insert(ev) {
objectWillChange.send() objectWillChange.send()

View File

@@ -25,6 +25,7 @@ class FollowPackModel: ObservableObject {
func subscribe(follow_pack_users: [Pubkey]) { func subscribe(follow_pack_users: [Pubkey]) {
loading = true loading = true
self.listener?.cancel()
self.listener = Task { self.listener = Task {
await self.listenForUpdates(follow_pack_users: follow_pack_users) await self.listenForUpdates(follow_pack_users: follow_pack_users)
} }
@@ -52,8 +53,10 @@ class FollowPackModel: ObservableObject {
guard let event else { return } guard let event else { return }
if event.is_textlike && should_show_event(state: damus_state, ev: event) && !event.is_reply() if event.is_textlike && should_show_event(state: damus_state, ev: event) && !event.is_reply()
{ {
if self.events.insert(event) { if await self.events.insert(event) {
self.objectWillChange.send() DispatchQueue.main.async {
self.objectWillChange.send()
}
} }
} }
case .eose: case .eose:

View File

@@ -67,18 +67,21 @@ class NIP05DomainEventsModel: ObservableObject {
for await item in state.nostrNetwork.reader.subscribe(filters: [filter]) { for await item in state.nostrNetwork.reader.subscribe(filters: [filter]) {
switch item { switch item {
case .event(borrow: let borrow): case .event(borrow: let borrow):
try? borrow { event in var event: NostrEvent? = nil
self.add_event(event.toOwned()) try? borrow { ev in
event = ev.toOwned()
guard let txn = NdbTxn(ndb: state.ndb) else { return } guard let txn = NdbTxn(ndb: state.ndb) else { return }
load_profiles(context: "search", load: .from_events(self.events.all_events), damus_state: state, txn: txn) load_profiles(context: "search", load: .from_events(self.events.all_events), damus_state: state, txn: txn)
} }
guard let event else { return }
await self.add_event(event)
case .eose: case .eose:
continue continue
} }
} }
} }
func add_event(_ ev: NostrEvent) { func add_event(_ ev: NostrEvent) async {
if !event_matches_filter(ev, filter: filter) { if !event_matches_filter(ev, filter: filter) {
return return
} }
@@ -87,8 +90,10 @@ class NIP05DomainEventsModel: ObservableObject {
return return
} }
if self.events.insert(ev) { if await self.events.insert(ev) {
objectWillChange.send() DispatchQueue.main.async {
self.objectWillChange.send()
}
} }
} }
} }

View File

@@ -49,7 +49,7 @@ class SearchModel: ObservableObject {
try? borrow { ev in try? borrow { ev in
let event = ev.toOwned() let event = ev.toOwned()
if event.is_textlike && event.should_show_event { if event.is_textlike && event.should_show_event {
self.add_event(event) Task { await self.add_event(event) }
} }
} }
case .eose: case .eose:
@@ -67,6 +67,7 @@ class SearchModel: ObservableObject {
listener = nil listener = nil
} }
@MainActor
func add_event(_ ev: NostrEvent) { func add_event(_ ev: NostrEvent) {
if !event_matches_filter(ev, filter: search) { if !event_matches_filter(ev, filter: search) {
return return

View File

@@ -765,6 +765,7 @@ class HomeModel: ContactsDelegate {
} }
} }
@MainActor
func insert_home_event(_ ev: NostrEvent) { func insert_home_event(_ ev: NostrEvent) {
if events.insert(ev) { if events.insert(ev) {
handle_last_event(ev: ev, timeline: .home) handle_last_event(ev: ev, timeline: .home)
@@ -798,7 +799,7 @@ class HomeModel: ContactsDelegate {
switch context { switch context {
case .home: case .home:
insert_home_event(ev) Task { await insert_home_event(ev) }
case .notifications: case .notifications:
handle_notification(ev: ev) handle_notification(ev: ev)
case .dms, .contacts, .initialRelayList, .initialContactList, .nwc: case .dms, .contacts, .initialRelayList, .initialContactList, .nwc:

View File

@@ -38,6 +38,7 @@ class EventHolder: ObservableObject, ScrollQueue {
self.incoming = self.incoming.filter(isIncluded) self.incoming = self.incoming.filter(isIncluded)
} }
@MainActor
func insert(_ ev: NostrEvent) -> Bool { func insert(_ ev: NostrEvent) -> Bool {
if should_queue { if should_queue {
return insert_queued(ev) return insert_queued(ev)
@@ -46,6 +47,7 @@ class EventHolder: ObservableObject, ScrollQueue {
} }
} }
@MainActor
private func insert_immediate(_ ev: NostrEvent) -> Bool { private func insert_immediate(_ ev: NostrEvent) -> Bool {
if has_event.contains(ev.id) { if has_event.contains(ev.id) {
return false return false
@@ -86,7 +88,9 @@ class EventHolder: ObservableObject, ScrollQueue {
} }
if changed { if changed {
self.objectWillChange.send() DispatchQueue.main.async {
self.objectWillChange.send()
}
} }
self.incoming = [] self.incoming = []