Use Photos picker on mac

This commit is contained in:
jack
2025-10-14 22:21:17 +02:00
parent 32a8e558ed
commit 9e0542df73
2 changed files with 21 additions and 36 deletions
+7 -4
View File
@@ -2443,12 +2443,18 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
} }
@MainActor @MainActor
func sendImage(from sourceURL: URL) { func sendImage(from sourceURL: URL, cleanup: (() -> Void)? = nil) {
let targetPeer = selectedPrivateChatPeer let targetPeer = selectedPrivateChatPeer
Task.detached(priority: .userInitiated) { [weak self] in Task.detached(priority: .userInitiated) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
var processedURL: URL? var processedURL: URL?
defer {
if let url = processedURL {
try? FileManager.default.removeItem(at: url)
}
cleanup?()
}
do { do {
let outputURL = try ImageUtils.processImage(at: sourceURL) let outputURL = try ImageUtils.processImage(at: sourceURL)
processedURL = outputURL processedURL = outputURL
@@ -2484,9 +2490,6 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
await MainActor.run { await MainActor.run {
self.addSystemMessage("Failed to prepare image for sending.") self.addSystemMessage("Failed to prepare image for sending.")
} }
if let url = processedURL {
try? FileManager.default.removeItem(at: url)
}
} }
} }
} }
+14 -32
View File
@@ -9,8 +9,11 @@
import SwiftUI import SwiftUI
#if os(iOS) #if os(iOS)
import UIKit import UIKit
#endif
#if canImport(PhotosUI)
import PhotosUI import PhotosUI
#else #endif
#if os(macOS)
import AppKit import AppKit
#endif #endif
import UniformTypeIdentifiers import UniformTypeIdentifiers
@@ -69,9 +72,8 @@ struct ContentView: View {
@State private var recordingDuration: TimeInterval = 0 @State private var recordingDuration: TimeInterval = 0
@State private var recordingTimer: Timer? @State private var recordingTimer: Timer?
@State private var recordingStartDate: Date? @State private var recordingStartDate: Date?
@State private var showImageImporter = false
@State private var showFileImporter = false @State private var showFileImporter = false
#if os(iOS) #if canImport(PhotosUI)
@State private var showPhotoPicker = false @State private var showPhotoPicker = false
@State private var selectedPhotoPickerItem: PhotosPickerItem? @State private var selectedPhotoPickerItem: PhotosPickerItem?
#endif #endif
@@ -199,23 +201,16 @@ struct ContentView: View {
FingerprintView(viewModel: viewModel, peerID: peerID) FingerprintView(viewModel: viewModel, peerID: peerID)
} }
} }
#if os(iOS) #if canImport(PhotosUI)
.photosPicker(isPresented: $showPhotoPicker, selection: $selectedPhotoPickerItem, matching: .images) .photosPicker(isPresented: $showPhotoPicker, selection: $selectedPhotoPickerItem, matching: .images)
.onChange(of: selectedPhotoPickerItem) { newItem in .onChange(of: selectedPhotoPickerItem) { newItem in
guard let item = newItem else { return } guard let item = newItem else { return }
Task { await handlePhotoSelection(item) } 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 #endif
.fileImporter(isPresented: $showFileImporter, allowedContentTypes: [.data], allowsMultipleSelection: false) { result in
handleImportResult(result, handler: handleImportedFile)
}
.sheet(isPresented: Binding( .sheet(isPresented: Binding(
get: { imagePreviewURL != nil }, get: { imagePreviewURL != nil },
set: { presenting in if !presenting { imagePreviewURL = nil } } set: { presenting in if !presenting { imagePreviewURL = nil } }
@@ -225,24 +220,15 @@ struct ContentView: View {
} }
} }
.confirmationDialog("Attach", isPresented: $showAttachmentActions, titleVisibility: .visible) { .confirmationDialog("Attach", isPresented: $showAttachmentActions, titleVisibility: .visible) {
#if os(iOS) #if canImport(PhotosUI)
Button("Image") { Button("Image") {
showAttachmentActions = false showAttachmentActions = false
DispatchQueue.main.async { showPhotoPicker = true } DispatchQueue.main.async { showPhotoPicker = true }
} }
#else
Button("Image") {
showAttachmentActions = false
DispatchQueue.main.async { showImageImporter = true }
}
#endif #endif
Button("File") { Button("File") {
showAttachmentActions = false showAttachmentActions = false
#if os(iOS)
DispatchQueue.main.async { showFileImporter = true } DispatchQueue.main.async { showFileImporter = true }
#else
DispatchQueue.main.async { showFileImporter = true }
#endif
} }
Button("Cancel", role: .cancel) {} Button("Cancel", role: .cancel) {}
} }
@@ -2038,7 +2024,7 @@ private extension ContentView {
} }
} }
#if os(iOS) #if canImport(PhotosUI)
func handlePhotoSelection(_ item: PhotosPickerItem) async { func handlePhotoSelection(_ item: PhotosPickerItem) async {
defer { Task { @MainActor in selectedPhotoPickerItem = nil } } defer { Task { @MainActor in selectedPhotoPickerItem = nil } }
do { do {
@@ -2048,7 +2034,9 @@ private extension ContentView {
.appendingPathExtension("jpg") .appendingPathExtension("jpg")
try data.write(to: tempURL, options: .atomic) try data.write(to: tempURL, options: .atomic)
await MainActor.run { await MainActor.run {
viewModel.sendImage(from: tempURL) viewModel.sendImage(from: tempURL) {
try? FileManager.default.removeItem(at: tempURL)
}
} }
} }
} catch { } catch {
@@ -2057,12 +2045,6 @@ private extension ContentView {
} }
#endif #endif
func handleImportedImage(url: URL) async {
await MainActor.run {
viewModel.sendImage(from: url)
}
}
func handleImportedFile(url: URL) async { func handleImportedFile(url: URL) async {
do { do {
let fileManager = FileManager.default let fileManager = FileManager.default