SelfieCam/SelfieCam/Features/Camera/Views/PhotoReviewView.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
}
}