Jul 21 - Update to support photos' timestamp/location

This commit is contained in:
2026-07-21 16:22:13 -04:00
parent 2a0b264a5c
commit 1921f95faf
18 changed files with 261 additions and 5172 deletions
+26 -10
View File
@@ -240,7 +240,8 @@ struct IssueDetailView: View {
@State private var statusError: String?
@State private var showStatusPicker = false
// Resolution Photos
@State private var resultPhotos: [(image: UIImage, path: String)] = []
// Resolution photos are evidence too record capture time + GPS at shutter.
@State private var resultPhotos: [CapturedPhoto] = []
@State private var showResultCamera = false
@State private var showResultLibrary = false
@State private var isUploadingResultPhotos = false
@@ -641,6 +642,8 @@ struct IssueDetailView: View {
}
.navigationTitle("Issue Detail")
.navigationBarTitleDisplayMode(.inline)
// Warm up GPS so resolution photos taken here carry coordinates.
.onAppear { PhotoLocationProvider.shared.start() }
.toolbar {
ToolbarItem(placement: .primaryAction) {
Button {
@@ -981,14 +984,14 @@ struct IssueDetailView: View {
private func appendResultPhoto(_ img: UIImage) {
guard resultPhotos.count < maxResultPhotos,
let path = saveResultPhotoToDisk(img) else { return }
resultPhotos.append((image: img, path: path))
resultPhotos.append(CapturedPhoto(image: img, path: path))
}
private func appendResultPhotos(_ images: [UIImage]) {
for img in images {
guard resultPhotos.count < maxResultPhotos,
let path = saveResultPhotoToDisk(img) else { break }
resultPhotos.append((image: img, path: path))
resultPhotos.append(CapturedPhoto(image: img, path: path))
}
}
@@ -1024,7 +1027,12 @@ struct IssueDetailView: View {
do {
var serverPaths: [String] = []
for photo in resultPhotos {
let path = try await APIClient.shared.uploadResultPhoto(localPath: photo.path)
let path = try await APIClient.shared.uploadResultPhoto(
localPath: photo.path,
capturedAt: photo.capturedAt,
latitude: photo.latitude,
longitude: photo.longitude
)
serverPaths.append(path)
}
@@ -1066,7 +1074,9 @@ struct StandaloneIssueView: View {
@State private var severity = "medium"
@State private var description = ""
@State private var photos: [(image: UIImage, path: String)] = []
// CapturedPhoto records the capture moment + GPS fix at shutter time; the
// `image` / `path` members match the tuple this replaced.
@State private var photos: [CapturedPhoto] = []
@State private var showCamera = false
@State private var showLibrary = false
@State private var showBanner = false
@@ -1238,6 +1248,9 @@ struct StandaloneIssueView: View {
}
.navigationTitle("New Issue")
.navigationBarTitleDisplayMode(.inline)
// Warm up GPS so a fix exists the instant a photo is taken; the
// coordinates are burned into the photo server-side.
.onAppear { PhotoLocationProvider.shared.start() }
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") { dismiss() }
@@ -1284,13 +1297,13 @@ struct StandaloneIssueView: View {
private func appendPhoto(_ img: UIImage) {
guard photos.count < maxPhotos, let path = savePhotoToDisk(img) else { return }
photos.append((image: img, path: path))
photos.append(CapturedPhoto(image: img, path: path))
}
private func appendPhotos(_ images: [UIImage]) {
for img in images {
guard photos.count < maxPhotos, let path = savePhotoToDisk(img) else { break }
photos.append((image: img, path: path))
photos.append(CapturedPhoto(image: img, path: path))
}
}
@@ -1325,9 +1338,12 @@ struct StandaloneIssueView: View {
for photo in photos {
let pending = PendingPhoto(
localFilePath: photo.path,
entityType: "issue",
entityLocalId: issue.localId
localFilePath: photo.path,
entityType: "issue",
entityLocalId: issue.localId,
capturedAt: photo.capturedAt,
captureLatitude: photo.latitude,
captureLongitude: photo.longitude
)
context.insert(pending)
}