feat: add status notifications for server monitoring
- Add notification preferences (Status Notifications and Alert Notifications toggles) - Implement ping failure/recovery notifications when servers go offline/online - Track individual service status changes and notify when services fail - Request notification permissions on app launch - Services like DNS, FTP, SSH, etc. now trigger alerts when status changes - Notifications only sent when settings are enabled Changes: - PreferencesView: Add NotificationsPreferencesView with two toggles - PingService: Add notification support with state tracking for ping events - MainView: Add service status monitoring with change detection - Track previous service states to detect transitions
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import Foundation
|
||||
import UserNotifications
|
||||
|
||||
enum PingService {
|
||||
static func ping(hostname: String, apiKey: String) async -> Bool {
|
||||
private static var previousPingStates: [String: Bool] = [:]
|
||||
|
||||
static func ping(hostname: String, apiKey: String, notificationsEnabled: Bool = true) async -> Bool {
|
||||
guard let url = URL(string: "https://\(hostname)/api/v2/ping") else {
|
||||
print("❌ [PingService] Invalid URL for \(hostname)")
|
||||
return false
|
||||
@@ -18,17 +21,49 @@ enum PingService {
|
||||
if let responseString = String(data: data, encoding: .utf8) {
|
||||
print("❌ [PingService] HTTP \(httpResponse.statusCode): \(responseString)")
|
||||
}
|
||||
handlePingFailure(for: hostname, notificationsEnabled: notificationsEnabled)
|
||||
return false
|
||||
}
|
||||
|
||||
if let result = try? JSONDecoder().decode([String: String].self, from: data), result["response"] == "pong" {
|
||||
handlePingSuccess(for: hostname, notificationsEnabled: notificationsEnabled)
|
||||
return true
|
||||
} else {
|
||||
handlePingFailure(for: hostname, notificationsEnabled: notificationsEnabled)
|
||||
return false
|
||||
}
|
||||
} catch {
|
||||
print("❌ [PingService] Error pinging \(hostname): \(error)")
|
||||
handlePingFailure(for: hostname, notificationsEnabled: notificationsEnabled)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private static func handlePingSuccess(for hostname: String, notificationsEnabled: Bool) {
|
||||
let wasPreviouslyDown = previousPingStates[hostname] == false
|
||||
previousPingStates[hostname] = true
|
||||
|
||||
if wasPreviouslyDown && notificationsEnabled {
|
||||
sendNotification(title: "Server Online", body: "\(hostname) is now online")
|
||||
}
|
||||
}
|
||||
|
||||
private static func handlePingFailure(for hostname: String, notificationsEnabled: Bool) {
|
||||
let wasPreviouslyUp = previousPingStates[hostname] != false
|
||||
previousPingStates[hostname] = false
|
||||
|
||||
if wasPreviouslyUp && notificationsEnabled {
|
||||
sendNotification(title: "Server Offline", body: "\(hostname) is offline")
|
||||
}
|
||||
}
|
||||
|
||||
private static func sendNotification(title: String, body: String) {
|
||||
let content = UNMutableNotificationContent()
|
||||
content.title = title
|
||||
content.body = body
|
||||
content.sound = .default
|
||||
|
||||
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: nil)
|
||||
UNUserNotificationCenter.current().add(request)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user