mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
tvOS layout improvements
This commit is contained in:
parent
9a958113c4
commit
60a52bc12e
@ -40,7 +40,12 @@ final class PlayerModel: ObservableObject {
|
|||||||
|
|
||||||
var mpvPlayerView = MPVPlayerView()
|
var mpvPlayerView = MPVPlayerView()
|
||||||
|
|
||||||
@Published var presentingPlayer = true { didSet { handlePresentationChange() } }
|
#if os(iOS)
|
||||||
|
static let presentingPlayerDefault = true
|
||||||
|
#else
|
||||||
|
static let presentingPlayerDefault = false
|
||||||
|
#endif
|
||||||
|
@Published var presentingPlayer = presentingPlayerDefault { didSet { handlePresentationChange() } }
|
||||||
@Published var activeBackend = PlayerBackendType.mpv
|
@Published var activeBackend = PlayerBackendType.mpv
|
||||||
|
|
||||||
var avPlayerBackend: AVPlayerBackend!
|
var avPlayerBackend: AVPlayerBackend!
|
||||||
@ -63,7 +68,9 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Published var playerSize: CGSize = .zero { didSet {
|
@Published var playerSize: CGSize = .zero { didSet {
|
||||||
backend.setSize(playerSize.width, playerSize.height)
|
#if !os(tvOS)
|
||||||
|
backend.setSize(playerSize.width, playerSize.height)
|
||||||
|
#endif
|
||||||
}}
|
}}
|
||||||
@Published var aspectRatio = VideoPlayerView.defaultAspectRatio
|
@Published var aspectRatio = VideoPlayerView.defaultAspectRatio
|
||||||
@Published var stream: Stream?
|
@Published var stream: Stream?
|
||||||
@ -880,13 +887,14 @@ final class PlayerModel: ObservableObject {
|
|||||||
mpvBackend.setVideoToAuto()
|
mpvBackend.setVideoToAuto()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func updateAspectRatio() {
|
func updateAspectRatio() {
|
||||||
guard aspectRatio != backend.aspectRatio else { return }
|
#if !os(tvOS)
|
||||||
|
guard aspectRatio != backend.aspectRatio else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.aspectRatio = self.backend.aspectRatio
|
self.aspectRatio = self.backend.aspectRatio
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,6 @@ struct TVControls: UIViewRepresentable {
|
|||||||
@State private var controlsArea = UIView()
|
@State private var controlsArea = UIView()
|
||||||
|
|
||||||
func makeUIView(context: Context) -> UIView {
|
func makeUIView(context: Context) -> UIView {
|
||||||
let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap(sender:)))
|
|
||||||
|
|
||||||
let leftSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:)))
|
let leftSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:)))
|
||||||
leftSwipe.direction = .left
|
leftSwipe.direction = .left
|
||||||
|
|
||||||
@ -24,7 +22,6 @@ struct TVControls: UIViewRepresentable {
|
|||||||
let downSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:)))
|
let downSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:)))
|
||||||
downSwipe.direction = .down
|
downSwipe.direction = .down
|
||||||
|
|
||||||
controlsArea.addGestureRecognizer(tapGesture)
|
|
||||||
controlsArea.addGestureRecognizer(leftSwipe)
|
controlsArea.addGestureRecognizer(leftSwipe)
|
||||||
controlsArea.addGestureRecognizer(rightSwipe)
|
controlsArea.addGestureRecognizer(rightSwipe)
|
||||||
controlsArea.addGestureRecognizer(upSwipe)
|
controlsArea.addGestureRecognizer(upSwipe)
|
||||||
@ -62,16 +59,9 @@ struct TVControls: UIViewRepresentable {
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func handleTap(sender: UITapGestureRecognizer) {
|
|
||||||
let location = sender.location(in: view)
|
|
||||||
model.reporter.send("tap \(location)")
|
|
||||||
print("tap \(location)")
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func handleSwipe(sender: UISwipeGestureRecognizer) {
|
@objc func handleSwipe(sender: UISwipeGestureRecognizer) {
|
||||||
let location = sender.location(in: view)
|
let location = sender.location(in: view)
|
||||||
model.reporter.send("swipe \(location)")
|
model.reporter.send("swipe \(location)")
|
||||||
print("swipe \(location)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ struct PlayerBackendView: View {
|
|||||||
.onAppear { player.playerSize = proxy.size }
|
.onAppear { player.playerSize = proxy.size }
|
||||||
.onChange(of: proxy.size) { _ in player.playerSize = proxy.size }
|
.onChange(of: proxy.size) { _ in player.playerSize = proxy.size }
|
||||||
.onChange(of: player.controls.presentingOverlays) { _ in player.playerSize = proxy.size }
|
.onChange(of: player.controls.presentingOverlays) { _ in player.playerSize = proxy.size }
|
||||||
.onChange(of: player.aspectRatio) { _ in player.playerSize = proxy.size }
|
|
||||||
})
|
})
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0)
|
.padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0)
|
||||||
@ -46,6 +45,8 @@ struct PlayerBackendView: View {
|
|||||||
.padding(.top, controlsTopPadding)
|
.padding(.top, controlsTopPadding)
|
||||||
.padding(.bottom, controlsBottomPadding)
|
.padding(.bottom, controlsBottomPadding)
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
hiddenControlsButton
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@ -82,6 +83,22 @@ struct PlayerBackendView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if os(tvOS)
|
||||||
|
private var hiddenControlsButton: some View {
|
||||||
|
VStack {
|
||||||
|
Button {
|
||||||
|
player.controls.show()
|
||||||
|
} label: {
|
||||||
|
EmptyView()
|
||||||
|
}
|
||||||
|
.offset(y: -100)
|
||||||
|
.buttonStyle(.plain)
|
||||||
|
.background(Color.clear)
|
||||||
|
.foregroundColor(.clear)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PlayerBackendView_Previews: PreviewProvider {
|
struct PlayerBackendView_Previews: PreviewProvider {
|
||||||
|
@ -238,6 +238,8 @@ struct YatteeApp: App {
|
|||||||
player.updateRemoteCommandCenter()
|
player.updateRemoteCommandCenter()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
player.presentingPlayer = false
|
if player.presentingPlayer {
|
||||||
|
player.presentingPlayer = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ struct TVNavigationView: View {
|
|||||||
|
|
||||||
@Default(.visibleSections) private var visibleSections
|
@Default(.visibleSections) private var visibleSections
|
||||||
|
|
||||||
|
@State private var playerInitialized = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
TabView(selection: navigation.tabSelectionBinding) {
|
TabView(selection: navigation.tabSelectionBinding) {
|
||||||
@ -52,11 +54,11 @@ struct TVNavigationView: View {
|
|||||||
.tag(TabSelection.search)
|
.tag(TabSelection.search)
|
||||||
|
|
||||||
SettingsView()
|
SettingsView()
|
||||||
.navigationBarHidden(true)
|
|
||||||
.tabItem { Image(systemName: "gear") }
|
.tabItem { Image(systemName: "gear") }
|
||||||
.tag(TabSelection.settings)
|
.tag(TabSelection.settings)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.background(videoPlayerInitialize)
|
||||||
.fullScreenCover(isPresented: $navigation.presentingAddToPlaylist) {
|
.fullScreenCover(isPresented: $navigation.presentingAddToPlaylist) {
|
||||||
if let video = navigation.videoToAddToPlaylist {
|
if let video = navigation.videoToAddToPlaylist {
|
||||||
AddToPlaylistView(video: video)
|
AddToPlaylistView(video: video)
|
||||||
@ -76,6 +78,18 @@ struct TVNavigationView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ViewBuilder var videoPlayerInitialize: some View {
|
||||||
|
if !playerInitialized {
|
||||||
|
VideoPlayerView()
|
||||||
|
.scaleEffect(0.00001)
|
||||||
|
.onAppear {
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||||
|
playerInitialized = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TVNavigationView_Previews: PreviewProvider {
|
struct TVNavigationView_Previews: PreviewProvider {
|
||||||
|
Loading…
Reference in New Issue
Block a user