Merge remote-tracking branch 'origin/main' into main
This commit is contained in:
commit
c0714761b2
|
@ -9,10 +9,8 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
class AudioViewController: UIViewController {
|
||||
|
||||
var height: CGFloat = 420
|
||||
|
||||
class AudioViewController: InfoTabViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
|
|
|
@ -10,14 +10,17 @@
|
|||
import TVUIKit
|
||||
import JellyfinAPI
|
||||
|
||||
class InfoTabViewController: UIViewController {
|
||||
var height : CGFloat = 420
|
||||
}
|
||||
|
||||
|
||||
class InfoTabBarViewController: UITabBarController, UIGestureRecognizerDelegate {
|
||||
|
||||
var videoPlayer: VideoPlayerViewController?
|
||||
var subtitleViewController: SubtitlesViewController?
|
||||
var audioViewController: AudioViewController?
|
||||
var mediaInfoController: MediaInfoViewController?
|
||||
var infoContainerPos: CGRect?
|
||||
var tabBarHeight: CGFloat = 0
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
@ -27,13 +30,6 @@ class InfoTabBarViewController: UITabBarController, UIGestureRecognizerDelegate
|
|||
|
||||
viewControllers = [mediaInfoController!, audioViewController!, subtitleViewController!]
|
||||
|
||||
tabBarHeight = tabBar.frame.size.height
|
||||
|
||||
tabBar.standardAppearance.backgroundColor = .clear
|
||||
tabBar.standardAppearance.backgroundImage = UIImage()
|
||||
tabBar.standardAppearance.backgroundEffect = .none
|
||||
tabBar.barTintColor = .clear
|
||||
|
||||
}
|
||||
|
||||
func setupInfoViews(mediaItem: BaseItemDto, subtitleTracks: [Subtitle], selectedSubtitleTrack: Int32, audioTracks: [AudioTrack], selectedAudioTrack: Int32, delegate: VideoPlayerSettingsDelegate) {
|
||||
|
@ -43,52 +39,18 @@ class InfoTabBarViewController: UITabBarController, UIGestureRecognizerDelegate
|
|||
audioViewController?.prepareAudioView(audioTracks: audioTracks, selectedTrack: selectedAudioTrack, delegate: delegate)
|
||||
|
||||
subtitleViewController?.prepareSubtitleView(subtitleTracks: subtitleTracks, selectedTrack: selectedSubtitleTrack, delegate: delegate)
|
||||
|
||||
if let videoPlayer = videoPlayer {
|
||||
infoContainerPos = CGRect(x: 88, y: 87, width: videoPlayer.infoViewContainer.frame.width, height: videoPlayer.infoViewContainer.frame.height)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
|
||||
guard let pos = infoContainerPos else {
|
||||
return
|
||||
}
|
||||
|
||||
switch item.title {
|
||||
case "Audio":
|
||||
if var height = audioViewController?.height {
|
||||
height += tabBarHeight
|
||||
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseOut) { [self] in
|
||||
videoPlayer?.infoViewContainer.frame = CGRect(x: pos.minX, y: pos.minY, width: pos.width, height: height)
|
||||
|
||||
}
|
||||
|
||||
|
||||
if let index = tabBar.items?.firstIndex(of: item),
|
||||
let tabViewController = viewControllers?[index] as? InfoTabViewController,
|
||||
let width = videoPlayer?.infoPanelContainerView.frame.width {
|
||||
let height = tabViewController.height + tabBar.frame.size.height
|
||||
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseOut) { [self] in
|
||||
videoPlayer?.infoPanelContainerView.frame = CGRect(x: 88, y: 87, width: width, height: height)
|
||||
}
|
||||
break
|
||||
case "Info":
|
||||
if var height = mediaInfoController?.height {
|
||||
height += tabBarHeight
|
||||
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseOut) { [self] in
|
||||
videoPlayer?.infoViewContainer.frame = CGRect(x: pos.minX, y: pos.minY, width: pos.width, height: height)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break
|
||||
case "Subtitles":
|
||||
if var height = subtitleViewController?.height {
|
||||
height += tabBarHeight
|
||||
UIView.animate(withDuration: 0.6, delay: 0, options: .curveEaseOut) { [self] in
|
||||
videoPlayer?.infoViewContainer.frame = CGRect(x: pos.minX, y: pos.minY, width: pos.width, height: height)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,9 @@
|
|||
import SwiftUI
|
||||
import JellyfinAPI
|
||||
|
||||
class MediaInfoViewController: UIViewController {
|
||||
class MediaInfoViewController: InfoTabViewController {
|
||||
private var contentView: UIHostingController<MediaInfoView>!
|
||||
|
||||
var height: CGFloat = 0
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
|
|
|
@ -9,9 +9,7 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
class SubtitlesViewController: UIViewController {
|
||||
|
||||
var height: CGFloat = 420
|
||||
class SubtitlesViewController: InfoTabViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="19115.3" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="18122" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="appleTV" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="tvOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19107.5"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -111,7 +110,7 @@
|
|||
<outlet property="controlsView" destination="OG6-kk-N7Z" id="8Ed-du-EpL"/>
|
||||
<outlet property="currentTimeLabel" destination="CL5-ko-ceu" id="gZB-h5-TGd"/>
|
||||
<outlet property="gradientView" destination="eh8-uG-9Wz" id="fBa-EG-C6z"/>
|
||||
<outlet property="infoViewContainer" destination="lie-K8-LNT" id="4io-B3-qE3"/>
|
||||
<outlet property="infoPanelContainerView" destination="lie-K8-LNT" id="4io-B3-qE3"/>
|
||||
<outlet property="remainingTimeLabel" destination="NyZ-z0-56J" id="Opj-7c-cIE"/>
|
||||
<outlet property="scrubLabel" destination="HfD-p0-JMA" id="R28-Fa-v9d"/>
|
||||
<outlet property="scrubberView" destination="yrg-ru-QSH" id="ylv-C7-RNl"/>
|
||||
|
|
|
@ -34,12 +34,9 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
@IBOutlet weak var currentTimeLabel: UILabel!
|
||||
@IBOutlet weak var remainingTimeLabel: UILabel!
|
||||
|
||||
@IBOutlet weak var infoViewContainer: UIView!
|
||||
@IBOutlet weak var infoPanelContainerView: UIView!
|
||||
|
||||
var infoPanelDisplayPoint: CGPoint = .zero
|
||||
var infoPanelHiddenPoint: CGPoint = .zero
|
||||
|
||||
var containerViewController: InfoTabBarViewController?
|
||||
var infoTabBarViewController: InfoTabBarViewController?
|
||||
var focusedOnTabBar: Bool = false
|
||||
var showingInfoPanel: Bool = false
|
||||
|
||||
|
@ -108,18 +105,16 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)
|
||||
self.gradientView.layer.addSublayer(gradientLayer)
|
||||
|
||||
infoPanelDisplayPoint = infoViewContainer.center
|
||||
infoPanelHiddenPoint = CGPoint(x: infoPanelDisplayPoint.x, y: -infoViewContainer.frame.height)
|
||||
infoViewContainer.center = infoPanelHiddenPoint
|
||||
infoViewContainer.layer.cornerRadius = 40
|
||||
infoPanelContainerView.center = CGPoint(x: infoPanelContainerView.center.x, y: -infoPanelContainerView.frame.height)
|
||||
infoPanelContainerView.layer.cornerRadius = 40
|
||||
|
||||
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
|
||||
blurEffectView.frame = infoViewContainer.bounds
|
||||
blurEffectView.frame = infoPanelContainerView.bounds
|
||||
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
blurEffectView.layer.cornerRadius = 40
|
||||
blurEffectView.clipsToBounds = true
|
||||
infoViewContainer.addSubview(blurEffectView)
|
||||
infoViewContainer.sendSubviewToBack(blurEffectView)
|
||||
infoPanelContainerView.addSubview(blurEffectView)
|
||||
infoPanelContainerView.sendSubviewToBack(blurEffectView)
|
||||
|
||||
transportBarView.layer.cornerRadius = CGFloat(5)
|
||||
|
||||
|
@ -351,11 +346,11 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
|
||||
}
|
||||
|
||||
// Grabs a refference to the info panel view controller
|
||||
// Grabs a reference to the info panel view controller
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
if segue.identifier == "infoView" {
|
||||
containerViewController = segue.destination as? InfoTabBarViewController
|
||||
containerViewController?.videoPlayer = self
|
||||
infoTabBarViewController = segue.destination as? InfoTabBarViewController
|
||||
infoTabBarViewController?.videoPlayer = self
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -398,7 +393,7 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
func toggleInfoContainer() {
|
||||
showingInfoPanel.toggle()
|
||||
|
||||
containerViewController?.view.isUserInteractionEnabled = showingInfoPanel
|
||||
infoTabBarViewController?.view.isUserInteractionEnabled = showingInfoPanel
|
||||
|
||||
if showingInfoPanel && seeking {
|
||||
scrubLabel.isHidden = true
|
||||
|
@ -413,7 +408,10 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
}
|
||||
|
||||
UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseOut) { [self] in
|
||||
infoViewContainer.center = showingInfoPanel ? infoPanelDisplayPoint : infoPanelHiddenPoint
|
||||
let size = infoPanelContainerView.frame.size
|
||||
let y : CGFloat = showingInfoPanel ? 87 : -size.height
|
||||
|
||||
infoPanelContainerView.frame = CGRect(x: 88, y: y, width: size.width, height: size.height)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -726,7 +724,7 @@ class VideoPlayerViewController: UIViewController, VideoPlayerSettingsDelegate,
|
|||
}
|
||||
|
||||
func setupInfoPanel() {
|
||||
containerViewController?.setupInfoViews(mediaItem: manifest, subtitleTracks: subtitleTrackArray, selectedSubtitleTrack: selectedCaptionTrack, audioTracks: audioTrackArray, selectedAudioTrack: selectedAudioTrack, delegate: self)
|
||||
infoTabBarViewController?.setupInfoViews(mediaItem: manifest, subtitleTracks: subtitleTrackArray, selectedSubtitleTrack: selectedCaptionTrack, audioTracks: audioTrackArray, selectedAudioTrack: selectedAudioTrack, delegate: self)
|
||||
}
|
||||
|
||||
func formatSecondsToHMS(_ seconds: Double) -> String {
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"package": "jellyfin-sdk-swift",
|
||||
"package": "JellyfinAPI",
|
||||
"repositoryURL": "https://github.com/jellyfin/jellyfin-sdk-swift",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
|
@ -47,7 +47,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"package": "keychain-swift",
|
||||
"package": "KeychainSwift",
|
||||
"repositoryURL": "https://github.com/evgenyneu/keychain-swift",
|
||||
"state": {
|
||||
"branch": null,
|
||||
|
@ -83,7 +83,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"package": "SwiftUI-Introspect",
|
||||
"package": "Introspect",
|
||||
"repositoryURL": "https://github.com/siteline/SwiftUI-Introspect",
|
||||
"state": {
|
||||
"branch": null,
|
||||
|
|
|
@ -53,8 +53,8 @@ final class SessionManager {
|
|||
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
|
||||
var deviceName = UIDevice.current.name
|
||||
deviceName = deviceName.folding(options: .diacriticInsensitive, locale: .current)
|
||||
deviceName = deviceName.removeRegexMatches(pattern: "[^\\w\\s]")
|
||||
|
||||
deviceName = String(deviceName.unicodeScalars.filter {CharacterSet.urlQueryAllowed.contains($0) })
|
||||
|
||||
var header = "MediaBrowser "
|
||||
#if os(tvOS)
|
||||
header.append("Client=\"SwiftFin tvOS\", ")
|
||||
|
|
Loading…
Reference in New Issue