Procházet zdrojové kódy

Cancel temp target

Jonas Björkert před 2 roky
rodič
revize
bca9da6e19

+ 38 - 9
LoopFollow/Remote/RemoteView.swift

@@ -19,11 +19,12 @@ struct RemoteView: View {
     @State private var newHKTarget = HKQuantity(unit: .milligramsPerDeciliter, doubleValue: 0.0)
     @State private var duration = HKQuantity(unit: .minute(), doubleValue: 0.0)
     @State private var showConfirmation: Bool = false
+    @State private var showCancelConfirmation: Bool = false
     @State private var showCheckmark: Bool = false
     @State private var isLoading: Bool = false
 
     var onRefreshStatus: () -> Void
-    var onCancelExistingTarget: () -> Void
+    var onCancelExistingTarget: (@escaping (Bool) -> Void) -> Void
     var sendTempTarget: (HKQuantity, HKQuantity, @escaping (Bool) -> Void) -> Void
 
     var body: some View {
@@ -46,16 +47,23 @@ struct RemoteView: View {
                         if let tempTargetValue = tempTarget.value {
                             Section(header: Text("Existing Temp Target")) {
                                 HStack {
-                                    Text("Current Target: \(Localizer.formatQuantity(tempTargetValue)) mg/dL")
+                                    Text("Current Target")
                                     Spacer()
-                                    Button(action: onCancelExistingTarget) {
-                                        Text("Cancel")
-                                            .foregroundColor(.red)
-                                    }
+                                    Text(Localizer.formatQuantity(tempTargetValue))
+                                    Text(UserDefaultsRepository.getPreferredUnit().localizedShortUnitString).foregroundColor(.secondary)
                                 }
+                                Button { showCancelConfirmation = true }
+                            label: {
+                                HStack {
+                                    Text("Cancel Temp Target")
+                                    Spacer()
+                                    Image(systemName: "xmark.app")
+                                        .font(.title)
+                                }
+                            }
+                            .tint(.red)
                             }
                         }
-
                         Section(header: Text("Temporary Target")) {
                             HStack {
                                 Text("Target")
@@ -95,7 +103,6 @@ struct RemoteView: View {
                     .navigationBarItems(trailing: Button(action: onRefreshStatus) {
                         Image(systemName: "arrow.clockwise")
                     })
-                    .padding()
                     .disabled(isLoading) // Disable the form when loading
 
                     if isLoading {
@@ -104,7 +111,6 @@ struct RemoteView: View {
                     }
                 }
             }
-            .padding()
             .navigationTitle("Remote")
             .navigationBarTitleDisplayMode(.inline)
             .alert(isPresented: .constant(!statusMessage.value.isEmpty)) {
@@ -116,6 +122,16 @@ struct RemoteView: View {
                     })
                 )
             }
+            .alert(isPresented: $showCancelConfirmation) {
+                Alert(
+                    title: Text("Confirm Cancellation"),
+                    message: Text("Are you sure you want to cancel the existing temp target?"),
+                    primaryButton: .default(Text("Confirm"), action: {
+                        cancelTempTarget()
+                    }),
+                    secondaryButton: .cancel()
+                )
+            }
         }
     }
 
@@ -135,6 +151,19 @@ struct RemoteView: View {
             }
         }
     }
+
+    private func cancelTempTarget() {
+        isLoading = true
+        let zeroDuration = HKQuantity(unit: .minute(), doubleValue: 0.0)
+        onCancelExistingTarget() { success in
+            isLoading = false
+            if success {
+                statusMessage.value = "Temp target successfully cancelled."
+            } else {
+                statusMessage.value = "Failed to cancel temp target."
+            }
+        }
+    }
 }
 
 struct ErrorMessageView: View {

+ 25 - 2
LoopFollow/Remote/RemoteViewController.swift

@@ -51,8 +51,31 @@ class RemoteViewController: UIViewController {
         // Refresh the status to check current temp targets and other relevant info
     }
 
-    private func cancelExistingTarget() {
-        // Cancel the existing temp target
+    private func cancelExistingTarget(completion: @escaping (Bool) -> Void) {
+        let tempTargetBody: [String: Any] = [
+            "enteredBy": "LoopFollow",
+            "eventType": "Temporary Target",
+            "reason": "Manual",
+            "duration": 0,
+            "created_at": ISO8601DateFormatter().string(from: Date())
+        ]
+
+        NightscoutUtils.executePostRequest(eventType: .treatments, body: tempTargetBody) { (result: Result<[TreatmentCancelResponse], Error>) in
+            switch result {
+            case .success(let response):
+                print("Success: \(response)")
+                DispatchQueue.main.async {
+                    self.statusMessage.set("Temp target successfully cancelled.")
+                    completion(true)
+                }
+            case .failure(let error):
+                print("Error: \(error)")
+                DispatchQueue.main.async {
+                    self.statusMessage.set("Failed to cancel temp target: \(error.localizedDescription)")
+                    completion(false)
+                }
+            }
+        }
     }
 
     private func sendTempTarget(newTarget: HKQuantity, duration: HKQuantity, completion: @escaping (Bool) -> Void) {

+ 20 - 0
LoopFollow/Remote/TreatmentResponse.swift

@@ -31,3 +31,23 @@ struct TreatmentResponse: Decodable {
         case id = "_id"
     }
 }
+
+struct TreatmentCancelResponse: Decodable {
+    let enteredBy: String
+    let eventType: String
+    let reason: String
+    let duration: Int
+    let createdAt: String
+    let utcOffset: Int
+    let id: String
+
+    enum CodingKeys: String, CodingKey {
+        case enteredBy = "enteredBy"
+        case eventType = "eventType"
+        case reason = "reason"
+        case duration = "duration"
+        case createdAt = "created_at"
+        case utcOffset = "utcOffset"
+        case id = "_id"
+    }
+}

+ 8 - 1
LoopFollow/helpers/NightscoutUtils.swift

@@ -280,7 +280,14 @@ class NightscoutUtils {
                     }
                     return
                 }
-
+                // Print the JSON string for debugging
+                /*
+                if let jsonString = String(data: data, encoding: .utf8) {
+                    print("JSON Response: \(jsonString)")
+                } else {
+                    print("Failed to convert data to JSON string")
+                }
+                */
                 let decoder = JSONDecoder()
                 do {
                     let decodedObject = try decoder.decode(T.self, from: data)