1 contributor
148 lines | 7.292kb
//
//  ChargeRecordSheetView.swift
//  USB Meter
//
//  Created by Bogdan Timofte on 09/03/2020.
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
//

import SwiftUI

struct ChargeRecordSheetView: View {
    
    @Binding var visibility: Bool
    @EnvironmentObject private var usbMeter: Meter
    
    var body: some View {
        NavigationView {
            ScrollView {
                VStack(spacing: 16) {
                    VStack(alignment: .leading, spacing: 8) {
                        HStack {
                            Text("Charge Record")
                                .font(.system(.title3, design: .rounded).weight(.bold))
                            Spacer()
                            Text(usbMeter.chargeRecordStatusText)
                                .font(.caption.weight(.bold))
                                .foregroundColor(usbMeter.chargeRecordStatusColor)
                                .padding(.horizontal, 10)
                                .padding(.vertical, 6)
                                .meterCard(
                                    tint: usbMeter.chargeRecordStatusColor,
                                    fillOpacity: 0.18,
                                    strokeOpacity: 0.24,
                                    cornerRadius: 999
                                )
                        }
                        Text("App-side charge accumulation based on the stop-threshold workflow.")
                            .font(.footnote)
                            .foregroundColor(.secondary)
                    }
                    .frame(maxWidth: .infinity)
                    .padding(18)
                    .meterCard(tint: .pink, fillOpacity: 0.18, strokeOpacity: 0.24)

                    ChargeRecordMetricsTableView(
                        labels: ["Capacity", "Energy", "Duration", "Stop Threshold"],
                        values: [
                            "\(usbMeter.chargeRecordAH.format(decimalDigits: 3)) Ah",
                            "\(usbMeter.chargeRecordWH.format(decimalDigits: 3)) Wh",
                            usbMeter.chargeRecordDurationDescription,
                            "\(usbMeter.chargeRecordStopThreshold.format(decimalDigits: 2)) A"
                        ]
                    )
                    .padding(18)
                    .meterCard(tint: .pink, fillOpacity: 0.14, strokeOpacity: 0.20)

                    if usbMeter.chargeRecordTimeRange != nil {
                        VStack(alignment: .leading, spacing: 12) {
                            HStack {
                                Text("Charge Curve")
                                    .font(.headline)
                                Spacer()
                                Button("Reset Graph") {
                                    usbMeter.resetChargeRecordGraph()
                                }
                                .foregroundColor(.red)
                            }
                            MeasurementChartView(timeRange: usbMeter.chargeRecordTimeRange)
                                .environmentObject(usbMeter.measurements)
                                .frame(minHeight: 220)
                            Text("Reset Graph clears the current charge-record session and removes older shared samples that are no longer needed for this curve.")
                                .font(.footnote)
                                .foregroundColor(.secondary)
                        }
                        .padding(18)
                        .meterCard(tint: .blue, fillOpacity: 0.14, strokeOpacity: 0.20)
                    }

                    VStack(alignment: .leading, spacing: 12) {
                        Text("Stop Threshold")
                            .font(.headline)
                        Slider(value: $usbMeter.chargeRecordStopThreshold, in: 0...0.30, step: 0.01)
                        Text("The app starts accumulating when current rises above this threshold and stops when it falls back to or below it.")
                            .font(.footnote)
                            .foregroundColor(.secondary)
                        Button("Reset") {
                            usbMeter.resetChargeRecord()
                        }
                        .frame(maxWidth: .infinity)
                        .padding(.vertical, 10)
                        .meterCard(tint: .orange, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
                        .buttonStyle(.plain)
                    }
                    .padding(18)
                    .meterCard(tint: .orange, fillOpacity: 0.14, strokeOpacity: 0.20)

                    if usbMeter.supportsDataGroupCommands || usbMeter.recordedAH > 0 || usbMeter.recordedWH > 0 || usbMeter.recordingDuration > 0 {
                        VStack(alignment: .leading, spacing: 12) {
                            Text("Meter Totals")
                                .font(.headline)
                            ChargeRecordMetricsTableView(
                                labels: ["Capacity", "Energy", "Duration", "Meter Threshold"],
                                values: [
                                    "\(usbMeter.recordedAH.format(decimalDigits: 3)) Ah",
                                    "\(usbMeter.recordedWH.format(decimalDigits: 3)) Wh",
                                    usbMeter.recordingDurationDescription,
                                    usbMeter.supportsRecordingThreshold ? "\(usbMeter.recordingTreshold.format(decimalDigits: 2)) A" : "Read-only"
                                ]
                            )
                            Text("These values are reported by the meter for the active data group.")
                                .font(.footnote)
                                .foregroundColor(.secondary)
                            if usbMeter.supportsDataGroupCommands {
                                Button("Reset Active Group") {
                                    usbMeter.clear()
                                }
                                .frame(maxWidth: .infinity)
                                .padding(.vertical, 10)
                                .meterCard(tint: .red, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
                                .buttonStyle(.plain)
                            }
                        }
                        .padding(18)
                        .meterCard(tint: .teal, fillOpacity: 0.14, strokeOpacity: 0.20)
                    }
                }
                .padding()
            }
            .background(
                LinearGradient(
                    colors: [.pink.opacity(0.14), Color.clear],
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
                .ignoresSafeArea()
            )
            .navigationBarTitle("Charge Record", displayMode: .inline)
            .navigationBarItems(trailing: Button("Done") { visibility.toggle() })
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct ChargeRecordSheetView_Previews: PreviewProvider {
    static var previews: some View {
        ChargeRecordSheetView(visibility: .constant(true))
    }
}