Add deep links for local notifications

Allow notifications to be clickable

Changelog-Added: Add deep links for local notifications
Co-authored-by: William Casarin <jb55@jb55.com>
Closes: #880
This commit is contained in:
Swift
2023-04-05 18:24:58 -04:00
committed by William Casarin
parent b5a3697d78
commit 05d332eac3
4 changed files with 58 additions and 22 deletions

View File

@@ -473,6 +473,29 @@ struct ContentView: View {
.onReceive(handle_notify(.unmute_thread)) { notif in
home.filter_muted()
}
.onReceive(handle_notify(.local_notification)) { notif in
let local = notif.object as! LossyLocalNotification
guard let damus_state else {
return
}
guard let target = damus_state.events.lookup(local.event_id) else {
return
}
switch local.type {
case .dm:
selected_timeline = .dms
damus_state.dms.open_dm_by_pk(target.pubkey)
case .like: fallthrough
case .zap: fallthrough
case .mention: fallthrough
case .repost:
open_event(ev: target)
}
}
.alert(NSLocalizedString("Deleted Account", comment: "Alert message to indicate this is a deleted account"), isPresented: $is_deleted_account) {
Button(NSLocalizedString("Logout", comment: "Button to close the alert that informs that the current account has been deleted.")) {
is_deleted_account = false

View File

@@ -145,7 +145,7 @@ class HomeModel: ObservableObject {
}
if damus_state.settings.zap_notification {
// Create in-app local notification for zap received.
create_in_app_zap_notification(profiles: profiles, zap: zap)
create_in_app_zap_notification(profiles: profiles, zap: zap, evId: ev.referenced_ids.first?.id ?? "")
}
}
@@ -521,7 +521,8 @@ class HomeModel: ObservableObject {
self.new_events = notifs
if damus_state.settings.dm_notification {
let convo = ev.decrypted(privkey: self.damus_state.keypair.privkey) ?? NSLocalizedString("New encrypted direct message", comment: "Notification that the user has received a new direct message")
create_local_notification(profiles: damus_state.profiles, pubkey: ev.pubkey, conversation: convo, type: .dm)
let notify = LocalNotification(type: .dm, event: ev, target: ev, content: convo)
create_local_notification(profiles: damus_state.profiles, notify: notify)
}
}
@@ -530,6 +531,8 @@ class HomeModel: ObservableObject {
return
}
damus_state.events.insert(ev)
if !should_debounce_dms {
self.incoming_dms.append(ev)
if let notifs = handle_incoming_dms(prev_events: self.new_events, dms: self.dms, our_pubkey: self.damus_state.pubkey, evs: self.incoming_dms) {
@@ -1013,12 +1016,13 @@ func zap_notification_body(profiles: Profiles, zap: Zap, locale: Locale = Locale
}
}
func create_in_app_zap_notification(profiles: Profiles, zap: Zap, locale: Locale = Locale.current) {
func create_in_app_zap_notification(profiles: Profiles, zap: Zap, locale: Locale = Locale.current, evId: String) {
let content = UNMutableNotificationContent()
content.title = zap_notification_title(zap)
content.body = zap_notification_body(profiles: profiles, zap: zap, locale: locale)
content.sound = UNNotificationSound.default
content.userInfo = LossyLocalNotification(type: .zap, event_id: evId).to_user_info()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
@@ -1055,37 +1059,34 @@ func process_local_notification(damus_state: DamusState, event ev: NostrEvent) {
for case .mention(let mention) in blocks where mention.ref.ref_id == damus_state.keypair.pubkey {
let content = NSAttributedString(render_note_content(ev: ev, profiles: damus_state.profiles, privkey: damus_state.keypair.privkey).content.attributed).string
create_local_notification(profiles: damus_state.profiles,
pubkey: ev.pubkey,
conversation: content,
type: type)
let notify = LocalNotification(type: .mention, event: ev, target: ev, content: content)
create_local_notification(profiles: damus_state.profiles, notify: notify )
}
} else if type == .boost && damus_state.settings.repost_notification, let inner_ev = ev.inner_event {
create_local_notification(profiles: damus_state.profiles,
pubkey: inner_ev.pubkey,
conversation: inner_ev.content,
type: type)
let notify = LocalNotification(type: .repost, event: ev, target: inner_ev, content: inner_ev.content)
create_local_notification(profiles: damus_state.profiles, notify: notify)
} else if type == .like && damus_state.settings.like_notification,
let e_ref = ev.referenced_ids.first?.ref_id,
let content = damus_state.events.lookup(e_ref)?.content {
create_local_notification(profiles: damus_state.profiles, pubkey: ev.pubkey, conversation: content, type: type)
let evid = ev.referenced_ids.first?.ref_id,
let liked_event = damus_state.events.lookup(evid)
{
let notify = LocalNotification(type: .like, event: ev, target: liked_event, content: liked_event.content)
create_local_notification(profiles: damus_state.profiles, notify: notify)
}
}
func create_local_notification(profiles: Profiles, pubkey: String, conversation: String, type: NostrKind) {
func create_local_notification(profiles: Profiles, notify: LocalNotification) {
let content = UNMutableNotificationContent()
var title = ""
var identifier = ""
let profile = profiles.lookup(id: pubkey)
let displayName = Profile.displayName(profile: profile, pubkey: pubkey).display_name
let displayName = event_author_name(profiles: profiles, pubkey: notify.event.pubkey)
switch type {
case .text:
switch notify.type {
case .mention:
title = String(format: NSLocalizedString("Mentioned by %@", comment: "Mentioned by heading in local notification"), displayName)
identifier = "myMentionNotification"
case .boost:
case .repost:
title = String(format: NSLocalizedString("Reposted by %@", comment: "Reposted by heading in local notification"), displayName)
identifier = "myBoostNotification"
case .like:
@@ -1094,12 +1095,14 @@ func create_local_notification(profiles: Profiles, pubkey: String, conversation:
case .dm:
title = String(format: NSLocalizedString("%@", comment: "DM by heading in local notification"), displayName)
identifier = "myDMNotification"
default:
case .zap:
// not handled here
break
}
content.title = title
content.body = conversation
content.body = notify.content
content.sound = UNNotificationSound.default
content.userInfo = notify.to_lossy().to_user_info()
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)

View File

@@ -110,6 +110,9 @@ extension Notification.Name {
static var unmute_thread: Notification.Name {
return Notification.Name("unmute_thread")
}
static var local_notification: Notification.Name {
return Notification.Name("local_notification")
}
}
func handle_notify(_ name: Notification.Name) -> NotificationCenter.Publisher {

View File

@@ -55,6 +55,13 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
// Display the notification in the foreground
completionHandler([.banner, .list, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let notification = LossyLocalNotification.from_user_info(user_info: userInfo)
notify(.local_notification, notification)
completionHandler()
}
}
func needs_setup() -> Keypair? {