diff --git a/Model/OpenVideosModel.swift b/Model/OpenVideosModel.swift index 04d6eebf..cca129ca 100644 --- a/Model/OpenVideosModel.swift +++ b/Model/OpenVideosModel.swift @@ -1,5 +1,11 @@ +#if canImport(AppKit) + import AppKit +#endif import Foundation import Logging +#if canImport(UIKit) + import UIKit +#endif struct OpenVideosModel { enum PlaybackMode: String, CaseIterable { @@ -42,6 +48,24 @@ struct OpenVideosModel { } } + var urlsFromClipboard: [URL] { + #if os(iOS) + if let pasteboard = UIPasteboard.general.string { + return urlsFrom(pasteboard) + } + #elseif os(macOS) + if let pasteboard = NSPasteboard.general.string(forType: .string) { + return urlsFrom(pasteboard) + } + #endif + + return [] + } + + func openURLsFromClipboard(removeQueueItems: Bool = false, playbackMode: OpenVideosModel.PlaybackMode) { + openURLs(urlsFromClipboard, removeQueueItems: removeQueueItems, playbackMode: playbackMode) + } + func openURLs(_ urls: [URL], removeQueueItems: Bool, playbackMode: OpenVideosModel.PlaybackMode) { logger.info("opening \(urls.count) urls") urls.forEach { logger.info("\($0.absoluteString)") } @@ -102,6 +126,10 @@ struct OpenVideosModel { } } + func urlsFrom(_ string: String) -> [URL] { + string.split(whereSeparator: \.isNewline).compactMap { URL(string: String($0)) } + } + var canOpenVideosByID: Bool { guard let app = player.accounts.current?.app else { return false } return !player.accounts.isEmpty && app.supportsOpeningVideosByID diff --git a/Shared/OpenURLHandler.swift b/Shared/OpenURLHandler.swift index 45c84f59..5423da17 100644 --- a/Shared/OpenURLHandler.swift +++ b/Shared/OpenURLHandler.swift @@ -82,6 +82,7 @@ struct OpenURLHandler { player.hide() navigation.presentingChannel = false navigation.presentingPlaylist = false + navigation.presentingOpenVideos = false } private func urlByReplacingYatteeProtocol(_ url: URL, with urlProtocol: String = "https") -> URL! { diff --git a/Shared/Views/OpenVideosView.swift b/Shared/Views/OpenVideosView.swift index 103c55d9..3d435933 100644 --- a/Shared/Views/OpenVideosView.swift +++ b/Shared/Views/OpenVideosView.swift @@ -74,44 +74,16 @@ struct OpenVideosView: View { HStack { Group { - Button { - openURLs(urlsToOpenFromText) - } label: { - HStack { - Image(systemName: "network") - Text("Open URLs") - .fontWeight(.bold) - .padding(.vertical, 10) - } - .padding(.horizontal, 20) - } - .disabled(urlsToOpenFromText.isEmpty) - #if !os(tvOS) - .keyboardShortcut(.defaultAction) - #endif + openURLsButton Spacer() - Button { - presentingFileImporter = true - } label: { - HStack { - Image(systemName: "folder") - Text("Open Files") - .fontWeight(.bold) - .padding(.vertical, 10) - } - .padding(.horizontal, 20) - } + openFromClipboardButton } - .foregroundColor(.accentColor) - - .background( - RoundedRectangle(cornerRadius: 4) - .foregroundColor(Color.accentColor.opacity(0.33)) - ) } - .buttonStyle(.plain) + .padding(.bottom, 10) + + openFilesButton Spacer() } @@ -146,8 +118,76 @@ struct OpenVideosView: View { #endif } + var openURLsButton: some View { + Button { + openURLs(urlsToOpenFromText) + } label: { + HStack { + Image(systemName: "network") + Text("Open URLs") + .fontWeight(.bold) + .padding(.vertical, 10) + } + .padding(.horizontal, 20) + } + .foregroundColor(.accentColor) + .buttonStyle(.plain) + .background(buttonBackground) + .disabled(urlsToOpenFromText.isEmpty) + #if !os(tvOS) + .keyboardShortcut(.defaultAction) + #endif + } + + var openFromClipboardButton: some View { + Button { + OpenVideosModel.shared.openURLsFromClipboard( + removeQueueItems: removeQueueItems, + playbackMode: playbackMode + ) + } label: { + HStack { + Image(systemName: "doc.on.clipboard.fill") + Text("Clipboard") + .fontWeight(.bold) + .padding(.vertical, 10) + } + .padding(.horizontal, 20) + } + .foregroundColor(.accentColor) + .buttonStyle(.plain) + .background(buttonBackground) + #if !os(tvOS) + .keyboardShortcut(.defaultAction) + #endif + } + + var openFilesButton: some View { + Button { + presentingFileImporter = true + } label: { + HStack { + Image(systemName: "folder") + Text("Open Files") + + .fontWeight(.bold) + .padding(.vertical, 10) + } + .frame(maxWidth: .infinity) + .padding(.horizontal, 20) + } + .foregroundColor(.accentColor) + .buttonStyle(.plain) + .background(buttonBackground) + } + + var buttonBackground: some View { + RoundedRectangle(cornerRadius: 4) + .foregroundColor(Color.accentColor.opacity(0.33)) + } + var urlsToOpenFromText: [URL] { - urlsToOpenText.split(whereSeparator: \.isNewline).compactMap { URL(string: String($0)) } + OpenVideosModel.shared.urlsFrom(urlsToOpenText) } func openURLs(_ urls: [URL]) {