damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit bb59c2d71c661dc001e0e196bcac4933e52795e1
parent 90f025564ae25992c693d489ee554e4df1147cf1
Author: Paul Miller <paul@paul.lol>
Date:   Tue, 20 Dec 2022 19:44:08 -0600

context menu for copy / share image

Changelog-Added: Added ability to copy and share image (@futurepaul)

Diffstat:
Mdamus/Components/ImageCarousel.swift | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 75 insertions(+), 0 deletions(-)

diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift @@ -8,9 +8,78 @@ import SwiftUI import Kingfisher +// TODO: all this ShareSheet complexity can be replaced with ShareLink once we update to iOS 16 +struct ShareSheet: UIViewControllerRepresentable { + typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void + + let activityItems: [URL] + let callback: Callback? = nil + let applicationActivities: [UIActivity]? = nil + let excludedActivityTypes: [UIActivity.ActivityType]? = nil + + func makeUIViewController(context: Context) -> UIActivityViewController { + let controller = UIActivityViewController( + activityItems: activityItems, + applicationActivities: applicationActivities) + controller.excludedActivityTypes = excludedActivityTypes + controller.completionWithItemsHandler = callback + return controller + } + + func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) { + // nothing to do here + } +} + +struct ImageContextMenuModifier: ViewModifier { + let url: URL + let image: UIImage? + @Binding var showShareSheet: Bool + + func body(content: Content) -> some View { + return content.contextMenu { + Button { + UIPasteboard.general.url = url + } label: { + Label("Copy Image URL", systemImage: "doc.on.doc") + } + if let someImage = image { + Button { + UIPasteboard.general.image = someImage + } label: { + Label("Copy Image", systemImage: "photo.on.rectangle") + } + } + Button { + showShareSheet = true + } label: { + Label("Share", systemImage: "square.and.arrow.up") + } + } + } +} + struct ImageViewer: View { let urls: [URL] + private struct ImageHandler: ImageModifier { + @Binding var handler: UIImage? + + func modify(_ image: UIImage) -> UIImage { + handler = image + return image + } + } + + @State private var image: UIImage? + @State private var showShareSheet = false + + func onShared(completed: Bool) -> Void { + if (completed) { + showShareSheet = false + } + } + var body: some View { TabView { ForEach(urls, id: \.absoluteString) { url in @@ -22,6 +91,7 @@ struct ImageViewer: View { view.framePreloadCount = 3 } .cacheOriginalImage() + .imageModifier(ImageHandler(handler: $image)) .loadDiskFileSynchronously() .scaleFactor(UIScreen.main.scale) .fade(duration: 0.1) @@ -30,6 +100,11 @@ struct ImageViewer: View { Text(url.absoluteString) } .id(url.absoluteString) + .modifier(ImageContextMenuModifier(url: url, image: image, showShareSheet: $showShareSheet)) + .sheet(isPresented: $showShareSheet) { + ShareSheet(activityItems: [url]) + } + } } }