mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 05:23:41 +00:00
Share button
This commit is contained in:
parent
b50d915d8e
commit
544dc70c5d
@ -74,6 +74,15 @@ struct Instance: Defaults.Serializable, Hashable, Identifiable {
|
||||
Account(instanceID: id, name: "Anonymous", url: url, anonymous: true)
|
||||
}
|
||||
|
||||
var urlComponents: URLComponents {
|
||||
URLComponents(string: url)!
|
||||
}
|
||||
|
||||
var frontendHost: String {
|
||||
// TODO: piped frontend link
|
||||
urlComponents.host!.replacingOccurrences(of: "api", with: "")
|
||||
}
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(url)
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import Foundation
|
||||
import Siesta
|
||||
|
||||
protocol VideosAPI {
|
||||
var account: Account! { get }
|
||||
var signedIn: Bool { get }
|
||||
|
||||
func channel(_ id: String) -> Resource
|
||||
@ -25,6 +26,7 @@ protocol VideosAPI {
|
||||
func channelPlaylist(_ id: String) -> Resource?
|
||||
|
||||
func loadDetails(_ item: PlayerQueueItem, completionHandler: @escaping (PlayerQueueItem) -> Void)
|
||||
func shareURL(_ item: ContentItem) -> URL
|
||||
}
|
||||
|
||||
extension VideosAPI {
|
||||
@ -45,4 +47,21 @@ extension VideosAPI {
|
||||
completionHandler(newItem)
|
||||
}
|
||||
}
|
||||
|
||||
func shareURL(_ item: ContentItem) -> URL {
|
||||
var urlComponents = account.instance.urlComponents
|
||||
urlComponents.host = account.instance.frontendHost
|
||||
switch item.contentType {
|
||||
case .video:
|
||||
urlComponents.path = "/watch"
|
||||
urlComponents.query = "v=\(item.video.videoID)"
|
||||
case .channel:
|
||||
urlComponents.path = "/channel/\(item.channel.id)"
|
||||
case .playlist:
|
||||
urlComponents.path = "/playlist"
|
||||
urlComponents.query = "list=\(item.playlist.id)"
|
||||
}
|
||||
|
||||
return urlComponents.url!
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
@discardableResult func remove(_ item: PlayerQueueItem) -> PlayerQueueItem? {
|
||||
if let index = queue.firstIndex(where: { $0 == item }) {
|
||||
if let index = queue.firstIndex(where: { $0.videoID == item.videoID }) {
|
||||
return queue.remove(at: index)
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ extension PlayerModel {
|
||||
}
|
||||
|
||||
func addItemToHistory(_ item: PlayerQueueItem) {
|
||||
if let index = history.firstIndex(where: { $0.video.videoID == item.video?.videoID }) {
|
||||
if let index = history.firstIndex(where: { $0.video?.videoID == item.video?.videoID }) {
|
||||
history.remove(at: index)
|
||||
}
|
||||
|
||||
|
@ -191,6 +191,9 @@
|
||||
377FC7E5267A084E00A6BBAF /* SearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AAF27F26737550007FC770 /* SearchView.swift */; };
|
||||
377FC7ED267A0A0800A6BBAF /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = 377FC7EC267A0A0800A6BBAF /* SwiftyJSON */; };
|
||||
377FC7F3267A0A0800A6BBAF /* Logging in Frameworks */ = {isa = PBXBuildFile; productRef = 377FC7F2267A0A0800A6BBAF /* Logging */; };
|
||||
3784B23B272894DA00B09468 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3784B23A272894DA00B09468 /* ShareSheet.swift */; };
|
||||
3784B23D2728B85300B09468 /* ShareButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3784B23C2728B85300B09468 /* ShareButton.swift */; };
|
||||
3784B23E2728B85300B09468 /* ShareButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3784B23C2728B85300B09468 /* ShareButton.swift */; };
|
||||
3788AC2726F6840700F6BAA9 /* WatchNowSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* WatchNowSection.swift */; };
|
||||
3788AC2826F6840700F6BAA9 /* WatchNowSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* WatchNowSection.swift */; };
|
||||
3788AC2926F6840700F6BAA9 /* WatchNowSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* WatchNowSection.swift */; };
|
||||
@ -540,6 +543,8 @@
|
||||
37732FEF2703A26300F04329 /* AccountValidationStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountValidationStatus.swift; sourceTree = "<group>"; };
|
||||
37732FF32703D32400F04329 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = "<group>"; };
|
||||
377A20A82693C9A2002842B8 /* TypedContentAccessors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypedContentAccessors.swift; sourceTree = "<group>"; };
|
||||
3784B23A272894DA00B09468 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = "<group>"; };
|
||||
3784B23C2728B85300B09468 /* ShareButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareButton.swift; sourceTree = "<group>"; };
|
||||
3788AC2626F6840700F6BAA9 /* WatchNowSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchNowSection.swift; sourceTree = "<group>"; };
|
||||
3788AC2A26F6842D00F6BAA9 /* WatchNowSectionBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchNowSectionBody.swift; sourceTree = "<group>"; };
|
||||
378E50FA26FE8B9F00F49626 /* Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Instance.swift; sourceTree = "<group>"; };
|
||||
@ -805,6 +810,7 @@
|
||||
37BA793A26DB8EE4002A0235 /* PlaylistVideosView.swift */,
|
||||
37AAF27D26737323007FC770 /* PopularView.swift */,
|
||||
37AAF27F26737550007FC770 /* SearchView.swift */,
|
||||
3784B23C2728B85300B09468 /* ShareButton.swift */,
|
||||
376B2E0626F920D600B1D64D /* SignInRequiredView.swift */,
|
||||
37AAF29F26741C97007FC770 /* SubscriptionsView.swift */,
|
||||
37B17D9F268A1F25006AEE9B /* VideoContextMenuView.swift */,
|
||||
@ -917,6 +923,7 @@
|
||||
37992DC826CC50CD003D4C27 /* iOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3784B23A272894DA00B09468 /* ShareSheet.swift */,
|
||||
37992DC726CC50BC003D4C27 /* Info.plist */,
|
||||
);
|
||||
path = iOS;
|
||||
@ -1173,10 +1180,10 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 37D4B0EC2671614900C925CA /* Build configuration list for PBXNativeTarget "Pearvidious (iOS)" */;
|
||||
buildPhases = (
|
||||
37CC3F48270CE89B00608308 /* ShellScript */,
|
||||
37D4B0C52671614900C925CA /* Sources */,
|
||||
37D4B0C62671614900C925CA /* Frameworks */,
|
||||
37D4B0C72671614900C925CA /* Resources */,
|
||||
37CC3F48270CE89B00608308 /* ShellScript */,
|
||||
37A3B1932725735F000FB5EE /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
@ -1205,10 +1212,10 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 37D4B0EF2671614900C925CA /* Build configuration list for PBXNativeTarget "Pearvidious (macOS)" */;
|
||||
buildPhases = (
|
||||
37CC3F4A270CE8D000608308 /* ShellScript */,
|
||||
37D4B0CB2671614900C925CA /* Sources */,
|
||||
37D4B0CC2671614900C925CA /* Frameworks */,
|
||||
37D4B0CD2671614900C925CA /* Resources */,
|
||||
37CC3F4A270CE8D000608308 /* ShellScript */,
|
||||
37A3B17127255E7F000FB5EE /* Embed App Extensions */,
|
||||
);
|
||||
buildRules = (
|
||||
@ -1272,10 +1279,10 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 37D4B177267164B000C925CA /* Build configuration list for PBXNativeTarget "Pearvidious (tvOS)" */;
|
||||
buildPhases = (
|
||||
37CC3F49270CE8CA00608308 /* ShellScript */,
|
||||
37D4B154267164AE00C925CA /* Sources */,
|
||||
37D4B155267164AE00C925CA /* Frameworks */,
|
||||
37D4B156267164AE00C925CA /* Resources */,
|
||||
37CC3F49270CE8CA00608308 /* ShellScript */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@ -1498,7 +1505,7 @@
|
||||
};
|
||||
37CC3F48270CE89B00608308 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
buildActionMask = 12;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
@ -1511,7 +1518,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
};
|
||||
37CC3F49270CE8CA00608308 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@ -1528,7 +1535,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
};
|
||||
37CC3F4A270CE8D000608308 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@ -1545,7 +1552,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
shellScript = "if test -d \"/opt/homebrew/bin/\"; then\n PATH=\"/opt/homebrew/bin/:${PATH}\"\nfi\n\nexport PATH\n\nif which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
|
||||
};
|
||||
37FD43EA2704A2350073EE42 /* ShellScript */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@ -1608,6 +1615,7 @@
|
||||
37CC3F45270CE30600608308 /* PlayerQueueItem.swift in Sources */,
|
||||
37BD07C82698B71C003EBB87 /* AppTabNavigation.swift in Sources */,
|
||||
37CB12792724C76D00213B45 /* VideoURLParser.swift in Sources */,
|
||||
3784B23D2728B85300B09468 /* ShareButton.swift in Sources */,
|
||||
37EAD86B267B9C5600D9E01B /* SponsorBlockAPI.swift in Sources */,
|
||||
3743CA52270F284F00E4D32B /* View+Borders.swift in Sources */,
|
||||
3763495126DFF59D00B9A393 /* AppSidebarRecents.swift in Sources */,
|
||||
@ -1677,6 +1685,7 @@
|
||||
3743CA4E270EFE3400E4D32B /* PlayerQueueRow.swift in Sources */,
|
||||
37BD672426F13D65004BE0C1 /* AppSidebarPlaylists.swift in Sources */,
|
||||
37B17DA2268A1F8A006AEE9B /* VideoContextMenuView.swift in Sources */,
|
||||
3784B23B272894DA00B09468 /* ShareSheet.swift in Sources */,
|
||||
379775932689365600DD52A8 /* Array+Next.swift in Sources */,
|
||||
37B81AFC26D2C9C900675966 /* VideoDetailsPaddingModifier.swift in Sources */,
|
||||
37C7A1D5267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */,
|
||||
@ -1799,6 +1808,7 @@
|
||||
37732FF52703D32400F04329 /* Sidebar.swift in Sources */,
|
||||
379775942689365600DD52A8 /* Array+Next.swift in Sources */,
|
||||
3748186726A7627F0084E870 /* Video+Fixtures.swift in Sources */,
|
||||
3784B23E2728B85300B09468 /* ShareButton.swift in Sources */,
|
||||
37BE0BDA26A214630092E2DB /* PlayerViewController.swift in Sources */,
|
||||
37E64DD226D597EB00C71877 /* SubscriptionsModel.swift in Sources */,
|
||||
37C7A1D6267BFD9D0010EAD6 /* SponsorBlockSegment.swift in Sources */,
|
||||
|
@ -15,6 +15,7 @@ struct PearvidiousApp: App {
|
||||
.handlesExternalEvents(matching: Set(["*"]))
|
||||
.commands {
|
||||
SidebarCommands()
|
||||
CommandGroup(replacing: .newItem, addition: {})
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -12,6 +12,7 @@ struct VideoDetails: View {
|
||||
@State private var subscribed = false
|
||||
@State private var confirmationShown = false
|
||||
@State private var presentingAddToPlaylist = false
|
||||
@State private var presentingShareSheet = false
|
||||
|
||||
@State private var currentPage = Page.details
|
||||
|
||||
@ -249,6 +250,11 @@ struct VideoDetails: View {
|
||||
Group {
|
||||
if let video = player.currentVideo {
|
||||
HStack {
|
||||
ShareButton(
|
||||
contentItem: ContentItem(video: video),
|
||||
presentingShareSheet: $presentingShareSheet
|
||||
)
|
||||
|
||||
Spacer()
|
||||
|
||||
if let views = video.viewsCount {
|
||||
@ -269,14 +275,17 @@ struct VideoDetails: View {
|
||||
|
||||
Spacer()
|
||||
|
||||
Button {
|
||||
presentingAddToPlaylist = true
|
||||
} label: {
|
||||
Label("Add to Playlist", systemImage: "text.badge.plus")
|
||||
.labelStyle(.iconOnly)
|
||||
.help("Add to Playlist...")
|
||||
if accounts.app.supportsUserPlaylists {
|
||||
Button {
|
||||
presentingAddToPlaylist = true
|
||||
} label: {
|
||||
Label("Add to Playlist", systemImage: "text.badge.plus")
|
||||
.labelStyle(.iconOnly)
|
||||
.help("Add to Playlist...")
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.foregroundColor(.blue)
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
.frame(maxHeight: 35)
|
||||
.foregroundColor(.secondary)
|
||||
@ -287,6 +296,17 @@ struct VideoDetails: View {
|
||||
AddToPlaylistView(video: video)
|
||||
}
|
||||
}
|
||||
#if os(iOS)
|
||||
.sheet(isPresented: $presentingShareSheet) {
|
||||
ShareSheet(activityItems: [
|
||||
accounts.api.shareURL(contentItem)
|
||||
])
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private var contentItem: ContentItem {
|
||||
ContentItem(video: player.currentVideo!)
|
||||
}
|
||||
|
||||
var detailsPage: some View {
|
||||
|
@ -4,6 +4,8 @@ import SwiftUI
|
||||
struct ChannelPlaylistView: View {
|
||||
var playlist: ChannelPlaylist
|
||||
|
||||
@State private var presentingShareSheet = false
|
||||
|
||||
@StateObject private var store = Store<ChannelPlaylist>()
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@ -44,12 +46,26 @@ struct ChannelPlaylistView: View {
|
||||
#endif
|
||||
VerticalCells(items: items)
|
||||
}
|
||||
#if os(iOS)
|
||||
.sheet(isPresented: $presentingShareSheet) {
|
||||
ShareSheet(activityItems: [
|
||||
accounts.api.shareURL(contentItem)
|
||||
])
|
||||
}
|
||||
#endif
|
||||
.onAppear {
|
||||
resource?.addObserver(store)
|
||||
resource?.loadIfNeeded()
|
||||
}
|
||||
#if !os(tvOS)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: shareButtonPlacement) {
|
||||
ShareButton(
|
||||
contentItem: contentItem,
|
||||
presentingShareSheet: $presentingShareSheet
|
||||
)
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
if inNavigationView {
|
||||
Button("Done") {
|
||||
@ -64,6 +80,18 @@ struct ChannelPlaylistView: View {
|
||||
.background(.thickMaterial)
|
||||
#endif
|
||||
}
|
||||
|
||||
private var shareButtonPlacement: ToolbarItemPlacement {
|
||||
#if os(iOS)
|
||||
.navigation
|
||||
#else
|
||||
.automatic
|
||||
#endif
|
||||
}
|
||||
|
||||
private var contentItem: ContentItem {
|
||||
ContentItem(playlist: playlist)
|
||||
}
|
||||
}
|
||||
|
||||
struct ChannelPlaylistView_Previews: PreviewProvider {
|
||||
|
@ -4,6 +4,8 @@ import SwiftUI
|
||||
struct ChannelVideosView: View {
|
||||
let channel: Channel
|
||||
|
||||
@State private var presentingShareSheet = false
|
||||
|
||||
@StateObject private var store = Store<Channel>()
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@ -70,6 +72,13 @@ struct ChannelVideosView: View {
|
||||
#endif
|
||||
#if !os(tvOS)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: shareButtonPlacement) {
|
||||
ShareButton(
|
||||
contentItem: contentItem,
|
||||
presentingShareSheet: $presentingShareSheet
|
||||
)
|
||||
}
|
||||
|
||||
ToolbarItem {
|
||||
HStack {
|
||||
Text("**\(store.item?.subscriptionsString ?? "loading")** subscribers")
|
||||
@ -91,6 +100,13 @@ struct ChannelVideosView: View {
|
||||
#else
|
||||
.background(.thickMaterial)
|
||||
#endif
|
||||
#if os(iOS)
|
||||
.sheet(isPresented: $presentingShareSheet) {
|
||||
ShareSheet(activityItems: [
|
||||
accounts.api.shareURL(contentItem)
|
||||
])
|
||||
}
|
||||
#endif
|
||||
.modifier(UnsubscribeAlertModifier())
|
||||
.onAppear {
|
||||
if store.item.isNil {
|
||||
@ -101,14 +117,14 @@ struct ChannelVideosView: View {
|
||||
.navigationTitle(navigationTitle)
|
||||
}
|
||||
|
||||
var resource: Resource {
|
||||
private var resource: Resource {
|
||||
let resource = accounts.api.channel(channel.id)
|
||||
resource.addObserver(store)
|
||||
|
||||
return resource
|
||||
}
|
||||
|
||||
var subscriptionToggleButton: some View {
|
||||
private var subscriptionToggleButton: some View {
|
||||
Group {
|
||||
if accounts.app.supportsSubscriptions && accounts.signedIn {
|
||||
if subscriptions.isSubscribing(channel.id) {
|
||||
@ -126,7 +142,19 @@ struct ChannelVideosView: View {
|
||||
}
|
||||
}
|
||||
|
||||
var navigationTitle: String {
|
||||
private var shareButtonPlacement: ToolbarItemPlacement {
|
||||
#if os(iOS)
|
||||
.navigation
|
||||
#else
|
||||
.automatic
|
||||
#endif
|
||||
}
|
||||
|
||||
private var contentItem: ContentItem {
|
||||
ContentItem(channel: channel)
|
||||
}
|
||||
|
||||
private var navigationTitle: String {
|
||||
store.item?.name ?? channel.name
|
||||
}
|
||||
}
|
||||
|
39
Shared/Views/ShareButton.swift
Normal file
39
Shared/Views/ShareButton.swift
Normal file
@ -0,0 +1,39 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ShareButton: View {
|
||||
let contentItem: ContentItem
|
||||
@Binding var presentingShareSheet: Bool
|
||||
|
||||
@EnvironmentObject<AccountsModel> private var accounts
|
||||
|
||||
var body: some View {
|
||||
Button {
|
||||
#if os(iOS)
|
||||
presentingShareSheet = true
|
||||
#else
|
||||
NSPasteboard.general.clearContents()
|
||||
NSPasteboard.general.setString(shareURL, forType: .string)
|
||||
#endif
|
||||
} label: {
|
||||
#if os(iOS)
|
||||
Label("Share", systemImage: "square.and.arrow.up")
|
||||
#else
|
||||
EmptyView()
|
||||
#endif
|
||||
}
|
||||
.keyboardShortcut("c")
|
||||
.foregroundColor(.blue)
|
||||
.buttonStyle(.plain)
|
||||
.labelStyle(.iconOnly)
|
||||
}
|
||||
|
||||
private var shareURL: String {
|
||||
accounts.api.shareURL(contentItem).absoluteString
|
||||
}
|
||||
}
|
||||
|
||||
struct ShareButton_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
ShareButton(contentItem: ContentItem(video: Video.fixture), presentingShareSheet: .constant(false))
|
||||
}
|
||||
}
|
28
iOS/ShareSheet.swift
Normal file
28
iOS/ShareSheet.swift
Normal file
@ -0,0 +1,28 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct ShareSheet: UIViewControllerRepresentable {
|
||||
typealias Callback = (_ activityType: UIActivity.ActivityType?,
|
||||
_ completed: Bool,
|
||||
_ returnedItems: [Any]?,
|
||||
_ error: Error?) -> Void
|
||||
|
||||
let activityItems: [Any]
|
||||
let applicationActivities = [UIActivity]()
|
||||
let excludedActivityTypes = [UIActivity.ActivityType]()
|
||||
let callback: Callback? = nil
|
||||
|
||||
func makeUIViewController(context _: Context) -> UIActivityViewController {
|
||||
let controller = UIActivityViewController(
|
||||
activityItems: activityItems,
|
||||
applicationActivities: applicationActivities
|
||||
)
|
||||
|
||||
controller.excludedActivityTypes = excludedActivityTypes
|
||||
controller.completionWithItemsHandler = callback
|
||||
|
||||
return controller
|
||||
}
|
||||
|
||||
func updateUIViewController(_: UIActivityViewController, context _: Context) {}
|
||||
}
|
@ -6,6 +6,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
true
|
||||
}
|
||||
|
||||
func applicationWillFinishLaunching(_: Notification) {
|
||||
NSWindow.allowsAutomaticWindowTabbing = false
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_: Notification) {
|
||||
ScreenSaverManager.shared.enable()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user