diff --git a/Tusker/Views/Attachments/AttachmentView.swift b/Tusker/Views/Attachments/AttachmentView.swift index cc4cd0e7..56a40a88 100644 --- a/Tusker/Views/Attachments/AttachmentView.swift +++ b/Tusker/Views/Attachments/AttachmentView.swift @@ -444,6 +444,7 @@ extension AttachmentView: UIContextMenuInteractionDelegate { } } actionProvider: { [unowned self] _ in let itemSource: UIActivityItemSource + let itemData: Task if self.attachment.kind == .image, let source { switch source { @@ -457,20 +458,41 @@ extension AttachmentView: UIContextMenuInteractionDelegate { return nil } itemSource = ImageActivityItemSource(data: imageData, url: url, image: image) + itemData = Task { imageData } + case .gifData(let url, let data, let image): itemSource = ImageActivityItemSource(data: data, url: url, image: image) + itemData = Task { data } } } else if self.attachment.kind == .gifv { itemSource = GifvActivityItemSource(asset: AVAsset(url: self.attachment.url), attachment: self.attachment) + itemData = Task { + try? await URLSession.shared.data(from: self.attachment.url).0 + } } else { return nil } - return UIMenu(children: [ + var actions = [ 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) } - ]) + ] + let activity = SaveToPhotosActivity() + if activity.canPerform(withActivityItems: [self.attachment.url]) { + actions.append(UIAction(title: "Save to Photos", image: UIImage(systemName: "square.and.arrow.down"), handler: { _ in + Task { + guard let itemData = await itemData.value else { + return + } + let tempURL = FileManager.default.temporaryDirectory.appendingPathComponent(self.attachment.url.lastPathComponent) + try itemData.write(to: tempURL) + activity.prepare(withActivityItems: [tempURL]) + activity.perform() + } + })) + } + return UIMenu(children: actions) } }