mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 22:05:21 +00:00
Use Photos picker on mac
This commit is contained in:
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user