Jonas Björkert 1 год назад
Родитель
Сommit
1f67ea25b7
2 измененных файлов с 92 добавлено и 21 удалено
  1. 92 0
      LoopFollow/Storage/Storage+Migrate.swift
  2. 0 21
      LoopFollow/Storage/UserDefaults.swift

+ 92 - 0
LoopFollow/Storage/Storage+Migrate.swift

@@ -291,6 +291,7 @@ extension Storage {
         migrateFastRiseAlarm()
         migrateFastRiseAlarm()
         migrateMissedReadingAlarm()
         migrateMissedReadingAlarm()
         migrateNotLoopingAlarm()
         migrateNotLoopingAlarm()
+        migrateMissedBolusAlarm()
     }
     }
 
 
     // MARK: - One-off alarm migrations
     // MARK: - One-off alarm migrations
@@ -766,4 +767,95 @@ extension Storage {
         list.append(alarm)
         list.append(alarm)
         Storage.shared.alarms.value = list
         Storage.shared.alarms.value = list
     }
     }
+
+    // MARK: – Missed-Bolus alarm -------------------------------------------------
+
+    private func migrateMissedBolusAlarm() {
+        // Was the old alarm ever configured?
+        let legacyActive = UserDefaultsValue<Bool>(key: "alertMissedBolusActive",
+                                                   default: false)
+        guard legacyActive.exists else { return } // nothing to do
+
+        // helper: read-then-delete ------------------------------------------------
+        func take<V: AnyConvertible & Equatable>(_ k: String,
+                                                 _ def: V) -> V
+        {
+            let box = UserDefaultsValue<V>(key: k, default: def)
+            defer { box.setNil(key: k) } // wipe after reading
+            return box.value
+        }
+
+        // ────────────────────────────────────────────────────────────────────────
+        // Build the new Alarm
+        // ────────────────────────────────────────────────────────────────────────
+        var alarm = Alarm(type: .missedBolus)
+        alarm.name = "Missed Bolus Alert"
+        alarm.isEnabled = take("alertMissedBolusActive", false)
+
+        // core timings
+        alarm.monitoringWindow = take("alertMissedBolus", 10) // delay
+        alarm.predictiveMinutes = take("alertMissedBolusPrebolus", 20) // pre-bolus window
+        alarm.snoozeDuration = take("alertMissedBolusSnooze", 10)
+
+        // snooze-state
+        if take("alertMissedBolusIsSnoozed", false) {
+            alarm.snoozedUntil = take("alertMissedBolusSnoozedTime",
+                                      nil as Date?)
+        }
+
+        // carb / bolus filters
+        alarm.delta = take("alertMissedBolusIgnoreBolus", 0.5)
+        alarm.threshold = Double(
+            take("alertMissedBolusLowGrams", 10))
+        alarm.aboveBG = Double(
+            take("alertMissedBolusLowGramsBG", 70.0))
+
+        // sound & tone
+        alarm.soundFile = SoundFile(rawValue:
+            take("alertMissedBolusSound",
+                 "Dhol_Shuffleloop")) ?? .dholShuffleloop
+
+        // ── ACTIVE-DURING  ← old “Pre-Snooze” flags
+        let actDay = take("alertMissedBolusAutosnoozeDay", false)
+        let actNight = take("alertMissedBolusAutosnoozeNight", false)
+        alarm.activeOption = {
+            switch (actDay, actNight) {
+            case (true, true): return .always
+            case (true, false): return .day
+            case (false, true): return .night
+            default: return .always // “Never” → always
+            }
+        }()
+
+        // ── PLAY-SOUND  ← old “PlaySound” picker
+        let playDay = take("alertMissedBolusDayTimeAudible", true)
+        let playNight = take("alertMissedBolusNightTimeAudible", true)
+        alarm.playSoundOption = {
+            switch (playDay, playNight) {
+            case (true, true): return .always
+            case (true, false): return .day
+            case (false, true): return .night
+            default: return .never
+            }
+        }()
+
+        // ── REPEAT-SOUND  ← old “Repeat Sound” picker
+        let repDay = take("alertMissedBolusDayTime", false)
+        let repNight = take("alertMissedBolusNightTime", false)
+        alarm.repeatSoundOption = {
+            switch (repDay, repNight) {
+            case (true, true): return .always
+            case (true, false): return .day
+            case (false, true): return .night
+            default: return .never
+            }
+        }()
+
+        // (The deprecated “alertMissedBolusQuiet” key is ignored.)
+
+        // ── Store & finish ------------------------------------------------------
+        var list = Storage.shared.alarms.value
+        list.append(alarm)
+        Storage.shared.alarms.value = list
+    }
 }
 }

+ 0 - 21
LoopFollow/Storage/UserDefaults.swift

@@ -97,27 +97,6 @@ class UserDefaultsRepository {
     static let alertCageInsertTime = UserDefaultsValue<TimeInterval>(key: "alertCageInsertTime", default: 0)
     static let alertCageInsertTime = UserDefaultsValue<TimeInterval>(key: "alertCageInsertTime", default: 0)
     static let alertSageInsertTime = UserDefaultsValue<TimeInterval>(key: "alertSageInsertTime", default: 0)
     static let alertSageInsertTime = UserDefaultsValue<TimeInterval>(key: "alertSageInsertTime", default: 0)
 
 
-    static let alertMissedBolusActive = UserDefaultsValue<Bool>(key: "alertMissedBolusActive", default: false)
-    static let alertMissedBolus = UserDefaultsValue<Int>(key: "alertMissedBolus", default: 10)
-    static let alertMissedBolusSnooze = UserDefaultsValue<Int>(key: "alertMissedBolusSnooze", default: 10)
-    static let alertMissedBolusPrebolus = UserDefaultsValue<Int>(key: "alertMissedBolusPrebolus", default: 20)
-    static let alertMissedBolusIgnoreBolus = UserDefaultsValue<Double>(key: "alertMissedBolusIgnoreBolus", default: 0.5)
-    static let alertMissedBolusLowGrams = UserDefaultsValue<Int>(key: "alertMissedBolusLowGrams", default: 10)
-    static let alertMissedBolusLowGramsBG = UserDefaultsValue<Float>(key: "alertMissedBolusLowGramsBG", default: 70.0)
-    static let alertMissedBolusSnoozedTime = UserDefaultsValue<Date?>(key: "alertMissedBolusSnoozedTime", default: nil)
-    static let alertMissedBolusIsSnoozed = UserDefaultsValue<Bool>(key: "alertMissedBolusIsSnoozed", default: false)
-    static let alertMissedBolusQuiet = UserDefaultsValue<Bool>(key: "alertMissedBolusQuiet", default: false)
-    static let alertMissedBolusRepeat = UserDefaultsValue<String>(key: "alertMissedBolusRepeat", default: "Never")
-    static let alertMissedBolusDayTime = UserDefaultsValue<Bool>(key: "alertMissedBolusDayTime", default: false)
-    static let alertMissedBolusNightTime = UserDefaultsValue<Bool>(key: "alertMissedBolusNightTime", default: false)
-    static let alertMissedBolusSound = UserDefaultsValue<String>(key: "alertMissedBolusSound", default: "Dhol_Shuffleloop")
-    static let alertMissedBolusAudible = UserDefaultsValue<String>(key: "alertMissedBolusAudible", default: "Always")
-    static let alertMissedBolusDayTimeAudible = UserDefaultsValue<Bool>(key: "alertMissedBolusDayTimeAudible", default: true)
-    static let alertMissedBolusNightTimeAudible = UserDefaultsValue<Bool>(key: "alertMissedBolusNightTimeAudible", default: true)
-    static let alertMissedBolusAutosnooze = UserDefaultsValue<String>(key: "alertMissedBolusAutosnooze", default: "Never")
-    static let alertMissedBolusAutosnoozeDay = UserDefaultsValue<Bool>(key: "alertMissedBolusAutosnoozeDay", default: false)
-    static let alertMissedBolusAutosnoozeNight = UserDefaultsValue<Bool>(key: "alertMissedBolusAutosnoozeNight", default: false)
-
     static let alertSAGEActive = UserDefaultsValue<Bool>(key: "alertSAGEActive", default: false)
     static let alertSAGEActive = UserDefaultsValue<Bool>(key: "alertSAGEActive", default: false)
     static let alertSAGE = UserDefaultsValue<Int>(key: "alertSAGE", default: 8) // Hours
     static let alertSAGE = UserDefaultsValue<Int>(key: "alertSAGE", default: 8) // Hours
     static let alertSAGEQuiet = UserDefaultsValue<Bool>(key: "alertSAGEQuiet", default: false)
     static let alertSAGEQuiet = UserDefaultsValue<Bool>(key: "alertSAGEQuiet", default: false)