diff --git a/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate b/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate index 42d4c1f..29cefd4 100644 Binary files a/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate and b/wake.xcodeproj/project.xcworkspace/xcuserdata/elliwood.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/wake/Info.plist b/wake/Info.plist index 4719d52..f985257 100644 --- a/wake/Info.plist +++ b/wake/Info.plist @@ -20,6 +20,10 @@ NSAppleIDUsageDescription Sign in with Apple is used to authenticate your account + NSCameraUsageDescription + We need access to your camera to take photos + NSPhotoLibraryUsageDescription + We need access to your photo library to select photos UIAppFonts Inter.ttf diff --git a/wake/View/Components/Upload/ImageCaptureView.swift b/wake/View/Components/Upload/ImageCaptureView.swift new file mode 100644 index 0000000..38db249 --- /dev/null +++ b/wake/View/Components/Upload/ImageCaptureView.swift @@ -0,0 +1,70 @@ +import AVFoundation +import UIKit + +class ImageCaptureManager: NSObject { + static let shared = ImageCaptureManager() + private var completion: ((UIImage?) -> Void)? + private weak var presentingViewController: UIViewController? + + func captureImage(from viewController: UIViewController, completion: @escaping (UIImage?) -> Void) { + self.completion = completion + self.presentingViewController = viewController + + let status = AVCaptureDevice.authorizationStatus(for: .video) + + switch status { + case .authorized: + presentImagePicker() + case .notDetermined: + AVCaptureDevice.requestAccess(for: .video) { [weak self] granted in + DispatchQueue.main.async { + if granted { + self?.presentImagePicker() + } else { + self?.completion?(nil) + } + } + } + default: + completion(nil) + } + } + + private func presentImagePicker() { + guard UIImagePickerController.isSourceTypeAvailable(.camera) else { + completion?(nil) + return + } + + let picker = UIImagePickerController() + picker.sourceType = .camera + picker.allowsEditing = true + picker.delegate = self + + // Present from the topmost view controller + var topController = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController + while let presentedVC = topController?.presentedViewController { + topController = presentedVC + } + + topController?.present(picker, animated: true) + } +} + +extension ImageCaptureManager: UINavigationControllerDelegate, UIImagePickerControllerDelegate { + func imagePickerController(_ picker: UIImagePickerController, + didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + let image = info[.editedImage] as? UIImage ?? info[.originalImage] as? UIImage + picker.dismiss(animated: true) { [weak self] in + self?.completion?(image) + self?.completion = nil + } + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + picker.dismiss(animated: true) { [weak self] in + self?.completion?(nil) + self?.completion = nil + } + } +} \ No newline at end of file diff --git a/wake/View/Owner/UserInfo/AvatarPicker.swift b/wake/View/Owner/UserInfo/AvatarPicker.swift index e4fec29..03fe974 100644 --- a/wake/View/Owner/UserInfo/AvatarPicker.swift +++ b/wake/View/Owner/UserInfo/AvatarPicker.swift @@ -3,6 +3,7 @@ import SwiftUI public struct AvatarPicker: View { @StateObject private var uploadManager = MediaUploadManager() @State private var showMediaPicker = false + @State private var showImageCapture = false @State private var isUploading = false @Binding var selectedImage: UIImage? @Binding var showUsername: Bool @@ -12,7 +13,10 @@ public struct AvatarPicker: View { // Animation state @State private var isAnimating = false - public init(selectedImage: Binding, showUsername: Binding, isKeyboardVisible: Binding, uploadedFileId: Binding) { + public init(selectedImage: Binding, + showUsername: Binding, + isKeyboardVisible: Binding, + uploadedFileId: Binding) { self._selectedImage = selectedImage self._showUsername = showUsername self._isKeyboardVisible = isKeyboardVisible @@ -139,6 +143,35 @@ public struct AvatarPicker: View { } } } + if !showUsername { + Button(action: { + withAnimation { + showImageCapture = true + } + }) { + Text("Take a Photo") + .font(Typography.font(for: .subtitle, family: .inter)) + .fontWeight(.regular) + .frame(maxWidth: .infinity) + .padding() + .foregroundColor(.black) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(Color.themePrimaryLight) + ) + } + .frame(maxWidth: .infinity) + .sheet(isPresented: $showImageCapture) { + CameraView(isPresented: $showImageCapture) { image in + selectedImage = image + uploadManager.selectedMedia = [.image(image)] + withAnimation { + isUploading = true + } + uploadManager.startUpload() + } + } + } } } diff --git a/wake/View/Owner/UserInfo/CameraView.swift b/wake/View/Owner/UserInfo/CameraView.swift new file mode 100644 index 0000000..8cfa8e4 --- /dev/null +++ b/wake/View/Owner/UserInfo/CameraView.swift @@ -0,0 +1,30 @@ +import SwiftUI +import UIKit + +struct CameraView: UIViewControllerRepresentable { + @Binding var isPresented: Bool + let onImageSelected: (UIImage) -> Void + @Environment(\.presentationMode) private var presentationMode + + func makeUIViewController(context: Context) -> UIViewController { + let viewController = UIViewController() + viewController.view.backgroundColor = .clear + return viewController + } + + func updateUIViewController(_ uiViewController: UIViewController, context: Context) { + if isPresented { + DispatchQueue.main.async { + if let rootVC = UIApplication.shared.windows.first?.rootViewController { + ImageCaptureManager.shared.captureImage(from: rootVC) { image in + if let image = image { + onImageSelected(image) + } + isPresented = false + presentationMode.wrappedValue.dismiss() + } + } + } + } + } +} \ No newline at end of file diff --git a/wake/View/Owner/UserInfo/UserInfo.swift b/wake/View/Owner/UserInfo/UserInfo.swift index 37521df..4e10afe 100644 --- a/wake/View/Owner/UserInfo/UserInfo.swift +++ b/wake/View/Owner/UserInfo/UserInfo.swift @@ -108,23 +108,6 @@ struct UserInfo: View { uploadedFileId: $uploadedFileId ) .padding(.top, isKeyboardVisible ? 0 : 20) - - if !showUsername { - Button(action: { - // Action for second button - }) { - Text("Take a Photo") - .font(Typography.font(for: .subtitle, family: .inter)) - .fontWeight(.regular) - .frame(maxWidth: .infinity) - .padding() - .foregroundColor(.black) - .background( - RoundedRectangle(cornerRadius: 16) - .fill(Color.themePrimaryLight) - ) - } - } if showUsername { TextField("Username", text: $userName)