From 64fb634166f81584d730c2f6e276f946371f7fb0 Mon Sep 17 00:00:00 2001 From: jack <212554440+jackjackbits@users.noreply.github.com> Date: Sun, 19 Oct 2025 15:23:05 +0200 Subject: [PATCH] Fix camera icon in DM sheets using parent-child presentation pattern (#834) Implements mutually-exclusive image picker presentations to fix the error "Currently, only presenting a single sheet is supported" when tapping camera in a DM. Solution: - ContentView: Only presents image picker when NOT in a sheet (when showSidebar=false and no private chat active) - peopleSheetView: Only presents image picker when IN a sheet (when showSidebar=true or private chat active) This ensures only ONE presentation is active at any time, preventing conflicts. Uses fullScreenCover on iOS to allow presentation over sheets. Addresses feedback from @qalandarov in PR #834 with minimal approach. Co-authored-by: jack --- bitchat/Views/ContentView.swift | 67 ++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index 7fc7d606..6d37bec1 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -203,7 +203,15 @@ struct ContentView: View { } } #if os(iOS) - .sheet(isPresented: $showImagePicker) { + // Only present image picker from main view when NOT in a sheet + .fullScreenCover(isPresented: Binding( + get: { showImagePicker && !showSidebar && viewModel.selectedPrivateChatPeer == nil }, + set: { newValue in + if !newValue { + showImagePicker = false + } + } + )) { ImagePickerView(sourceType: imagePickerSourceType) { image in showImagePicker = false if let image = image { @@ -223,7 +231,15 @@ struct ContentView: View { } #endif #if os(macOS) - .sheet(isPresented: $showMacImagePicker) { + // Only present Mac image picker from main view when NOT in a sheet + .sheet(isPresented: Binding( + get: { showMacImagePicker && !showSidebar && viewModel.selectedPrivateChatPeer == nil }, + set: { newValue in + if !newValue { + showMacImagePicker = false + } + } + )) { MacImagePickerView { url in showMacImagePicker = false if let url = url { @@ -906,6 +922,53 @@ struct ContentView: View { #if os(macOS) .frame(minWidth: 420, minHeight: 520) #endif + // Present image picker from sheet context when IN a sheet (parent-child pattern) + #if os(iOS) + .fullScreenCover(isPresented: Binding( + get: { showImagePicker && (showSidebar || viewModel.selectedPrivateChatPeer != nil) }, + set: { newValue in + if !newValue { + showImagePicker = false + } + } + )) { + ImagePickerView(sourceType: imagePickerSourceType) { image in + showImagePicker = false + if let image = image { + Task { + do { + let processedURL = try ImageUtils.processImage(image) + await MainActor.run { + viewModel.sendImage(from: processedURL) + } + } catch { + SecureLogger.error("Image processing failed: \(error)", category: .session) + } + } + } + } + .ignoresSafeArea() + } + #endif + #if os(macOS) + .sheet(isPresented: $showMacImagePicker) { + MacImagePickerView { url in + showMacImagePicker = false + if let url = url { + Task { + do { + let processedURL = try ImageUtils.processImage(at: url) + await MainActor.run { + viewModel.sendImage(from: processedURL) + } + } catch { + SecureLogger.error("Image processing failed: \(error)", category: .session) + } + } + } + } + } + #endif } // MARK: - People Sheet Views