06/19 Update inspections/issues sent via email, and duplicated issue photos issues

This commit is contained in:
Nguyen Ngo
2026-06-19 17:28:09 -04:00
parent 95c8238c00
commit a57d6f02ba
7 changed files with 1366 additions and 12 deletions
@@ -25,12 +25,15 @@ struct ExecuteInspectionView: View {
@State private var formValues: [String: String] = [:]
@State private var showFlagIssue = false
@State private var showSubmitAlert = false
@State private var showNoGPSAlert = false
@State private var isSaving = false
@State private var isSubmitting = false
@State private var submitResult: SubmitResult?
// Location manager created lazily when submit alert fires so the
// permission prompt only appears at the point of actual submission.
// Location manager created on view init. requestLocation() is called in
// onAppear so the permission prompt (and GPS fix acquisition) starts as
// soon as the inspector opens the inspection, maximising the chance of
// having a fix ready by submit time.
@State private var locationManager = InspectionLocationManager()
// Auto-save interval
@@ -82,6 +85,11 @@ struct ExecuteInspectionView: View {
}
.onAppear {
formValues = inspection.formData.compactMapValues { "\($0)" }
// Request Location permission (and start acquiring a fix) the moment
// the inspector opens the inspection gives GPS the entire duration
// of the inspection to get a fix, rather than only the few seconds
// the confirm dialog is on screen. requestLocation() is idempotent.
locationManager.requestLocation()
}
.onDisappear {
saveDraft()
@@ -96,13 +104,27 @@ struct ExecuteInspectionView: View {
FlagIssueView(inspection: inspection)
}
.alert("Submit Inspection", isPresented: $showSubmitAlert) {
Button("Submit") { Task { await submitInspection() } }
Button("Submit") {
if locationManager.lastLocation == nil {
// No GPS fix yet warn before proceeding rather than
// silently submitting without a location.
showNoGPSAlert = true
} else {
Task { await submitInspection() }
}
}
Button("Cancel", role: .cancel) {}
} message: {
Text(sync.isOnline
? "Once submitted the inspection cannot be edited. It will be sent to the server now."
: "Once submitted the inspection cannot be edited. It will sync automatically when you're back online.")
}
.alert("No GPS Location", isPresented: $showNoGPSAlert) {
Button("Submit Anyway") { Task { await submitInspection() } }
Button("Wait & Retry", role: .cancel) { locationManager.requestLocation() }
} message: {
Text("This inspection's location could not be recorded — Location permission may be denied, or no GPS signal is available right now. You can submit without it, or wait a moment and try again.")
}
.onChange(of: showSubmitAlert) { _, showing in
// Begin acquiring a GPS fix the moment the confirm dialog appears
// so a location is likely ready by the time the inspector taps Submit.
@@ -1161,9 +1183,12 @@ struct ConnectivityBadge: View {
// MARK: - InspectionLocationManager
// Thin CLLocationManager wrapper used only by ExecuteInspectionView.
// Requests a single best-accuracy fix when the Submit confirmation dialog
// appears. The fix is stored in lastLocation and read synchronously at the
// moment the inspector confirms submission.
// requestLocation() is called as soon as the inspection opens (onAppear),
// giving GPS the full duration of the inspection to acquire a fix, and again
// when the Submit confirmation dialog appears as a fallback retry. The fix
// is stored in lastLocation and read synchronously at submit time; if still
// nil, the view warns the inspector and lets them choose to submit anyway
// or wait and retry GPS is not silently dropped.
//
// Design constraints:
// - @Observable is unavailable before iOS 17 WWDC beta; use plain class +