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>
76 lines
2.6 KiB
Swift
76 lines
2.6 KiB
Swift
//
|
|
// SeekView.swift
|
|
// KSPlayer-iOS
|
|
//
|
|
// Created by kintan on 2018/11/14.
|
|
//
|
|
#if canImport(UIKit)
|
|
import UIKit
|
|
#else
|
|
import AppKit
|
|
#endif
|
|
public protocol SeekViewProtocol {
|
|
func set(text: String, isAdd: Bool)
|
|
}
|
|
|
|
class SeekView: UIView {
|
|
private let seekToViewImage = UIImageView()
|
|
private let seekToLabel = UILabel()
|
|
override public init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
addSubview(seekToViewImage)
|
|
addSubview(seekToLabel)
|
|
seekToLabel.font = .systemFont(ofSize: 13)
|
|
seekToLabel.textColor = UIColor(red: 0.9098, green: 0.9098, blue: 0.9098, alpha: 1.0)
|
|
backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.7)
|
|
cornerRadius = 4
|
|
clipsToBounds = true
|
|
isHidden = true
|
|
if #available(macOS 11.0, *) {
|
|
seekToViewImage.image = UIImage(systemName: "forward.fill")
|
|
}
|
|
translatesAutoresizingMaskIntoConstraints = false
|
|
seekToViewImage.translatesAutoresizingMaskIntoConstraints = false
|
|
seekToLabel.translatesAutoresizingMaskIntoConstraints = false
|
|
NSLayoutConstraint.activate([
|
|
seekToViewImage.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15),
|
|
seekToViewImage.centerYAnchor.constraint(equalTo: centerYAnchor),
|
|
seekToViewImage.widthAnchor.constraint(equalToConstant: 25),
|
|
seekToViewImage.heightAnchor.constraint(equalToConstant: 15),
|
|
seekToLabel.leadingAnchor.constraint(equalTo: seekToViewImage.trailingAnchor, constant: 10),
|
|
seekToLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
|
|
])
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder _: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
#if canImport(AppKit)
|
|
var backgroundColor: UIColor? {
|
|
get {
|
|
if let layer, let cgColor = layer.backgroundColor {
|
|
return UIColor(cgColor: cgColor)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
set {
|
|
backingLayer?.backgroundColor = newValue?.cgColor
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
extension SeekView: SeekViewProtocol {
|
|
public func set(text: String, isAdd: Bool) {
|
|
seekToLabel.text = text
|
|
if !isAdd {
|
|
seekToViewImage.backingLayer?.position = CGPoint(x: seekToViewImage.backingLayer!.frame.midX, y: seekToViewImage.backingLayer!.frame.midY)
|
|
seekToViewImage.backingLayer?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
|
|
}
|
|
seekToViewImage.centerRotate(byDegrees: isAdd ? 0.0 : 180)
|
|
}
|
|
}
|