Improve private message notification behavior

- Don't show PM notifications when the private chat is already open
- Store peer ID in notification userInfo for reliable chat opening
- Tap notification to open the correct private chat using peer ID
- Check both in ChatViewModel (when receiving) and NotificationDelegate (when presenting)
This commit is contained in:
jack
2025-07-24 12:00:01 +02:00
parent b0204afa75
commit c4ca38654d
3 changed files with 32 additions and 13 deletions
+21 -9
View File
@@ -147,17 +147,14 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let identifier = response.notification.request.identifier
let userInfo = response.notification.request.content.userInfo
// Check if this is a private message notification
if identifier.hasPrefix("private-") {
// Extract sender from notification title
let title = response.notification.request.content.title
if let senderName = title.replacingOccurrences(of: "Private message from ", with: "").nilIfEmpty {
// Find peer ID and open chat
if let peerID = chatViewModel?.getPeerIDForNickname(senderName) {
DispatchQueue.main.async {
self.chatViewModel?.startPrivateChat(with: peerID)
}
// Get peer ID from userInfo
if let peerID = userInfo["peerID"] as? String {
DispatchQueue.main.async {
self.chatViewModel?.startPrivateChat(with: peerID)
}
}
}
@@ -166,7 +163,22 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// Show notification even when app is in foreground (for testing)
let identifier = notification.request.identifier
let userInfo = notification.request.content.userInfo
// Check if this is a private message notification
if identifier.hasPrefix("private-") {
// Get peer ID from userInfo
if let peerID = userInfo["peerID"] as? String {
// Don't show notification if the private chat is already open
if chatViewModel?.selectedPrivateChatPeer == peerID {
completionHandler([])
return
}
}
}
// Show notification in all other cases
completionHandler([.banner, .sound])
}
}
+7 -3
View File
@@ -29,7 +29,7 @@ class NotificationService {
}
}
func sendLocalNotification(title: String, body: String, identifier: String) {
func sendLocalNotification(title: String, body: String, identifier: String, userInfo: [String: Any]? = nil) {
// For now, skip app state check entirely to avoid thread issues
// The NotificationDelegate will handle foreground presentation
DispatchQueue.main.async {
@@ -37,6 +37,9 @@ class NotificationService {
content.title = title
content.body = body
content.sound = .default
if let userInfo = userInfo {
content.userInfo = userInfo
}
let request = UNNotificationRequest(
identifier: identifier,
@@ -58,12 +61,13 @@ class NotificationService {
sendLocalNotification(title: title, body: body, identifier: identifier)
}
func sendPrivateMessageNotification(from sender: String, message: String) {
func sendPrivateMessageNotification(from sender: String, message: String, peerID: String) {
let title = "🔒 private message from \(sender)"
let body = message
let identifier = "private-\(UUID().uuidString)"
let userInfo = ["peerID": peerID, "senderName": sender]
sendLocalNotification(title: title, body: body, identifier: identifier)
sendLocalNotification(title: title, body: body, identifier: identifier, userInfo: userInfo)
}
func sendFavoriteOnlineNotification(nickname: String) {
+4 -1
View File
@@ -1968,7 +1968,10 @@ extension ChatViewModel: BitchatDelegate {
if isMentioned && message.sender != nickname {
NotificationService.shared.sendMentionNotification(from: message.sender, message: message.content)
} else if message.isPrivate && message.sender != nickname {
NotificationService.shared.sendPrivateMessageNotification(from: message.sender, message: message.content)
// Only send notification if the private chat is not currently open
if selectedPrivateChatPeer != message.senderPeerID {
NotificationService.shared.sendPrivateMessageNotification(from: message.sender, message: message.content, peerID: message.senderPeerID ?? "")
}
}
#if os(iOS)