yattee/Shared/Views/OpenVideosView.swift

220 lines
6.5 KiB
Swift
Raw Normal View History

2022-11-10 17:11:28 +00:00
import SwiftUI
struct OpenVideosView: View {
@State private var presentingFileImporter = false
2022-11-10 21:20:35 +00:00
@State private var urlsToOpenText = ""
2022-11-10 17:11:28 +00:00
@State private var playbackMode = OpenVideosModel.PlaybackMode.playNow
@State private var removeQueueItems = false
@ObservedObject private var navigation = NavigationModel.shared
2022-11-10 17:11:28 +00:00
@Environment(\.openURL) private var openURL
@Environment(\.presentationMode) private var presentationMode
var body: some View {
#if os(macOS)
openVideos
2022-11-11 17:50:13 +00:00
.frame(minWidth: 600, maxWidth: 800, minHeight: 350, maxHeight: 500)
2022-11-10 17:11:28 +00:00
#else
NavigationView {
2022-11-12 23:07:23 +00:00
ScrollView(.vertical, showsIndicators: false) {
openVideos
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
closeButton
2022-11-10 17:11:28 +00:00
}
2022-11-12 23:07:23 +00:00
}
.navigationTitle("Open Videos")
2022-11-11 15:19:14 +00:00
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
2022-11-10 17:11:28 +00:00
}
#endif
}
var closeButton: some View {
Button(action: { presentationMode.wrappedValue.dismiss() }) {
2022-12-11 22:15:56 +00:00
Label("Done", systemImage: "xmark")
}
#if os(macOS)
.labelStyle(.titleOnly)
#endif
#if !os(tvOS)
.keyboardShortcut(.cancelAction)
#endif
}
2022-11-10 17:11:28 +00:00
var openVideos: some View {
VStack(alignment: .leading) {
#if os(macOS)
closeButton
#endif
2022-11-10 17:11:28 +00:00
ZStack(alignment: .topLeading) {
#if os(tvOS)
2022-11-11 17:50:13 +00:00
TextField("URL to Open", text: $urlsToOpenText)
2022-11-10 17:11:28 +00:00
#else
TextEditor(text: $urlsToOpenText)
.padding(2)
.border(Color(white: 0.8), width: 1)
2022-11-11 17:50:13 +00:00
.frame(minHeight: 100, maxHeight: 250)
2022-11-10 17:11:28 +00:00
#if !os(macOS)
.keyboardType(.URL)
#endif
#endif
}
2022-11-11 17:50:13 +00:00
Group {
#if os(tvOS)
Text("Enter link to open")
#else
Text("Enter links to open, one per line")
#endif
2022-11-10 17:11:28 +00:00
}
2022-11-11 17:50:13 +00:00
.font(.caption2)
.foregroundColor(.secondary)
playbackModeControl
2022-11-10 17:11:28 +00:00
Toggle(isOn: $removeQueueItems) {
2022-11-11 17:50:13 +00:00
Text("Clear Queue before opening")
2022-11-10 17:11:28 +00:00
}
.disabled(!playbackMode.allowsRemovingQueueItems)
.padding(.bottom)
HStack {
Group {
2022-11-11 17:50:13 +00:00
#if os(tvOS)
Spacer()
#endif
2022-11-10 20:47:27 +00:00
openURLsButton
2022-11-11 17:50:13 +00:00
Spacer()
2022-11-10 17:11:28 +00:00
2022-11-10 21:28:55 +00:00
#if !os(tvOS)
openFromClipboardButton
#endif
2022-11-10 17:11:28 +00:00
}
}
2022-11-10 20:47:27 +00:00
.padding(.bottom, 10)
2022-11-10 21:28:55 +00:00
#if !os(tvOS)
openFilesButton
#endif
2022-11-10 17:11:28 +00:00
Spacer()
}
.padding()
2022-11-11 17:50:13 +00:00
.alert(isPresented: $navigation.presentingAlertInOpenVideos) { navigation.alert }
2022-11-10 17:11:28 +00:00
#if !os(tvOS)
.fileImporter(
isPresented: $presentingFileImporter,
allowedContentTypes: [.audiovisualContent],
allowsMultipleSelection: true
) { result in
do {
let selectedFiles = try result.get()
let urlsToOpen = selectedFiles.map { url in
if let bookmarkURL = URLBookmarkModel.shared.loadBookmark(url) {
return bookmarkURL
}
if url.startAccessingSecurityScopedResource() {
URLBookmarkModel.shared.saveBookmark(url)
}
return url
}
2022-11-13 22:48:55 +00:00
openURLs(urlsToOpen)
2022-11-10 17:11:28 +00:00
} catch {
navigation.alert = Alert(title: Text("Could not open Files"))
navigation.presentingAlertInOpenVideos = true
2022-11-10 17:11:28 +00:00
}
presentationMode.wrappedValue.dismiss()
}
#endif
}
2022-11-11 17:50:13 +00:00
var playbackModeControl: some View {
HStack {
#if !os(tvOS)
Text("Playback Mode")
Spacer()
#endif
#if os(iOS)
Menu {
playbackModePicker
} label: {
Text(playbackMode.description)
}
#else
playbackModePicker
#if !os(tvOS)
.frame(maxWidth: 200)
#endif
#endif
}
.transaction { t in t.animation = .none }
.padding(.bottom, 5)
.frame(maxWidth: .infinity, alignment: .center)
}
var playbackModePicker: some View {
Picker("Playback Mode", selection: $playbackMode) {
ForEach(OpenVideosModel.PlaybackMode.allCases, id: \.rawValue) { mode in
Text(mode.description).tag(mode)
}
}
.labelsHidden()
}
2022-11-10 20:47:27 +00:00
var openURLsButton: some View {
2022-11-11 17:50:13 +00:00
OpenVideosButton(text: "Open", imageSystemName: "network") {
2022-11-10 20:47:27 +00:00
openURLs(urlsToOpenFromText)
}
.disabled(urlsToOpenFromText.isEmpty)
2022-11-11 17:50:13 +00:00
#if os(tvOS)
.frame(maxWidth: 600)
#else
2022-11-10 20:47:27 +00:00
.keyboardShortcut(.defaultAction)
#endif
}
var openFromClipboardButton: some View {
2022-11-11 17:50:13 +00:00
OpenVideosButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") {
2022-11-10 20:47:27 +00:00
OpenVideosModel.shared.openURLsFromClipboard(
removeQueueItems: removeQueueItems,
playbackMode: playbackMode
)
}
}
var openFilesButton: some View {
2022-11-11 17:50:13 +00:00
OpenVideosButton(text: "Open Files", imageSystemName: "folder") {
2022-11-10 20:47:27 +00:00
presentingFileImporter = true
}
}
2022-11-10 17:11:28 +00:00
var urlsToOpenFromText: [URL] {
2022-11-10 20:47:27 +00:00
OpenVideosModel.shared.urlsFrom(urlsToOpenText)
2022-11-10 17:11:28 +00:00
}
func openURLs(_ urls: [URL]) {
OpenVideosModel.shared.openURLs(urls, removeQueueItems: removeQueueItems, playbackMode: playbackMode)
presentationMode.wrappedValue.dismiss()
}
}
struct OpenVideosView_Previews: PreviewProvider {
static var previews: some View {
OpenVideosView()
2022-11-11 17:50:13 +00:00
.injectFixtureEnvironmentObjects()
2022-11-10 17:11:28 +00:00
#if os(iOS)
.navigationViewStyle(.stack)
#endif
}
}