Fix crash when pasting screenshots, not being able to paste gifs

This commit is contained in:
Shadowfacts 2023-04-17 20:03:31 -04:00
parent 436159bd46
commit 849882287f
3 changed files with 14 additions and 16 deletions

View File

@ -1,6 +1,6 @@
//
// PostService.swift
// Tusker
// ComposeUI
//
// Created by Shadowfacts on 4/27/22.
// Copyright © 2022 Shadowfacts. All rights reserved.

View File

@ -72,8 +72,7 @@ class AttachmentsListController: ViewController {
draft.attachments.remove(atOffsets: indices)
}
@MainActor
private func insertAttachments(at offset: Int, itemProviders: [NSItemProvider]) async {
private func insertAttachments(at offset: Int, itemProviders: [NSItemProvider]) {
for provider in itemProviders where provider.canLoadObject(ofClass: DraftAttachment.self) {
provider.loadObject(ofClass: DraftAttachment.self) { object, error in
guard let attachment = object as? DraftAttachment else { return }
@ -87,9 +86,7 @@ class AttachmentsListController: ViewController {
private func addImage() {
parent.config.presentAssetPicker?({ results in
Task {
await self.insertAttachments(at: self.draft.attachments.count, itemProviders: results.map(\.itemProvider))
}
self.insertAttachments(at: self.draft.attachments.count, itemProviders: results.map(\.itemProvider))
})
}
@ -147,11 +144,14 @@ class AttachmentsListController: ViewController {
.onDelete(perform: controller.deleteAttachments)
.conditionally(controller.canAddAttachment) {
$0.onInsert(of: DraftAttachment.readableTypeIdentifiersForItemProvider, perform: { offset, providers in
Task {
await controller.insertAttachments(at: offset, itemProviders: providers)
}
controller.insertAttachments(at: offset, itemProviders: providers)
})
}
// only sort of works, see #240
.onDrop(of: DraftAttachment.readableTypeIdentifiersForItemProvider, isTargeted: nil) { providers in
controller.insertAttachments(at: 0, itemProviders: providers)
return true
}
}
private var addImageButton: some View {

View File

@ -50,10 +50,10 @@ public final class DraftAttachment: NSObject, Codable, ObservableObject, Identif
}
}
private let imageType = UTType.image.identifier
private let jpegType = UTType.jpeg.identifier
private let pngType = UTType.png.identifier
private let mp4Type = UTType.mpeg4Movie.identifier
private let quickTimeType = UTType.quickTimeMovie.identifier
private let dataType = UTType.data.identifier
private let gifType = UTType.gif.identifier
extension DraftAttachment: NSItemProviderWriting {
@ -91,7 +91,7 @@ extension DraftAttachment: NSItemProviderReading {
// todo: is there a better way of handling movies than manually adding all possible UTI types?
// just using kUTTypeMovie doesn't work, because we need the actually type in order to get the file extension
// without the file extension, getting the thumbnail and exporting the video for attachment upload fails
[typeIdentifier] + UIImage.readableTypeIdentifiersForItemProvider + [mp4Type, quickTimeType] + NSURL.readableTypeIdentifiersForItemProvider
[typeIdentifier, gifType, jpegType, pngType, mp4Type, quickTimeType]
}
public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> DraftAttachment {
@ -101,15 +101,13 @@ extension DraftAttachment: NSItemProviderReading {
return DraftAttachment(data: .gif(data))
} else if UIImage.readableTypeIdentifiersForItemProvider.contains(typeIdentifier) {
return DraftAttachment(data: .image(data, originalType: UTType(typeIdentifier)!))
} else if let type = UTType(typeIdentifier), type == .mpeg4Movie || type == .quickTimeMovie {
} else if typeIdentifier == mp4Type || typeIdentifier == quickTimeType {
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
let temporaryFileName = ProcessInfo().globallyUniqueString
let fileExt = type.preferredFilenameExtension!
let fileExt = UTType(typeIdentifier)!.preferredFilenameExtension!
let temporaryFileURL = temporaryDirectoryURL.appendingPathComponent(temporaryFileName).appendingPathExtension(fileExt)
try data.write(to: temporaryFileURL)
return DraftAttachment(data: .video(temporaryFileURL))
} else if NSURL.readableTypeIdentifiersForItemProvider.contains(typeIdentifier), let url = try? NSURL.object(withItemProviderData: data, typeIdentifier: typeIdentifier) as URL {
return DraftAttachment(data: .video(url))
} else {
throw ItemProviderError.incompatibleTypeIdentifier
}