|
|
@ -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]) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|