USB-Meter / USB Meter / Views / ChargedDevices / ChargeSessionCompletionSheetView.swift
1 contributor
86 lines | 3.158kb
//
//  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."
    }
}