164 lines
5.4 KiB
Swift
164 lines
5.4 KiB
Swift
//
|
|
// PhotoReviewView.swift
|
|
// CameraTester
|
|
//
|
|
// Created by Matt Bruce on 1/2/26.
|
|
//
|
|
|
|
import SwiftUI
|
|
import Bedrock
|
|
|
|
// MARK: - Photo Review View
|
|
|
|
struct PhotoReviewView: View {
|
|
let photo: CapturedPhoto
|
|
let isSaving: Bool
|
|
let saveError: String?
|
|
let onRetake: () -> Void
|
|
let onSave: () -> Void
|
|
|
|
var body: some View {
|
|
ZStack {
|
|
// Photo display
|
|
Color.black
|
|
.ignoresSafeArea()
|
|
|
|
Image(uiImage: photo.image)
|
|
.resizable()
|
|
.scaledToFit()
|
|
.ignoresSafeArea()
|
|
|
|
// Top toolbar
|
|
VStack {
|
|
HStack {
|
|
// Retake button
|
|
Button(action: onRetake) {
|
|
Image(systemName: "arrow.triangle.2.circlepath")
|
|
.font(.system(size: 20, weight: .medium))
|
|
.foregroundColor(.white)
|
|
.frame(width: 44, height: 44)
|
|
.background(
|
|
Circle()
|
|
.fill(Color.black.opacity(0.6))
|
|
)
|
|
}
|
|
|
|
Spacer()
|
|
|
|
// Close button
|
|
Button(action: onRetake) {
|
|
Image(systemName: "xmark")
|
|
.font(.system(size: 20, weight: .medium))
|
|
.foregroundColor(.white)
|
|
.frame(width: 44, height: 44)
|
|
.background(
|
|
Circle()
|
|
.fill(Color.black.opacity(0.6))
|
|
)
|
|
}
|
|
}
|
|
.padding(.horizontal, Design.Spacing.large)
|
|
.padding(.top, Design.Spacing.large)
|
|
|
|
Spacer()
|
|
|
|
// Bottom action bar
|
|
VStack(spacing: Design.Spacing.medium) {
|
|
// Save status or error
|
|
if let error = saveError {
|
|
Text(error)
|
|
.foregroundColor(.red)
|
|
.font(.system(size: 14, weight: .medium))
|
|
.multilineTextAlignment(.center)
|
|
.padding(.vertical, Design.Spacing.small)
|
|
.padding(.horizontal, Design.Spacing.medium)
|
|
.background(
|
|
RoundedRectangle(cornerRadius: Design.CornerRadius.medium)
|
|
.fill(Color.red.opacity(0.2))
|
|
)
|
|
} else if isSaving {
|
|
HStack(spacing: Design.Spacing.small) {
|
|
ProgressView()
|
|
.tint(.white)
|
|
Text("Saving...")
|
|
.foregroundColor(.white)
|
|
.font(.system(size: 16, weight: .medium))
|
|
}
|
|
.padding(.vertical, Design.Spacing.small)
|
|
}
|
|
|
|
// Action buttons
|
|
HStack(spacing: Design.Spacing.xLarge) {
|
|
// Share button
|
|
ShareButton(photo: photo.image)
|
|
|
|
// Save button
|
|
Button(action: onSave) {
|
|
ZStack {
|
|
Circle()
|
|
.fill(Color.white)
|
|
.frame(width: 80, height: 80)
|
|
|
|
Image(systemName: "checkmark")
|
|
.font(.system(size: 24, weight: .bold))
|
|
.foregroundColor(.black)
|
|
}
|
|
.shadow(radius: 5)
|
|
}
|
|
.disabled(isSaving)
|
|
}
|
|
.padding(.bottom, Design.Spacing.large)
|
|
}
|
|
.padding(.horizontal, Design.Spacing.large)
|
|
}
|
|
}
|
|
.accessibilityLabel("Photo review")
|
|
.accessibilityHint("Use the buttons at the bottom to save or share your photo")
|
|
}
|
|
}
|
|
|
|
// MARK: - Share Button
|
|
|
|
struct ShareButton: View {
|
|
let photo: UIImage
|
|
@State private var isShareSheetPresented = false
|
|
|
|
var body: some View {
|
|
Button(action: {
|
|
isShareSheetPresented = true
|
|
}) {
|
|
ZStack {
|
|
Circle()
|
|
.fill(Color.black.opacity(0.6))
|
|
.frame(width: 80, height: 80)
|
|
|
|
Image(systemName: "square.and.arrow.up")
|
|
.font(.system(size: 24, weight: .medium))
|
|
.foregroundColor(.white)
|
|
}
|
|
.shadow(radius: 5)
|
|
}
|
|
.sheet(isPresented: $isShareSheetPresented) {
|
|
ShareSheet(activityItems: [photo])
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Share Sheet
|
|
|
|
struct ShareSheet: UIViewControllerRepresentable {
|
|
let activityItems: [Any]
|
|
|
|
func makeUIViewController(context: Context) -> UIActivityViewController {
|
|
let controller = UIActivityViewController(
|
|
activityItems: activityItems,
|
|
applicationActivities: nil
|
|
)
|
|
return controller
|
|
}
|
|
|
|
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
|
|
// No updates needed
|
|
}
|
|
}
|