diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 308d9355..1e376c6c 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -2443,12 +2443,18 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { } @MainActor - func sendImage(from sourceURL: URL) { + func sendImage(from sourceURL: URL, cleanup: (() -> Void)? = nil) { let targetPeer = selectedPrivateChatPeer Task.detached(priority: .userInitiated) { [weak self] in guard let self = self else { return } var processedURL: URL? + defer { + if let url = processedURL { + try? FileManager.default.removeItem(at: url) + } + cleanup?() + } do { let outputURL = try ImageUtils.processImage(at: sourceURL) processedURL = outputURL @@ -2484,9 +2490,6 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { await MainActor.run { self.addSystemMessage("Failed to prepare image for sending.") } - if let url = processedURL { - try? FileManager.default.removeItem(at: url) - } } } } diff --git a/bitchat/Views/ContentView.swift b/bitchat/Views/ContentView.swift index 5e61908d..3cac1767 100644 --- a/bitchat/Views/ContentView.swift +++ b/bitchat/Views/ContentView.swift @@ -9,8 +9,11 @@ import SwiftUI #if os(iOS) import UIKit +#endif +#if canImport(PhotosUI) import PhotosUI -#else +#endif +#if os(macOS) import AppKit #endif import UniformTypeIdentifiers @@ -69,9 +72,8 @@ struct ContentView: View { @State private var recordingDuration: TimeInterval = 0 @State private var recordingTimer: Timer? @State private var recordingStartDate: Date? - @State private var showImageImporter = false @State private var showFileImporter = false -#if os(iOS) +#if canImport(PhotosUI) @State private var showPhotoPicker = false @State private var selectedPhotoPickerItem: PhotosPickerItem? #endif @@ -199,23 +201,16 @@ struct ContentView: View { FingerprintView(viewModel: viewModel, peerID: peerID) } } -#if os(iOS) +#if canImport(PhotosUI) .photosPicker(isPresented: $showPhotoPicker, selection: $selectedPhotoPickerItem, matching: .images) .onChange(of: selectedPhotoPickerItem) { newItem in guard let item = newItem else { return } Task { await handlePhotoSelection(item) } } - .fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.data], allowsMultipleSelection: false) { result in - handleImportResult(result, handler: handleImportedFile) - } -#else - .fileImporter(isPresented: $showImageImporter, allowedContentTypes: [.image], allowsMultipleSelection: false) { result in - handleImportResult(result, handler: handleImportedImage) - } - .fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.data], allowsMultipleSelection: false) { result in - handleImportResult(result, handler: handleImportedFile) - } #endif + .fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.data], allowsMultipleSelection: false) { result in + handleImportResult(result, handler: handleImportedFile) + } .sheet(isPresented: Binding( get: { imagePreviewURL != nil }, set: { presenting in if !presenting { imagePreviewURL = nil } } @@ -225,24 +220,15 @@ struct ContentView: View { } } .confirmationDialog("Attach", isPresented: $showAttachmentActions, titleVisibility: .visible) { -#if os(iOS) +#if canImport(PhotosUI) Button("Image") { showAttachmentActions = false DispatchQueue.main.async { showPhotoPicker = true } } -#else - Button("Image") { - showAttachmentActions = false - DispatchQueue.main.async { showImageImporter = true } - } #endif Button("File") { showAttachmentActions = false -#if os(iOS) DispatchQueue.main.async { showFileImporter = true } -#else - DispatchQueue.main.async { showFileImporter = true } -#endif } Button("Cancel", role: .cancel) {} } @@ -2038,7 +2024,7 @@ private extension ContentView { } } -#if os(iOS) +#if canImport(PhotosUI) func handlePhotoSelection(_ item: PhotosPickerItem) async { defer { Task { @MainActor in selectedPhotoPickerItem = nil } } do { @@ -2048,7 +2034,9 @@ private extension ContentView { .appendingPathExtension("jpg") try data.write(to: tempURL, options: .atomic) await MainActor.run { - viewModel.sendImage(from: tempURL) + viewModel.sendImage(from: tempURL) { + try? FileManager.default.removeItem(at: tempURL) + } } } } catch { @@ -2057,12 +2045,6 @@ private extension ContentView { } #endif - func handleImportedImage(url: URL) async { - await MainActor.run { - viewModel.sendImage(from: url) - } - } - func handleImportedFile(url: URL) async { do { let fileManager = FileManager.default