Newer Older
200 lines | 8.447kb
Bogdan Timofte authored 2 months ago
1
//
2
//  MeterSettingsTabView.swift
3
//  USB Meter
4
//
5

            
6
import SwiftUI
7

            
8
struct MeterSettingsTabView: View {
Bogdan Timofte authored a month ago
9
    @EnvironmentObject private var appData: AppData
Bogdan Timofte authored 2 months ago
10
    @EnvironmentObject private var meter: Meter
11

            
12
    let isMacIPadApp: Bool
13
    let onBackToHome: () -> Void
14

            
15
    @State private var editingName = false
16
    @State private var editingScreenTimeout = false
17
    @State private var editingScreenBrightness = false
Bogdan Timofte authored a month ago
18
    @State private var deleteConfirmationVisibility = false
Bogdan Timofte authored 2 months ago
19

            
20
    var body: some View {
21
        VStack(spacing: 0) {
22
            if isMacIPadApp {
23
                settingsMacHeader
24
            }
25
            ScrollView {
26
                VStack(spacing: 14) {
27
                    settingsCard(title: "Name", tint: meter.color) {
28
                        HStack {
29
                            Spacer()
30
                            if !editingName {
31
                                Text(meter.name)
32
                                    .foregroundColor(.secondary)
33
                            }
34
                            ChevronView(rotate: $editingName)
35
                        }
36
                        if editingName {
Bogdan Timofte authored 2 months ago
37
                            MeterNameEditorView(editingName: $editingName, newName: meter.name)
Bogdan Timofte authored 2 months ago
38
                        }
39
                    }
40

            
41
                    if meter.operationalState == .dataIsAvailable && meter.supportsManualTemperatureUnitSelection {
42
                        settingsCard(title: "Meter Temperature Unit", tint: .orange) {
43
                            Text("TC66 temperature is shown as degrees without assuming Celsius or Fahrenheit. Keep this matched to the unit configured on the device so you can interpret the reading correctly.")
44
                                .font(.footnote)
45
                                .foregroundColor(.secondary)
46
                            Picker("", selection: $meter.tc66TemperatureUnitPreference) {
47
                                ForEach(TemperatureUnitPreference.allCases) { unit in
48
                                    Text(unit.title).tag(unit)
49
                                }
50
                            }
51
                            .pickerStyle(SegmentedPickerStyle())
52
                        }
53
                    }
54

            
Bogdan Timofte authored 2 months ago
55
                    if meter.operationalState == .dataIsAvailable && meter.model == .TC66C {
56
                        settingsCard(title: "Screen Reporting", tint: .orange) {
Bogdan Timofte authored 2 months ago
57
                            MeterInfoRowView(label: "Current Screen", value: "Not Reported")
Bogdan Timofte authored 2 months ago
58
                            Text("TC66 is the exception: it does not report the current screen in the payload, so the app keeps this note here instead of showing it on the home screen.")
59
                                .font(.footnote)
60
                                .foregroundColor(.secondary)
61
                        }
62
                    }
63

            
Bogdan Timofte authored 2 months ago
64
                    if meter.operationalState == .dataIsAvailable {
65
                        settingsCard(
66
                            title: meter.reportsCurrentScreenIndex ? "Screen Controls" : "Page Controls",
67
                            tint: .indigo
68
                        ) {
69
                            if meter.reportsCurrentScreenIndex {
70
                                Text("Use these controls when you want to change the screen shown on the device without crowding the main meter view.")
71
                                    .font(.footnote)
72
                                    .foregroundColor(.secondary)
73
                            } else {
74
                                Text("Use these controls when you want to switch device pages without crowding the main meter view.")
75
                                    .font(.footnote)
76
                                    .foregroundColor(.secondary)
77
                            }
78

            
Bogdan Timofte authored 2 months ago
79
                            MeterScreenControlsView(showsHeader: false)
Bogdan Timofte authored 2 months ago
80
                        }
81
                    }
82

            
83
                    if meter.operationalState == .dataIsAvailable && meter.supportsUMSettings {
84
                        settingsCard(title: "Screen Timeout", tint: .purple) {
85
                            HStack {
86
                                Spacer()
87
                                if !editingScreenTimeout {
88
                                    Text(meter.screenTimeout > 0 ? "\(meter.screenTimeout) Minutes" : "Off")
89
                                        .foregroundColor(.secondary)
90
                                }
91
                                ChevronView(rotate: $editingScreenTimeout)
92
                            }
93
                            if editingScreenTimeout {
Bogdan Timofte authored 2 months ago
94
                                ScreenTimeoutEditorView()
Bogdan Timofte authored 2 months ago
95
                            }
96
                        }
97

            
98
                        settingsCard(title: "Screen Brightness", tint: .yellow) {
99
                            HStack {
100
                                Spacer()
101
                                if !editingScreenBrightness {
102
                                    Text("\(meter.screenBrightness)")
103
                                        .foregroundColor(.secondary)
104
                                }
105
                                ChevronView(rotate: $editingScreenBrightness)
106
                            }
107
                            if editingScreenBrightness {
Bogdan Timofte authored 2 months ago
108
                                ScreenBrightnessEditorView()
Bogdan Timofte authored 2 months ago
109
                            }
110
                        }
111
                    }
Bogdan Timofte authored a month ago
112

            
113
                    settingsCard(title: "Danger Zone", tint: .red) {
114
                        Text("Delete this meter from the sidebar and clear its saved metadata. If the device is still nearby, it can appear again after a fresh Bluetooth discovery.")
115
                            .font(.footnote)
116
                            .foregroundColor(.secondary)
117

            
118
                        Button("Delete Meter") {
119
                            deleteConfirmationVisibility = true
120
                        }
121
                        .frame(maxWidth: .infinity)
122
                        .padding(.vertical, 10)
123
                        .meterCard(tint: .red, fillOpacity: 0.16, strokeOpacity: 0.22, cornerRadius: 14)
124
                        .buttonStyle(.plain)
125
                    }
Bogdan Timofte authored 2 months ago
126
                }
127
                .padding()
128
            }
129
            .background(
130
                LinearGradient(
131
                    colors: [meter.color.opacity(0.14), Color.clear],
132
                    startPoint: .topLeading,
133
                    endPoint: .bottomTrailing
134
            )
Bogdan Timofte authored a month ago
135
            .ignoresSafeArea()
136
        )
137
        .alert("Delete Meter?", isPresented: $deleteConfirmationVisibility) {
138
            Button("Delete", role: .destructive) {
139
                if appData.deleteMeter(macAddress: meter.btSerial.macAddress.description) {
140
                    onBackToHome()
141
                }
142
            }
143
            Button("Cancel", role: .cancel) {}
144
        } message: {
145
            Text("This removes the saved meter entry and disconnects the live meter view.")
Bogdan Timofte authored 2 months ago
146
        }
147
    }
Bogdan Timofte authored a month ago
148
    }
Bogdan Timofte authored 2 months ago
149

            
150
    private var settingsMacHeader: some View {
151
        HStack(spacing: 12) {
152
            Button(action: onBackToHome) {
153
                HStack(spacing: 4) {
154
                    Image(systemName: "chevron.left")
155
                        .font(.body.weight(.semibold))
156
                    Text("Back")
157
                }
158
                .foregroundColor(.accentColor)
159
            }
160
            .buttonStyle(.plain)
161

            
162
            Text("Meter Settings")
163
                .font(.headline)
164
                .lineLimit(1)
165

            
166
            Spacer()
167

            
168
            if meter.operationalState > .notPresent {
169
                RSSIView(RSSI: meter.btSerial.averageRSSI)
170
                    .frame(width: 18, height: 18)
171
            }
172
        }
173
        .padding(.horizontal, 16)
174
        .padding(.vertical, 10)
175
        .background(
176
            Rectangle()
177
                .fill(.ultraThinMaterial)
178
                .ignoresSafeArea(edges: .top)
179
        )
180
        .overlay(alignment: .bottom) {
181
            Rectangle()
182
                .fill(Color.secondary.opacity(0.12))
183
                .frame(height: 1)
184
        }
185
    }
186

            
187
    private func settingsCard<Content: View>(
188
        title: String,
189
        tint: Color,
190
        @ViewBuilder content: () -> Content
191
    ) -> some View {
192
        VStack(alignment: .leading, spacing: 12) {
193
            Text(title)
194
                .font(.headline)
195
            content()
196
        }
197
        .padding(18)
198
        .meterCard(tint: tint, fillOpacity: 0.18, strokeOpacity: 0.24)
199
    }
200
}