Full-screen camera with photo library option

- Change to fullScreenCover for immersive camera experience
- Add action sheet with 'Take Photo' and 'Choose from Library' options
- Renamed ImagePickerView to support both camera and library sources
- Both options open full-screen for better UX
- Updated accessibility label to 'Add photo' (more accurate)
This commit is contained in:
jack
2025-10-18 13:52:02 +02:00
parent a84b8c05f1
commit 369c335088
+25 -10
View File
@@ -69,7 +69,9 @@ struct ContentView: View {
@State private var recordingTimer: Timer? @State private var recordingTimer: Timer?
@State private var recordingStartDate: Date? @State private var recordingStartDate: Date?
#if os(iOS) #if os(iOS)
@State private var showCameraPicker = false @State private var showImagePicker = false
@State private var imagePickerSourceType: UIImagePickerController.SourceType = .camera
@State private var showImageSourcePicker = false
#endif #endif
@ScaledMetric(relativeTo: .body) private var headerHeight: CGFloat = 44 @ScaledMetric(relativeTo: .body) private var headerHeight: CGFloat = 44
@ScaledMetric(relativeTo: .subheadline) private var headerPeerIconSize: CGFloat = 11 @ScaledMetric(relativeTo: .subheadline) private var headerPeerIconSize: CGFloat = 11
@@ -204,9 +206,9 @@ struct ContentView: View {
} }
} }
#if os(iOS) #if os(iOS)
.sheet(isPresented: $showCameraPicker) { .fullScreenCover(isPresented: $showImagePicker) {
CameraPickerView { image in ImagePickerView(sourceType: imagePickerSourceType) { image in
showCameraPicker = false showImagePicker = false
if let image = image { if let image = image {
Task { Task {
do { do {
@@ -215,12 +217,23 @@ struct ContentView: View {
viewModel.sendImage(from: processedURL) viewModel.sendImage(from: processedURL)
} }
} catch { } catch {
SecureLogger.error("Camera image processing failed: \(error)", category: .session) SecureLogger.error("Image processing failed: \(error)", category: .session)
} }
} }
} }
} }
} }
.confirmationDialog("Add Photo", isPresented: $showImageSourcePicker, titleVisibility: .visible) {
Button("Take Photo") {
imagePickerSourceType = .camera
showImagePicker = true
}
Button("Choose from Library") {
imagePickerSourceType = .photoLibrary
showImagePicker = true
}
Button("Cancel", role: .cancel) {}
}
#endif #endif
.sheet(isPresented: Binding( .sheet(isPresented: Binding(
get: { imagePreviewURL != nil }, get: { imagePreviewURL != nil },
@@ -1805,7 +1818,7 @@ private extension ContentView {
var attachmentButton: some View { var attachmentButton: some View {
Button(action: { Button(action: {
#if os(iOS) #if os(iOS)
showCameraPicker = true showImageSourcePicker = true
#endif #endif
}) { }) {
Image(systemName: "camera.circle.fill") Image(systemName: "camera.circle.fill")
@@ -1814,7 +1827,7 @@ private extension ContentView {
.frame(width: 36, height: 36) .frame(width: 36, height: 36)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.accessibilityLabel("Take photo") .accessibilityLabel("Add photo")
} }
var sendOrMicButton: some View { var sendOrMicButton: some View {
@@ -2128,15 +2141,17 @@ struct ImagePreviewView: View {
} }
#if os(iOS) #if os(iOS)
// MARK: - Camera Picker // MARK: - Image Picker (Camera or Photo Library)
struct CameraPickerView: UIViewControllerRepresentable { struct ImagePickerView: UIViewControllerRepresentable {
let sourceType: UIImagePickerController.SourceType
let completion: (UIImage?) -> Void let completion: (UIImage?) -> Void
func makeUIViewController(context: Context) -> UIImagePickerController { func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController() let picker = UIImagePickerController()
picker.sourceType = .camera picker.sourceType = sourceType
picker.delegate = context.coordinator picker.delegate = context.coordinator
picker.allowsEditing = false picker.allowsEditing = false
picker.modalPresentationStyle = .fullScreen
return picker return picker
} }