damus

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

commit 0a9bcb6189251e1f0a27f3378c318a9e40d59923
parent 5a68cfa448f6ecbb29a0d4aef3e4a288ab25178b
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Wed, 15 May 2024 16:47:16 -0700

Add notification mode setting

This allows the user to switch between local and push notifications

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>

Diffstat:
MDamusNotificationService/NotificationService.swift | 2+-
Mdamus/Models/HomeModel.swift | 2+-
Mdamus/Models/NotificationsManager.swift | 9+++++++--
Mdamus/Models/UserSettingsStore.swift | 33+++++++++++++++++++++++++++++++++
Mdamus/Views/Settings/NotificationSettingsView.swift | 11+++++++++++
Mdamus/damusApp.swift | 2+-
6 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/DamusNotificationService/NotificationService.swift b/DamusNotificationService/NotificationService.swift @@ -53,7 +53,7 @@ class NotificationService: UNNotificationServiceExtension { return } - guard should_display_notification(state: state, event: nostr_event) else { + guard should_display_notification(state: state, event: nostr_event, mode: .push) else { // We should not display notification for this event. Suppress notification. // contentHandler(UNNotificationContent()) // TODO: We cannot really suppress until we have the notification supression entitlement. Show the raw notification diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -733,7 +733,7 @@ class HomeModel: ContactsDelegate { func got_new_dm(notifs: NewEventsBits, ev: NostrEvent) { notification_status.new_events = notifs - guard should_display_notification(state: damus_state, event: ev), + guard should_display_notification(state: damus_state, event: ev, mode: .local), let notification_object = generate_local_notification_object(from: ev, state: damus_state) else { return diff --git a/damus/Models/NotificationsManager.swift b/damus/Models/NotificationsManager.swift @@ -13,7 +13,7 @@ import UIKit let EVENT_MAX_AGE_FOR_NOTIFICATION: TimeInterval = 12 * 60 * 60 func process_local_notification(state: HeadlessDamusState, event ev: NostrEvent) { - guard should_display_notification(state: state, event: ev) else { + guard should_display_notification(state: state, event: ev, mode: .local) else { // We should not display notification. Exit. return } @@ -25,7 +25,12 @@ func process_local_notification(state: HeadlessDamusState, event ev: NostrEvent) create_local_notification(profiles: state.profiles, notify: local_notification) } -func should_display_notification(state: HeadlessDamusState, event ev: NostrEvent) -> Bool { +func should_display_notification(state: HeadlessDamusState, event ev: NostrEvent, mode: UserSettingsStore.NotificationsMode) -> Bool { + // Do not show notification if it's coming from a mode different from the one selected by our user + guard state.settings.notifications_mode == mode else { + return false + } + if ev.known_kind == nil { return false } diff --git a/damus/Models/UserSettingsStore.swift b/damus/Models/UserSettingsStore.swift @@ -155,6 +155,9 @@ class UserSettingsStore: ObservableObject { @Setting(key: "like_notification", default_value: true) var like_notification: Bool + @StringSetting(key: "notifications_mode", default_value: .local) + var notifications_mode: NotificationsMode + @Setting(key: "notification_only_from_following", default_value: false) var notification_only_from_following: Bool @@ -326,6 +329,36 @@ class UserSettingsStore: ObservableObject { @Setting(key: "latest_contact_event_id", default_value: nil) var latest_contact_event_id_hex: String? + + // MARK: Helper types + + enum NotificationsMode: String, CaseIterable, Identifiable, StringCodable, Equatable { + var id: String { self.rawValue } + + func to_string() -> String { + return rawValue + } + + init?(from string: String) { + guard let notifications_mode = NotificationsMode(rawValue: string) else { + return nil + } + self = notifications_mode + } + + func text_description() -> String { + switch self { + case .local: + NSLocalizedString("Local", comment: "Option for notification mode setting: Local notification mode") + case .push: + NSLocalizedString("Push", comment: "Option for notification mode setting: Push notification mode") + } + } + + case local + case push + } + } func pk_setting_key(_ pubkey: Pubkey, key: String) -> String { diff --git a/damus/Views/Settings/NotificationSettingsView.swift b/damus/Views/Settings/NotificationSettingsView.swift @@ -26,6 +26,17 @@ struct NotificationSettingsView: View { var body: some View { Form { + if settings.enable_experimental_push_notifications { + Picker(NSLocalizedString("Notifications mode", comment: "Prompt selection of the notification mode (Feature to switch between local notifications (generated from user's own phone) or push notifications (generated by Damus server)."), + selection: Binding($settings.notifications_mode) + ) { + ForEach(UserSettingsStore.NotificationsMode.allCases, id: \.self) { notification_mode in + Text(notification_mode.text_description()) + .tag(notification_mode.rawValue) + } + } + } + Section(header: Text("Local Notifications", comment: "Section header for damus local notifications user configuration")) { Toggle(NSLocalizedString("Zaps", comment: "Setting to enable Zap Local Notification"), isOn: $settings.zap_notification) .toggleStyle(.switch) diff --git a/damus/damusApp.swift b/damus/damusApp.swift @@ -73,7 +73,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // Return if this feature is disabled guard let settings = self.settings else { return } - if !settings.enable_experimental_push_notifications { + if !settings.enable_experimental_push_notifications || settings.notifications_mode == .local { return }