This commit is contained in:
世界
2023-08-03 17:57:35 +08:00
parent b3808dbcb5
commit 313721c7cf
6 changed files with 86 additions and 47 deletions
@@ -1,4 +1,5 @@
import Foundation
import Library
import SwiftUI
#if canImport(UIKit)
import UIKit
@@ -6,55 +7,101 @@ import SwiftUI
import AppKit
#endif
public struct ShareButton<Label>: View where Label: View {
private let items: () throws -> [Any]
private let label: Label
@Binding private var alert: Alert?
public struct ProfileShareButton<Label>: View where Label: View {
private let alert: Binding<Alert?>
private let profile: Profile
private let label: () -> Label
public init(_ alert: Binding<Alert?>, @ViewBuilder label: () -> Label, items: @escaping () throws -> [Any]) {
_alert = alert
self.items = items
self.label = label()
public init(_ alert: Binding<Alert?>, _ profile: Profile, label: @escaping () -> Label) {
self.alert = alert
self.profile = profile
self.label = label
}
public var body: some View {
#if os(iOS)
if #available(iOS 16.0, *) {
ShareLink(item: profile, subject: Text(profile.name), preview: SharePreview("Share profile"), label: label)
} else if UIDevice.current.userInterfaceIdiom != .pad {
bodyCompat
}
#else
bodyCompat
#endif
}
private var bodyCompat: some View {
ShareButtonCompat(alert, label: label) {
try profile.toContent().generateShareFile()
}
}
}
public struct ShareButtonCompat<Label>: View where Label: View {
private let label: () -> Label
private let itemURL: () throws -> URL
@Binding private var alert: Alert?
#if canImport(AppKit)
@State private var sharePresented = false
#endif
public var body: some View {
Button {
#if os(iOS)
do {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
try windowScene.keyWindow?.rootViewController?.present(UIActivityViewController(activityItems: items(), applicationActivities: nil), animated: true, completion: nil)
public init(_ alert: Binding<Alert?>, @ViewBuilder label: @escaping () -> Label, itemURL: @escaping () throws -> URL) {
_alert = alert
self.label = label
self.itemURL = itemURL
}
} catch {
alert = Alert(error)
public var body: some View {
Button(action: shareItem, label: label)
#if canImport(AppKit)
.background(SharingServicePicker($sharePresented, $alert, itemURL))
#endif
}
private func shareItem() {
#if canImport(UIKit)
Task.detached {
shareItem0()
}
#elseif canImport(AppKit)
sharePresented = true
#endif
} label: {
label
}
#if canImport(AppKit)
.background(SharingServicePicker($sharePresented, $alert, items))
#endif
}
private func shareItems() {}
#if canImport(UIKit)
private func shareItem0() {
do {
let shareItem = try itemURL()
DispatchQueue.main.async {
shareItem1(shareItem)
}
} catch {
DispatchQueue.main.async {
alert = Alert(error)
}
}
}
private func shareItem1(_ item: URL) {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
try windowScene.keyWindow?.rootViewController?.present(UIActivityViewController(activityItems: [item], applicationActivities: nil), animated: true, completion: nil)
}
}
#endif
}
#if canImport(AppKit)
private struct SharingServicePicker: NSViewRepresentable {
@Binding private var isPresented: Bool
@Binding private var alert: Alert?
private let items: () throws -> [Any]
private let item: () throws -> URL
init(_ isPresented: Binding<Bool>, _ alert: Binding<Alert?>, _ items: @escaping () throws -> [Any]) {
init(_ isPresented: Binding<Bool>, _ alert: Binding<Alert?>, _ item: @escaping () throws -> URL) {
_isPresented = isPresented
_alert = alert
self.items = items
self.item = item
}
func makeNSView(context _: Context) -> NSView {
@@ -65,7 +112,7 @@ public struct ShareButton<Label>: View where Label: View {
func updateNSView(_ nsView: NSView, context: Context) {
if isPresented {
do {
let picker = try NSSharingServicePicker(items: items())
let picker = try NSSharingServicePicker(items: [item()])
picker.delegate = context.coordinator
DispatchQueue.main.async {
picker.show(relativeTo: .zero, of: nsView, preferredEdge: .minY)
@@ -22,7 +22,7 @@ public struct ActiveDashboardView: View {
}
}
} else {
viewBuilder {
VStack {
#if os(iOS) || os(tvOS)
if ApplicationLibrary.inPreview || profile.status.isConnectedStrict {
Picker("Page", selection: $selection) {
@@ -33,7 +33,6 @@ public struct GroupItemView: View {
.lineLimit(1)
.truncationMode(.tail)
Spacer(minLength: 0)
}
Spacer(minLength: 8)
HStack {
@@ -41,7 +40,6 @@ public struct GroupItemView: View {
.font(.caption)
.foregroundColor(.secondary)
Spacer(minLength: 0)
}
}
Spacer(minLength: 0)
@@ -66,10 +66,8 @@ public struct EditProfileView: View {
} label: {
Text("View Content").foregroundColor(.accentColor)
}
ShareButton($alert) {
ProfileShareButton($alert, profile) {
Text("Share")
} items: {
try [profile.toContent().generateShareFile()]
}
#endif
Button("Update") {
@@ -318,10 +318,8 @@ public struct ProfileView: View {
Text(profile.name)
}
.contextMenu {
ShareButton(parent.$alert) {
ProfileShareButton(parent.$alert, profile) {
Label("Share", systemImage: "square.and.arrow.up.fill")
} items: {
try [profile.toContent().generateShareFile()]
}
if profile.type == .remote {
Button {
@@ -359,10 +357,8 @@ public struct ProfileView: View {
Image(systemName: "arrow.clockwise")
})
}
ShareButton(parent.$alert) {
ProfileShareButton(parent.$alert, profile) {
Image(systemName: "square.and.arrow.up.fill")
} items: {
try [profile.toContent().generateShareFile()]
}
Button(action: {
parent.openWindow(id: EditProfileWindowView.windowID, value: profile.mustID)
@@ -7,7 +7,7 @@
<key>ApplicationLibrary.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
<integer>5</integer>
</dict>
<key>Associations (Playground) 1.xcscheme</key>
<dict>
@@ -69,7 +69,7 @@
<key>MacLibrary.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>2</integer>
</dict>
<key>MessageExtension.xcscheme_^#shared#^_</key>
<dict>
@@ -131,7 +131,7 @@
<key>SFM.System.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
<integer>6</integer>
</dict>
<key>SFM.xcscheme</key>
<dict>
@@ -141,7 +141,7 @@
<key>SFT.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
<integer>4</integer>
</dict>
<key>ShareExtension.xcscheme_^#shared#^_</key>
<dict>
@@ -151,7 +151,7 @@
<key>SystemExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>5</integer>
<integer>3</integer>
</dict>
<key>Test.xcscheme_^#shared#^_</key>
<dict>