mirror of
				https://github.com/yattee/yattee.git
				synced 2025-11-04 14:42:05 +00:00 
			
		
		
		
	tvOS layout improvements
This commit is contained in:
		@@ -40,7 +40,12 @@ final class PlayerModel: ObservableObject {
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    var avPlayerBackend: AVPlayerBackend!
 | 
			
		||||
@@ -63,7 +68,9 @@ final class PlayerModel: ObservableObject {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @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 stream: Stream?
 | 
			
		||||
@@ -880,13 +887,14 @@ final class PlayerModel: ObservableObject {
 | 
			
		||||
        mpvBackend.setVideoToAuto()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    func updateAspectRatio() {
 | 
			
		||||
        guard aspectRatio != backend.aspectRatio else { return }
 | 
			
		||||
        #if !os(tvOS)
 | 
			
		||||
            guard aspectRatio != backend.aspectRatio else { return }
 | 
			
		||||
 | 
			
		||||
        DispatchQueue.main.async { [weak self] in
 | 
			
		||||
            guard let self = self else { return }
 | 
			
		||||
            self.aspectRatio = self.backend.aspectRatio
 | 
			
		||||
        }
 | 
			
		||||
            DispatchQueue.main.async { [weak self] in
 | 
			
		||||
                guard let self = self else { return }
 | 
			
		||||
                self.aspectRatio = self.backend.aspectRatio
 | 
			
		||||
            }
 | 
			
		||||
        #endif
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,8 +10,6 @@ struct TVControls: UIViewRepresentable {
 | 
			
		||||
    @State private var controlsArea = 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:)))
 | 
			
		||||
        leftSwipe.direction = .left
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +22,6 @@ struct TVControls: UIViewRepresentable {
 | 
			
		||||
        let downSwipe = UISwipeGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleSwipe(sender:)))
 | 
			
		||||
        downSwipe.direction = .down
 | 
			
		||||
 | 
			
		||||
        controlsArea.addGestureRecognizer(tapGesture)
 | 
			
		||||
        controlsArea.addGestureRecognizer(leftSwipe)
 | 
			
		||||
        controlsArea.addGestureRecognizer(rightSwipe)
 | 
			
		||||
        controlsArea.addGestureRecognizer(upSwipe)
 | 
			
		||||
@@ -62,16 +59,9 @@ struct TVControls: UIViewRepresentable {
 | 
			
		||||
            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) {
 | 
			
		||||
            let location = sender.location(in: view)
 | 
			
		||||
            model.reporter.send("swipe \(location)")
 | 
			
		||||
            print("swipe \(location)")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,6 @@ struct PlayerBackendView: View {
 | 
			
		||||
                    .onAppear { 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.aspectRatio) { _ in player.playerSize = proxy.size }
 | 
			
		||||
            })
 | 
			
		||||
            #if os(iOS)
 | 
			
		||||
            .padding(.top, player.playingFullScreen && verticalSizeClass == .regular ? 20 : 0)
 | 
			
		||||
@@ -46,6 +45,8 @@ struct PlayerBackendView: View {
 | 
			
		||||
                    .padding(.top, controlsTopPadding)
 | 
			
		||||
                    .padding(.bottom, controlsBottomPadding)
 | 
			
		||||
                #endif
 | 
			
		||||
            #else
 | 
			
		||||
                hiddenControlsButton
 | 
			
		||||
            #endif
 | 
			
		||||
        }
 | 
			
		||||
        #if os(iOS)
 | 
			
		||||
@@ -82,6 +83,22 @@ struct PlayerBackendView: View {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    #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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -238,6 +238,8 @@ struct YatteeApp: App {
 | 
			
		||||
            player.updateRemoteCommandCenter()
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        player.presentingPlayer = false
 | 
			
		||||
        if player.presentingPlayer {
 | 
			
		||||
            player.presentingPlayer = false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,8 @@ struct TVNavigationView: View {
 | 
			
		||||
 | 
			
		||||
    @Default(.visibleSections) private var visibleSections
 | 
			
		||||
 | 
			
		||||
    @State private var playerInitialized = false
 | 
			
		||||
 | 
			
		||||
    var body: some View {
 | 
			
		||||
        NavigationView {
 | 
			
		||||
            TabView(selection: navigation.tabSelectionBinding) {
 | 
			
		||||
@@ -52,11 +54,11 @@ struct TVNavigationView: View {
 | 
			
		||||
                    .tag(TabSelection.search)
 | 
			
		||||
 | 
			
		||||
                SettingsView()
 | 
			
		||||
                    .navigationBarHidden(true)
 | 
			
		||||
                    .tabItem { Image(systemName: "gear") }
 | 
			
		||||
                    .tag(TabSelection.settings)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        .background(videoPlayerInitialize)
 | 
			
		||||
        .fullScreenCover(isPresented: $navigation.presentingAddToPlaylist) {
 | 
			
		||||
            if let video = navigation.videoToAddToPlaylist {
 | 
			
		||||
                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 {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user