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:
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])
+ }
+
}
}
}