damus

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

commit 61ef709d91c162e4a63407b7ce31b6d562c6f14c
parent f6133814e8a4983ca10c2c6f0b0ee84eb2ecadca
Author: Swift <scoder1747@gmail.com>
Date:   Wed, 29 Mar 2023 19:19:41 -0400

Local notifications for other events

Changelog-Added: Added local notifications for other events

Diffstat:
Mdamus/Models/HomeModel.swift | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mdamus/Models/UserSettingsStore.swift | 35+++++++++++++++++++++++++++++++++++
Mdamus/Views/ConfigView.swift | 41+++++++++++++++++++++++++++++++----------
3 files changed, 147 insertions(+), 14 deletions(-)

diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift @@ -150,8 +150,10 @@ class HomeModel: ObservableObject { // Generate zap vibration zap_vibrate(zap_amount: zap.invoice.amount) } - // Create in-app local notification for zap received. - create_in_app_zap_notification(profiles: profiles, zap: zap) + if damus_state.settings.zap_notification { + // Create in-app local notification for zap received. + create_in_app_zap_notification(profiles: profiles, zap: zap) + } } return @@ -487,7 +489,40 @@ class HomeModel: ObservableObject { return } - handle_last_event(ev: ev, timeline: .notifications) + if handle_last_event(ev: ev, timeline: .notifications), + damus_state.contacts.follow_state(ev.pubkey) == .follows, + let type = ev.known_kind { + + if type == .text, + damus_state.settings.mention_notification { + for block in ev.blocks(damus_state.keypair.privkey) { + if case .mention(let mention) = block, mention.ref.ref_id == damus_state.keypair.pubkey, + let displayName = damus_state.profiles.lookup(id: ev.pubkey)?.display_name { + let justContent = NSAttributedString(render_note_content(ev: ev, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey).content).string + create_notification(displayName: displayName, conversation: justContent, type: type) + } + } + } else if type == .boost, + damus_state.settings.repost_notification, + let displayName = damus_state.profiles.lookup(id: ev.pubkey)?.display_name { + + let justContent = NSAttributedString(render_note_content(ev: ev, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey).content).string + if let jsonData = justContent.data(using: .utf8), + let jsonDict = try? JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any], + let content = jsonDict["content"] as? String { + create_notification(displayName: displayName, conversation: content, type: type) + } + + } else if type == .like, + damus_state.settings.like_notification, + let displayName = damus_state.profiles.lookup(id: ev.pubkey)?.display_name, + let eRef = ev.referenced_ids.eRefs.first?.ref_id, + let content = damus_state.events.lookup(eRef)?.content { + + create_notification(displayName: displayName, conversation: content, type: type) + } + } + } @discardableResult @@ -506,6 +541,44 @@ class HomeModel: ObservableObject { } } + func create_notification(displayName: String, conversation: String, type: NostrKind) { + let content = UNMutableNotificationContent() + var title = "" + var identifier = "" + switch type { + case .text: + title = String(format: NSLocalizedString("Mentioned by %@", comment: "Mentioned by heading in local notification"), displayName) + identifier = "myMentionNotification" + case .boost: + title = String(format: NSLocalizedString("Reposted by %@", comment: "Reposted by heading in local notification"), displayName) + identifier = "myBoostNotification" + case .like: + title = String(format: NSLocalizedString("Liked by %@", comment: "Liked by heading in local notification"), displayName) + identifier = "myLikeNotification" + case .dm: + title = String(format: NSLocalizedString("DM by %@", comment: "DM by heading in local notification"), displayName) + identifier = "myDMNotification" + default: + break + } + content.title = title + content.body = conversation + content.sound = UNNotificationSound.default + + let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) + + let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) + + UNUserNotificationCenter.current().add(request) { error in + if let error = error { + print("Error: \(error)") + } else { + print("Local notification scheduled") + } + } + } + + func handle_text_event(sub_id: String, _ ev: NostrEvent) { guard should_show_event(contacts: damus_state.contacts, ev: ev) else { return @@ -536,9 +609,13 @@ class HomeModel: ObservableObject { incoming_dms.append(ev) - dm_debouncer.debounce { + dm_debouncer.debounce { [self] in if let notifs = handle_incoming_dms(prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) { self.new_events = notifs + if damus_state.settings.dm_notification, + let displayName = damus_state.profiles.lookup(id: self.incoming_dms.last!.pubkey)?.display_name { + create_notification(displayName: displayName, conversation: "You have received a direct message", type: .dm) + } } self.incoming_dms = [] } diff --git a/damus/Models/UserSettingsStore.swift b/damus/Models/UserSettingsStore.swift @@ -128,6 +128,36 @@ class UserSettingsStore: ObservableObject { } } + @Published var zap_notification: Bool { + didSet { + UserDefaults.standard.set(zap_notification, forKey: "zap_notification") + } + } + + @Published var mention_notification: Bool { + didSet { + UserDefaults.standard.set(mention_notification, forKey: "mention_notification") + } + } + + @Published var repost_notification: Bool { + didSet { + UserDefaults.standard.set(repost_notification, forKey: "repost_notification") + } + } + + @Published var dm_notification: Bool { + didSet { + UserDefaults.standard.set(repost_notification, forKey: "dm_notification") + } + } + + @Published var like_notification: Bool { + didSet { + UserDefaults.standard.set(like_notification, forKey: "like_notification") + } + } + @Published var truncate_timeline_text: Bool { didSet { UserDefaults.standard.set(truncate_timeline_text, forKey: "truncate_timeline_text") @@ -227,6 +257,11 @@ class UserSettingsStore: ObservableObject { left_handed = UserDefaults.standard.object(forKey: "left_handed") as? Bool ?? false zap_vibration = UserDefaults.standard.object(forKey: "zap_vibration") as? Bool ?? false + zap_notification = UserDefaults.standard.object(forKey: "zap_notification") as? Bool ?? true + mention_notification = UserDefaults.standard.object(forKey: "mention_notification") as? Bool ?? true + repost_notification = UserDefaults.standard.object(forKey: "repost_notification") as? Bool ?? true + like_notification = UserDefaults.standard.object(forKey: "like_notification") as? Bool ?? true + dm_notification = UserDefaults.standard.object(forKey: "dm_notification") as? Bool ?? true truncate_timeline_text = UserDefaults.standard.object(forKey: "truncate_timeline_text") as? Bool ?? false disable_animation = should_disable_image_animation() auto_translate = UserDefaults.standard.object(forKey: "auto_translate") as? Bool ?? true diff --git a/damus/Views/ConfigView.swift b/damus/Views/ConfigView.swift @@ -132,7 +132,7 @@ struct ConfigView: View { } } - Section(NSLocalizedString("Wallet Selector", comment: "Section title for selection of wallet.")) { + Section(NSLocalizedString("Wallet and others", comment: "Section header for miscellaneous user configuration")) { Toggle(NSLocalizedString("Show wallet selector", comment: "Toggle to show or hide selection of wallet."), isOn: $settings.show_wallet_selector).toggleStyle(.switch) Picker(NSLocalizedString("Select default wallet", comment: "Prompt selection of user's default wallet"), selection: $settings.default_wallet) { @@ -141,8 +141,17 @@ struct ConfigView: View { .tag(wallet.model.tag) } } + Toggle(NSLocalizedString("Left Handed", comment: "Moves the post button to the left side of the screen"), isOn: $settings.left_handed) + .toggleStyle(.switch) + Toggle(NSLocalizedString("Zap Vibration", comment: "Setting to enable vibration on zap"), isOn: $settings.zap_vibration) + .toggleStyle(.switch) } + NavigationLink(destination: NotificationView(settings: settings)) { + Section(NSLocalizedString("Local Notifications", comment: "Section header for damus local notifications user configuration")) { + } + } + Section(NSLocalizedString("Default Zap Amount in sats", comment: "Section title for zap configuration")) { TextField(String("1000"), text: $default_zap_amount) .keyboardType(.numberPad) @@ -209,15 +218,6 @@ struct ConfigView: View { } } - Section(NSLocalizedString("Miscellaneous", comment: "Section header for miscellaneous user configuration")) { - Toggle(NSLocalizedString("Left Handed", comment: "Moves the post button to the left side of the screen"), isOn: $settings.left_handed) - .toggleStyle(.switch) - Toggle(NSLocalizedString("Zap Vibration", comment: "Setting to enable vibration on zap"), isOn: $settings.zap_vibration) - .toggleStyle(.switch) - Toggle(NSLocalizedString("Truncate text in timeline", comment: "Truncate text in timeline"), isOn: $settings.truncate_timeline_text) - .toggleStyle(.switch) - } - Section(NSLocalizedString("Images", comment: "Section title for images configuration.")) { Toggle(NSLocalizedString("Disable animations", comment: "Button to disable image animation"), isOn: $settings.disable_animation) .toggleStyle(.switch) @@ -390,6 +390,27 @@ struct ConfigView: View { } } +struct NotificationView: View { + @ObservedObject var settings: UserSettingsStore + + var body: some View { + Form { + Section(header: Text(NSLocalizedString("Local Notifications", comment: "Section header for damus local notifications user configuration"))) { + Toggle(NSLocalizedString("Zap Notification", comment: "Setting to enable Zap Local Notification"), isOn: $settings.zap_notification) + .toggleStyle(.switch) + Toggle(NSLocalizedString("Mention Notification", comment: "Setting to enable Mention Local Notification"), isOn: $settings.mention_notification) + .toggleStyle(.switch) + Toggle(NSLocalizedString("Repost Notification", comment: "Setting to enable Repost Local Notification"), isOn: $settings.repost_notification) + .toggleStyle(.switch) + Toggle(NSLocalizedString("Like Notification", comment: "Setting to enable Like Local Notification"), isOn: $settings.like_notification) + .toggleStyle(.switch) + Toggle(NSLocalizedString("DM Notification", comment: "Setting to enable DM Local Notification"), isOn: $settings.dm_notification) + .toggleStyle(.switch) + } + } + } +} + struct ConfigView_Previews: PreviewProvider { static var previews: some View { NavigationView {