From 6d5a152c17a8474a89b5f178048779fd86ccc8aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=E2=80=99Aquino?= Date: Fri, 26 Apr 2024 23:13:47 +0000 Subject: [PATCH] Fix Ghost notifications from Damus Purple Impending expiration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit fixes the "ghost notifications" experienced by Purple users whose membership has expired (or about to expire). It does that by using a similar mechanism as other notifications to keep track of the last event date seen on the notifications tab in a persistent way. Testing -------- iOS: 17.4 Device: iPhone 15 simulator damus-api: bfe6c4240a0b3729724162896f0024a963586f7c Damus: This commit Setup: 1. Local Purple server 2. Damus running on local testing mode for Purple 3. An existing but expired Purple account (on the local server) Steps: 1. Reopen app after pointing to the new server and setting things up. 2. Check that the bell icon shows there is a new notification. PASS 3. Check that purple expiration notifications are visible. PASS 4. Restart app. 5. Check the bell icon. This time there should be no new notifications. PASS 6. Using another account, engage with the primary test account to cause a new notification to appear. 7. After a second or two, the bell icon should indicate there is a new notification from the other user. PASS 8. Switch out and into the app. Check that the bell icon does not indicate any new notifications. PASS 9. Restart the app again. The bell icon should once again NOT indicate any new notifications. PASS Changelog-Fixed: Fix ghost notifications caused by Purple impending expiration notifications Closes: https://github.com/damus-io/damus/issues/2158 Signed-off-by: Daniel D’Aquino Reviewed-by: William Casarin --- damus/ContentView.swift | 6 ++++++ damus/Models/HomeModel.swift | 11 ++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/damus/ContentView.swift b/damus/ContentView.swift index e8efd7d2..b8619102 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -832,6 +832,12 @@ func save_last_event(_ ev: NostrEvent, timeline: Timeline) { UserDefaults.standard.set(String(ev.created_at), forKey: "last_\(str)_time") } +func save_last_event(_ ev_id: NoteId, created_at: UInt32, timeline: Timeline) { + let str = timeline.rawValue + UserDefaults.standard.set(ev_id.hex(), forKey: "last_\(str)") + UserDefaults.standard.set(String(created_at), forKey: "last_\(str)_time") +} + func update_filters_with_since(last_of_kind: [UInt32: NostrEvent], filters: [NostrFilter]) -> [NostrFilter] { return filters.map { filter in diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift index ee460ad0..82d5bde1 100644 --- a/damus/Models/HomeModel.swift +++ b/damus/Models/HomeModel.swift @@ -309,9 +309,14 @@ class HomeModel: ContactsDelegate { @MainActor func handle_damus_app_notification(_ notification: DamusAppNotification) async { if self.notifications.insert_app_notification(notification: notification) { - // If we successfully inserted a new Damus App notification, switch ON the Damus App notification bit on our NewsEventsBits - // This will cause the bell icon on the tab bar to display the purple dot indicating there is an unread notification - self.notification_status.new_events = NewEventsBits(rawValue: self.notification_status.new_events.rawValue | NewEventsBits.damus_app_notifications.rawValue) + let last_notification = get_last_event(.notifications) + if last_notification == nil || last_notification!.created_at < notification.last_event_at { + save_last_event(NoteId.empty, created_at: notification.last_event_at, timeline: .notifications) + // If we successfully inserted a new Damus App notification, switch ON the Damus App notification bit on our NewsEventsBits + // This will cause the bell icon on the tab bar to display the purple dot indicating there is an unread notification + self.notification_status.new_events = NewEventsBits(rawValue: self.notification_status.new_events.rawValue | NewEventsBits.damus_app_notifications.rawValue) + } + return } }