diff --git a/Tusker/Screens/Large Image/LargeImageContentView.swift b/Tusker/Screens/Large Image/LargeImageContentView.swift index 69e3c1ec..c7652f08 100644 --- a/Tusker/Screens/Large Image/LargeImageContentView.swift +++ b/Tusker/Screens/Large Image/LargeImageContentView.swift @@ -197,7 +197,7 @@ class LargeImageGifvContentView: GifvAttachmentView, LargeImageContentView { } -fileprivate class ImageActivityItemSource: NSObject, UIActivityItemSource { +class ImageActivityItemSource: NSObject, UIActivityItemSource { let data: Data let url: URL let image: UIImage? @@ -231,7 +231,7 @@ fileprivate class ImageActivityItemSource: NSObject, UIActivityItemSource { } } -fileprivate class GifvActivityItemSource: NSObject, UIActivityItemSource { +class GifvActivityItemSource: NSObject, UIActivityItemSource { let asset: AVAsset let attachment: Attachment diff --git a/Tusker/Views/Attachments/AttachmentView.swift b/Tusker/Views/Attachments/AttachmentView.swift index c424d3b3..cc4cd0e7 100644 --- a/Tusker/Views/Attachments/AttachmentView.swift +++ b/Tusker/Views/Attachments/AttachmentView.swift @@ -203,7 +203,7 @@ class AttachmentView: GIFImageView { await displayImage() } } else if let image { - source = .image(attachment.url, image) + source = .image(attachment.url, data, image) await displayImage() } } @@ -225,7 +225,7 @@ class AttachmentView: GIFImageView { return } - source = .image(previewURL, image) + source = .image(previewURL, nil, image) await displayImage() } else { let asset = AVURLAsset(url: attachment.url) @@ -246,7 +246,7 @@ class AttachmentView: GIFImageView { !Task.isCancelled else { return } - source = .image(attachment.url, prepared) + source = .image(attachment.url, nil, prepared) await displayImage() } } @@ -315,7 +315,7 @@ class AttachmentView: GIFImageView { case nil: self.image = nil - case let .image(url, sourceImage): + case let .image(url, _, sourceImage): if isGrayscale { self.image = await ImageGrayscalifier.convert(url: url, image: sourceImage) } else { @@ -329,13 +329,6 @@ class AttachmentView: GIFImageView { } else { self.image = sourceImage } - - case let .cgImage(url, cgImage): - if isGrayscale { - self.image = await ImageGrayscalifier.convert(url: url, cgImage: cgImage) - } else { - self.image = UIImage(cgImage: cgImage) - } } } @@ -424,9 +417,9 @@ class AttachmentView: GIFImageView { fileprivate extension AttachmentView { enum Source { - case image(URL, UIImage) + case image(URL, Data?, UIImage) case gifData(URL, Data, UIImage?) - case cgImage(URL, CGImage) +// case cgImage(URL, CGImage) } struct Badges: OptionSet { @@ -439,7 +432,7 @@ fileprivate extension AttachmentView { extension AttachmentView: UIContextMenuInteractionDelegate { func contextMenuInteraction(_ interaction: UIContextMenuInteraction, configurationForMenuAtLocation location: CGPoint) -> UIContextMenuConfiguration? { - return UIContextMenuConfiguration(identifier: nil, previewProvider: { () -> UIViewController? in + return UIContextMenuConfiguration { [unowned self] () -> UIViewController? in if self.attachment.kind == .image { return AttachmentPreviewViewController(sourceView: self) } else if self.attachment.kind == .gifv { @@ -449,8 +442,38 @@ extension AttachmentView: UIContextMenuInteractionDelegate { } else { return self.delegate?.attachmentViewGallery(startingAt: self.index) } - }, actionProvider: nil) + } actionProvider: { [unowned self] _ in + let itemSource: UIActivityItemSource + if self.attachment.kind == .image, + let source { + switch source { + case .image(let url, let data, let image): + let imageData: Data + if let data { + imageData = data + } else if let data = image.pngData() { + imageData = data + } else { + return nil + } + itemSource = ImageActivityItemSource(data: imageData, url: url, image: image) + case .gifData(let url, let data, let image): + itemSource = ImageActivityItemSource(data: data, url: url, image: image) + } + } else if self.attachment.kind == .gifv { + itemSource = GifvActivityItemSource(asset: AVAsset(url: self.attachment.url), attachment: self.attachment) + } else { + return nil + } + return UIMenu(children: [ + UIAction(title: "Share…", image: UIImage(systemName: "square.and.arrow.up")) { [unowned self] _ in + let vc = UIActivityViewController(activityItems: [itemSource], applicationActivities: [SaveToPhotosActivity()]) + self.delegate?.attachmentViewPresent(vc, animated: true) + } + ]) + } } + func contextMenuInteraction(_ interaction: UIContextMenuInteraction, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { animator.addCompletion { animator.preferredCommitStyle = .pop