Просмотр исходного кода

Fix swipe away behavior not dismissing in-app banner

dnzxy 1 неделя назад
Родитель
Сommit
d1dccb3ed5

+ 15 - 6
Trio/Sources/Localizations/Main/Localizable.xcstrings

@@ -8903,6 +8903,9 @@
         }
       }
     },
+    "%@ Device Alerts" : {
+      "comment" : "Device Alerts help sheet label; text reads: '<severity level> Device Alerts'."
+    },
     "%@ g" : {
       "localizations" : {
         "bg" : {
@@ -47216,7 +47219,7 @@
         }
       }
     },
-    "Applies To" : {
+    "Applies To (Cannot be changed)" : {
 
     },
     "Apply a Temporary Target" : {
@@ -85023,7 +85026,7 @@
         }
       }
     },
-    "Default notification banner. Suppressed by Silence & Focus Mode." : {
+    "Default notification banner. Suppressed by Silence & Focus Mode by default." : {
 
     },
     "Default Percent: 70%" : {
@@ -123546,6 +123549,9 @@
         }
       }
     },
+    "For everyday heads-up notifications. These behave like a standard banner — they stay quiet when your phone is silenced or a Focus is on. Examples: an algorithm error, a sensor expiration reminder, or a time-zone change being detected." : {
+
+    },
     "For example, at a temp target of %@ %@, your basal is reduced to 50%%, but this scales depending on the target (e.g., 75%% at %@ %@, 60%% at %@ %@)." : {
       "localizations" : {
         "bg" : {
@@ -124048,6 +124054,12 @@
         }
       }
     },
+    "For situations that require prompt attention. These break through Silent Mode, Do Not Disturb, and any Focus you have enabled. Examples: a pump fault, an occlusion, or Trio not looping for too long. Heads up: if your build of Trio has Apple's Critical Alerts entitlement, iOS plays its own critical alert sound and the sound you picked for this alert category is ignored." : {
+
+    },
+    "For things you should know about soon, but not 'act right now'. These can break through banner suppression on the lock screen, but they still obey Silent Mode and Focus by default. Examples: reservoir running low, pod or patch expiring soon, or glucose data going stale." : {
+
+    },
     "For write data to Apple Health you must give permissions in Settings > Health > Data Access" : {
       "comment" : "Show when have not permissions for writing to Health",
       "extractionState" : "manual",
@@ -193861,9 +193873,6 @@
     "Overrides Focus" : {
 
     },
-    "Overrides Silence & Focus Mode" : {
-
-    },
     "Overrides Silence & Focus Mode. For situations requiring immediate attention." : {
 
     },
@@ -197428,7 +197437,7 @@
         }
       }
     },
-    "Pierces banner suppression but obeys Silence & Focus Mode." : {
+    "Pierces banner suppression but obeys Silence & Focus Mode by default." : {
 
     },
     "Play Sound" : {

+ 3 - 1
Trio/Sources/Models/NotificationIdentifiers.swift

@@ -54,11 +54,13 @@ enum NotificationCategoryFactory {
             )
         }
 
+        // `.customDismissAction` — otherwise iOS swallows swipes silently and
+        // the in-app banner outlives the notification.
         return UNNotificationCategory(
             identifier: NotificationCategoryIdentifier.trioAlert.rawValue,
             actions: snoozeActions,
             intentIdentifiers: [],
-            options: []
+            options: [.customDismissAction]
         )
     }
 }

+ 9 - 0
Trio/Sources/Services/Alerts/TrioAlertManager.swift

@@ -207,6 +207,15 @@ final class BaseTrioAlertManager: TrioAlertManager, Injectable {
             let alertId = userInfo[AlertUserInfoKey.alertIdentifier.rawValue] as? String
         else { return }
         let identifier = Alert.Identifier(managerIdentifier: managerId, alertIdentifier: alertId)
+
+        // Swipe = 15-min snooze (mirrors the in-app banner's swipe-up).
+        // Tap and action buttons keep the full-ack path.
+        if response.actionIdentifier == UNNotificationDismissActionIdentifier {
+            modalScheduler.snooze(identifier: identifier, duration: 15 * 60)
+            userNotificationScheduler.unschedule(identifier: identifier)
+            return
+        }
+
         handleAcknowledgement(identifier: identifier)
     }