Settings: test alert notification button
Fires a local notification shaped exactly like a real price alert (uses the currently configured alerts fuel + radius), with permission-gated handling: prompts on first use, guides to Settings when denied. Tapping it opens FuelBoard, same as a real alert.
This commit is contained in:
@@ -1,15 +1,22 @@
|
||||
import SwiftUI
|
||||
import StoreKit
|
||||
import UserNotifications
|
||||
import WidgetKit
|
||||
|
||||
/// Settings tab — distance units, onboarding replay, and a tip jar.
|
||||
/// Settings tab — distance units, onboarding replay, a tip jar, and a
|
||||
/// test-alert button that previews what a real price notification looks like.
|
||||
struct SettingsView: View {
|
||||
@Binding var distanceUnit: DistanceUnit
|
||||
/// The fuel + radius currently configured for alerts (mirrors the Alerts
|
||||
/// tab) so the test notification matches what real alerts will say.
|
||||
var alertsFuel: FuelType = .e10
|
||||
var alertsRadiusKM: Double = 3.0
|
||||
var onShowOnboarding: () -> Void = {}
|
||||
|
||||
@StateObject private var tipStore = TipStore()
|
||||
@State private var showTipAlert = false
|
||||
@State private var tipAlertMessage = ""
|
||||
@State private var testAlertMessage: String?
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
@@ -41,6 +48,23 @@ struct SettingsView: View {
|
||||
Text("Replay the welcome screen, including the location and notification permission prompts.")
|
||||
}
|
||||
|
||||
Section {
|
||||
Button {
|
||||
sendTestAlert()
|
||||
} label: {
|
||||
Label("Test alert notification", systemImage: "bell.badge.fill")
|
||||
}
|
||||
if let testAlertMessage {
|
||||
Text(testAlertMessage)
|
||||
.font(.footnote)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
} header: {
|
||||
Text("Alerts")
|
||||
} footer: {
|
||||
Text("Sends a notification exactly like a real price alert for \(alertsFuel.displayName.lowercased()) within \(distanceUnit.format(alertsRadiusKM)). Tapping it opens FuelBoard — just like a real alert.")
|
||||
}
|
||||
|
||||
Section {
|
||||
Button {
|
||||
Task { await tipStore.purchase() }
|
||||
@@ -75,6 +99,32 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func sendTestAlert() {
|
||||
UNUserNotificationCenter.current().getNotificationSettings { settings in
|
||||
Task { @MainActor in
|
||||
switch settings.authorizationStatus {
|
||||
case .authorized, .provisional, .ephemeral:
|
||||
ProximityMonitor.sendTestNotification(fuel: alertsFuel, radiusKM: alertsRadiusKM)
|
||||
testAlertMessage = "Test alert sent — check your notification centre."
|
||||
case .denied:
|
||||
testAlertMessage = "Notifications are turned off for FuelBoard. Enable them in Settings → Notifications → FuelBoard, then try again."
|
||||
default:
|
||||
// First time — ask, then fire if granted.
|
||||
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
|
||||
Task { @MainActor in
|
||||
if granted {
|
||||
ProximityMonitor.sendTestNotification(fuel: alertsFuel, radiusKM: alertsRadiusKM)
|
||||
testAlertMessage = "Test alert sent — check your notification centre."
|
||||
} else {
|
||||
testAlertMessage = "Notifications weren't allowed, so no test alert was sent."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads the £4.99 tip product and drives its purchase.
|
||||
|
||||
Reference in New Issue
Block a user