Initial commit: SimVision tvOS streaming app
Features: - VOD library with movie grouping and version detection - TV show library with season/episode organization - TMDB integration for trending shows and recently aired episodes - Recent releases section with TMDB release date sorting - Watch history tracking with continue watching - Playlist caching (12-hour TTL) for offline support - M3U playlist parsing with XStream API support - Authentication with credential storage Technical: - SwiftUI for tvOS - Actor-based services for thread safety - Persistent caching for playlists, TMDB data, and watch history - KSPlayer integration for video playback Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
81
KSPlayer-main/Demo/SwiftUI/Shared/URLImportView.swift
Normal file
81
KSPlayer-main/Demo/SwiftUI/Shared/URLImportView.swift
Normal file
@@ -0,0 +1,81 @@
|
||||
//
|
||||
// URLImportView.swift
|
||||
// Demo
|
||||
//
|
||||
// Created by kintan on 2020/3/22.
|
||||
// Copyright © 2020 kintan. All rights reserved.
|
||||
//
|
||||
|
||||
import KSPlayer
|
||||
import SwiftUI
|
||||
|
||||
struct URLImportView: View {
|
||||
@EnvironmentObject private var appModel: APPModel
|
||||
@State private var username = ""
|
||||
@State private var password = ""
|
||||
@State private var playURL: String = ""
|
||||
@State private var rememberURL = false
|
||||
@AppStorage("historyURLs") private var historyURLs = [URL]()
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
var body: some View {
|
||||
Form {
|
||||
Section {
|
||||
TextField("URL:", text: $playURL)
|
||||
Toggle("Remember URL", isOn: $rememberURL)
|
||||
if !historyURLs.isEmpty {
|
||||
Picker("History URL", selection: $playURL) {
|
||||
Text("None").tag("")
|
||||
ForEach(historyURLs) {
|
||||
Text($0.description).tag($0.description)
|
||||
}
|
||||
}
|
||||
#if os(tvOS)
|
||||
.pickerStyle(.inline)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Section("HTTP Authentication") {
|
||||
TextField("Username:", text: $username)
|
||||
SecureField("Password:", text: $password)
|
||||
}
|
||||
Section {
|
||||
Button("Done") {
|
||||
dismiss()
|
||||
let urlString = playURL.trimmingCharacters(in: NSMutableCharacterSet.whitespacesAndNewlines)
|
||||
if !urlString.isEmpty, var components = URLComponents(string: urlString) {
|
||||
if !username.isEmpty {
|
||||
components.user = username
|
||||
}
|
||||
if !password.isEmpty {
|
||||
components.password = password
|
||||
}
|
||||
if let url = components.url {
|
||||
if rememberURL {
|
||||
if let index = historyURLs.firstIndex(of: url) {
|
||||
historyURLs.swapAt(index, historyURLs.startIndex)
|
||||
} else {
|
||||
historyURLs.insert(url, at: 0)
|
||||
}
|
||||
if historyURLs.count > 20 {
|
||||
historyURLs.removeLast()
|
||||
}
|
||||
}
|
||||
appModel.open(url: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if !os(tvOS)
|
||||
.keyboardShortcut(.defaultAction)
|
||||
#endif
|
||||
#if os(macOS) || targetEnvironment(macCatalyst)
|
||||
Button("Cancel") {
|
||||
dismiss()
|
||||
}
|
||||
.keyboardShortcut(.cancelAction)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user