// // ChargeSessionCompletionSheetView.swift // USB Meter // import SwiftUI struct ChargeSessionCompletionSheetView: View { @EnvironmentObject private var appData: AppData @Environment(\.dismiss) private var dismiss let sessionID: UUID let title: String let confirmTitle: String let explanation: String @State private var batteryPercent = "" var body: some View { NavigationView { Form { Section( header: ContextInfoHeader( title: "Final Checkpoint", message: explanation ) ) { TextField("Battery %", text: $batteryPercent) .keyboardType(.decimalPad) } Section { if let sessionWarning { Text(sessionWarning) .font(.footnote) .foregroundColor(.orange) } else if (parsedBatteryPercent ?? 0) >= 99.5 { Text("A final checkpoint at 100% lets the app learn the stop current for this exact charging type when the session data is reliable.") .font(.footnote) .foregroundColor(.secondary) } } } .navigationTitle(title) .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .cancellationAction) { Button("Cancel") { dismiss() } } ToolbarItem(placement: .confirmationAction) { Button(confirmTitle) { guard let percent = parsedBatteryPercent else { return } if appData.stopChargeSession(sessionID: sessionID, finalBatteryPercent: percent) { dismiss() } } .disabled(parsedBatteryPercent == nil) } } } .navigationViewStyle(StackNavigationViewStyle()) } private var parsedBatteryPercent: Double? { let normalized = batteryPercent .trimmingCharacters(in: .whitespacesAndNewlines) .replacingOccurrences(of: ",", with: ".") guard let value = Double(normalized), value >= 0, value <= 100 else { return nil } return value } private var sessionWarning: String? { guard let session = appData.chargedDevices .flatMap(\.sessions) .first(where: { $0.id == sessionID }), session.chargingTransportMode == .wireless, let chargerID = session.chargerID, let charger = appData.chargedDeviceSummary(id: chargerID), charger.chargerIdleCurrentAmps == nil else { return nil } return "This charger has no idle-current measurement, so the final checkpoint will stop the session but will not learn a wireless stop threshold yet." } }