mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 21:43:41 +00:00
220 lines
6.5 KiB
Swift
220 lines
6.5 KiB
Swift
import SwiftUI
|
|
|
|
struct OpenVideosView: View {
|
|
@State private var presentingFileImporter = false
|
|
@State private var urlsToOpenText = ""
|
|
@State private var playbackMode = OpenVideosModel.PlaybackMode.playNow
|
|
@State private var removeQueueItems = false
|
|
|
|
@ObservedObject private var navigation = NavigationModel.shared
|
|
|
|
@Environment(\.openURL) private var openURL
|
|
@Environment(\.presentationMode) private var presentationMode
|
|
|
|
var body: some View {
|
|
#if os(macOS)
|
|
openVideos
|
|
.frame(minWidth: 600, maxWidth: 800, minHeight: 350, maxHeight: 500)
|
|
#else
|
|
NavigationView {
|
|
ScrollView(.vertical, showsIndicators: false) {
|
|
openVideos
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .navigationBarLeading) {
|
|
closeButton
|
|
}
|
|
}
|
|
.navigationTitle("Open Videos")
|
|
#if os(iOS)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
#endif
|
|
}
|
|
#endif
|
|
}
|
|
|
|
var closeButton: some View {
|
|
Button(action: { presentationMode.wrappedValue.dismiss() }) {
|
|
Label("Done", systemImage: "xmark")
|
|
}
|
|
#if os(macOS)
|
|
.labelStyle(.titleOnly)
|
|
#endif
|
|
#if !os(tvOS)
|
|
.keyboardShortcut(.cancelAction)
|
|
#endif
|
|
}
|
|
|
|
var openVideos: some View {
|
|
VStack(alignment: .leading) {
|
|
#if os(macOS)
|
|
closeButton
|
|
#endif
|
|
|
|
ZStack(alignment: .topLeading) {
|
|
#if os(tvOS)
|
|
TextField("URL to Open", text: $urlsToOpenText)
|
|
#else
|
|
TextEditor(text: $urlsToOpenText)
|
|
.padding(2)
|
|
.border(Color(white: 0.8), width: 1)
|
|
.frame(minHeight: 100, maxHeight: 250)
|
|
#if !os(macOS)
|
|
.keyboardType(.URL)
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
Group {
|
|
#if os(tvOS)
|
|
Text("Enter link to open")
|
|
#else
|
|
Text("Enter links to open, one per line")
|
|
#endif
|
|
}
|
|
.font(.caption2)
|
|
.foregroundColor(.secondary)
|
|
|
|
playbackModeControl
|
|
|
|
Toggle(isOn: $removeQueueItems) {
|
|
Text("Clear Queue before opening")
|
|
}
|
|
.disabled(!playbackMode.allowsRemovingQueueItems)
|
|
.padding(.bottom)
|
|
|
|
HStack {
|
|
Group {
|
|
#if os(tvOS)
|
|
Spacer()
|
|
#endif
|
|
openURLsButton
|
|
Spacer()
|
|
|
|
#if !os(tvOS)
|
|
openFromClipboardButton
|
|
#endif
|
|
}
|
|
}
|
|
.padding(.bottom, 10)
|
|
|
|
#if !os(tvOS)
|
|
openFilesButton
|
|
#endif
|
|
|
|
Spacer()
|
|
}
|
|
.padding()
|
|
.alert(isPresented: $navigation.presentingAlertInOpenVideos) { navigation.alert }
|
|
#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
|
|
}
|
|
|
|
openURLs(urlsToOpen)
|
|
} catch {
|
|
navigation.alert = Alert(title: Text("Could not open Files"))
|
|
navigation.presentingAlertInOpenVideos = true
|
|
}
|
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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()
|
|
}
|
|
|
|
var openURLsButton: some View {
|
|
AccentButton(text: "Open", imageSystemName: "network") {
|
|
openURLs(urlsToOpenFromText)
|
|
}
|
|
.disabled(urlsToOpenFromText.isEmpty)
|
|
#if os(tvOS)
|
|
.frame(maxWidth: 600)
|
|
#else
|
|
.keyboardShortcut(.defaultAction)
|
|
#endif
|
|
}
|
|
|
|
var openFromClipboardButton: some View {
|
|
AccentButton(text: "Paste", imageSystemName: "doc.on.clipboard.fill") {
|
|
OpenVideosModel.shared.openURLsFromClipboard(
|
|
removeQueueItems: removeQueueItems,
|
|
playbackMode: playbackMode
|
|
)
|
|
}
|
|
}
|
|
|
|
var openFilesButton: some View {
|
|
AccentButton(text: "Open Files", imageSystemName: "folder") {
|
|
presentingFileImporter = true
|
|
}
|
|
}
|
|
|
|
var urlsToOpenFromText: [URL] {
|
|
OpenVideosModel.shared.urlsFrom(urlsToOpenText)
|
|
}
|
|
|
|
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()
|
|
.injectFixtureEnvironmentObjects()
|
|
#if os(iOS)
|
|
.navigationViewStyle(.stack)
|
|
#endif
|
|
}
|
|
}
|