From d6ae19e11e6db3aff319d27da8a9d6fa900f539d Mon Sep 17 00:00:00 2001 From: jack Date: Thu, 3 Jul 2025 23:21:29 +0200 Subject: [PATCH] Enable notifications on macOS - Add macOS support to NotificationService - Use NSApplication.shared.isActive to check app state on macOS - Move notification logic outside of iOS-only block in ChatViewModel - Notifications now work for both mentions and private messages on macOS - Keep haptic feedback iOS-only as it's not available on macOS --- bitchat/Services/NotificationService.swift | 20 ++++++++++++-------- bitchat/ViewModels/ChatViewModel.swift | 11 +++++++---- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bitchat/Services/NotificationService.swift b/bitchat/Services/NotificationService.swift index cd2559da..70cf385b 100644 --- a/bitchat/Services/NotificationService.swift +++ b/bitchat/Services/NotificationService.swift @@ -1,9 +1,9 @@ import Foundation +import UserNotifications #if os(iOS) import UIKit -import UserNotifications -#else -import UserNotifications +#elseif os(macOS) +import AppKit #endif class NotificationService { @@ -12,7 +12,6 @@ class NotificationService { private init() {} func requestAuthorization() { - #if os(iOS) UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { print("[NOTIFICATIONS] Permission granted") @@ -20,18 +19,24 @@ class NotificationService { print("[NOTIFICATIONS] Permission error: \(error)") } } - #endif } func sendLocalNotification(title: String, body: String, identifier: String) { + // Check if app is in foreground #if os(iOS) - // Send notification if app is not active (background or inactive) guard UIApplication.shared.applicationState != .active else { print("[NOTIFICATIONS] App is active/foreground, skipping notification") return } - print("[NOTIFICATIONS] App state: \(UIApplication.shared.applicationState.rawValue), sending notification") + #elseif os(macOS) + // On macOS, check if app is active + guard !NSApplication.shared.isActive else { + print("[NOTIFICATIONS] App is active/foreground, skipping notification") + return + } + print("[NOTIFICATIONS] App is not active, sending notification") + #endif let content = UNMutableNotificationContent() content.title = title @@ -51,7 +56,6 @@ class NotificationService { print("[NOTIFICATIONS] Notification sent: \(title)") } } - #endif } func sendMentionNotification(from sender: String, message: String) { diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index eb378632..5b8c0416 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -430,14 +430,19 @@ extension ChatViewModel: BitchatDelegate { messages.append(message) } - #if os(iOS) // Check if we're mentioned let isMentioned = message.mentions?.contains(nickname) ?? false // Send notifications for mentions and private messages when app is in background 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) + } + + #if os(iOS) + // Haptic feedback for iOS only + if isMentioned && message.sender != nickname { // Very prominent haptic for @mentions - triple tap with heavy impact let impactFeedback = UIImpactFeedbackGenerator(style: .heavy) impactFeedback.prepare() @@ -450,8 +455,6 @@ extension ChatViewModel: BitchatDelegate { impactFeedback.impactOccurred() } } else if message.isPrivate && message.sender != nickname { - NotificationService.shared.sendPrivateMessageNotification(from: message.sender, message: message.content) - // Heavy haptic for private messages - more pronounced let impactFeedback = UIImpactFeedbackGenerator(style: .heavy) impactFeedback.prepare()