PiP and UI improvements

This commit is contained in:
Arkadiusz Fal
2021-10-28 19:14:55 +02:00
parent c387454d9a
commit 24f7c566bf
18 changed files with 169 additions and 55 deletions

View File

@@ -5,6 +5,10 @@ private struct InNavigationViewKey: EnvironmentKey {
static let defaultValue = false
}
private struct InChannelViewKey: EnvironmentKey {
static let defaultValue = false
}
private struct HorizontalCellsKey: EnvironmentKey {
static let defaultValue = false
}
@@ -27,6 +31,11 @@ extension EnvironmentValues {
set { self[InNavigationViewKey.self] = newValue }
}
var inChannelView: Bool {
get { self[InChannelViewKey.self] }
set { self[InChannelViewKey.self] = newValue }
}
var horizontalCells: Bool {
get { self[HorizontalCellsKey.self] }
set { self[HorizontalCellsKey.self] = newValue }

View File

@@ -104,6 +104,7 @@ struct AppTabNavigation: View {
if let channel = recents.presentedChannel {
NavigationView {
ChannelVideosView(channel: channel)
.environment(\.inChannelView, true)
.environment(\.inNavigationView, true)
.background(playerNavigationLink)
}

View File

@@ -2,6 +2,7 @@ import Defaults
import SwiftUI
struct Player: UIViewControllerRepresentable {
@EnvironmentObject<NavigationModel> private var navigation
@EnvironmentObject<PlayerModel> private var player
var controller: PlayerViewController?
@@ -17,6 +18,7 @@ struct Player: UIViewControllerRepresentable {
let controller = PlayerViewController()
controller.navigationModel = navigation
controller.playerModel = player
player.controller = controller

View File

@@ -4,6 +4,7 @@ import SwiftUI
final class PlayerViewController: UIViewController {
var playerLoaded = false
var navigationModel: NavigationModel!
var playerModel: PlayerModel!
var playerViewController = AVPlayerViewController()
@@ -11,6 +12,12 @@ final class PlayerViewController: UIViewController {
super.viewWillAppear(animated)
loadPlayer()
#if os(tvOS)
if !playerViewController.isBeingPresented, !playerViewController.isBeingDismissed {
present(playerViewController, animated: false)
}
#endif
}
func loadPlayer() {
@@ -26,12 +33,9 @@ final class PlayerViewController: UIViewController {
#if os(tvOS)
playerModel.avPlayerViewController = playerViewController
playerViewController.customInfoViewControllers = [playerQueueInfoViewController]
present(playerViewController, animated: false)
#else
embedViewController()
#endif
playerLoaded = true
}
#if os(tvOS)
@@ -66,7 +70,7 @@ extension PlayerViewController: AVPlayerViewControllerDelegate {
}
func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_: AVPlayerViewController) -> Bool {
false
true
}
func playerViewControllerWillBeginDismissalTransition(_: AVPlayerViewController) {}
@@ -95,7 +99,35 @@ extension PlayerViewController: AVPlayerViewControllerDelegate {
}
}
func playerViewControllerWillStartPictureInPicture(_: AVPlayerViewController) {}
func playerViewController(
_ playerViewController: AVPlayerViewController,
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void
) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if self.navigationModel.presentingChannel {
self.playerModel.playerNavigationLinkActive = true
} else {
self.playerModel.presentPlayer()
}
func playerViewControllerWillStopPictureInPicture(_: AVPlayerViewController) {}
#if os(tvOS)
if self.playerModel.playingInPictureInPicture {
self.present(playerViewController, animated: false) {
completionHandler(true)
}
}
#else
completionHandler(true)
#endif
}
}
func playerViewControllerWillStartPictureInPicture(_: AVPlayerViewController) {
playerModel.playingInPictureInPicture = true
playerModel.playerNavigationLinkActive = false
}
func playerViewControllerWillStopPictureInPicture(_: AVPlayerViewController) {
playerModel.playingInPictureInPicture = false
}
}

View File

@@ -17,6 +17,7 @@ struct VideoDetails: View {
@State private var currentPage = Page.details
@Environment(\.dismiss) private var dismiss
@Environment(\.inNavigationView) private var inNavigationView
@EnvironmentObject<AccountsModel> private var accounts
@EnvironmentObject<PlayerModel> private var player
@@ -89,6 +90,7 @@ struct VideoDetails: View {
.edgesIgnoringSafeArea(.horizontal)
}
}
.padding(.top, inNavigationView && fullScreen ? 10 : 0)
.onAppear {
#if !os(macOS)
if video.isNil {
@@ -298,9 +300,9 @@ struct VideoDetails: View {
}
#if os(iOS)
.sheet(isPresented: $presentingShareSheet) {
ShareSheet(activityItems: [
accounts.api.shareURL(contentItem)
])
if let url = accounts.api.shareURL(contentItem) {
ShareSheet(activityItems: [url])
}
}
#endif
}

View File

@@ -42,9 +42,9 @@ struct VideoPlayerView: View {
var content: some View {
Group {
VStack(alignment: .leading, spacing: 0) {
Group {
#if os(tvOS)
player()
player.playerView
#else
GeometryReader { geometry in
VStack(spacing: 0) {
@@ -59,7 +59,8 @@ struct VideoPlayerView: View {
if player.currentItem.isNil {
playerPlaceholder(geometry: geometry)
} else {
player(geometry: geometry)
player.playerView
.modifier(VideoPlayerSizeModifier(geometry: geometry))
}
}
#if os(iOS)
@@ -131,13 +132,6 @@ struct VideoPlayerView: View {
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: geometry.size.width / VideoPlayerView.defaultAspectRatio)
}
func player(geometry: GeometryProxy? = nil) -> some View {
Player()
#if !os(tvOS)
.modifier(VideoPlayerSizeModifier(geometry: geometry))
#endif
}
#if os(iOS)
var sidebarQueue: Bool {
horizontalSizeClass == .regular && playerSize.width > 750

View File

@@ -21,6 +21,10 @@ struct VideoCell: View {
Button(action: {
player.playNow(video)
guard !player.playingInPictureInPicture else {
return
}
if inNavigationView {
player.playerNavigationLinkActive = true
} else {

View File

@@ -48,9 +48,9 @@ struct ChannelPlaylistView: View {
}
#if os(iOS)
.sheet(isPresented: $presentingShareSheet) {
ShareSheet(activityItems: [
accounts.api.shareURL(contentItem)
])
if let url = accounts.api.shareURL(contentItem) {
ShareSheet(activityItems: [url])
}
}
#endif
.onAppear {

View File

@@ -67,6 +67,7 @@ struct ChannelVideosView: View {
.prefersDefaultFocus(in: focusNamespace)
#endif
}
.environment(\.inChannelView, true)
#if !os(iOS)
.focusScope(focusNamespace)
#endif
@@ -102,9 +103,9 @@ struct ChannelVideosView: View {
#endif
#if os(iOS)
.sheet(isPresented: $presentingShareSheet) {
ShareSheet(activityItems: [
accounts.api.shareURL(contentItem)
])
if let url = accounts.api.shareURL(contentItem) {
ShareSheet(activityItems: [url])
}
}
#endif
.modifier(UnsubscribeAlertModifier())

View File

@@ -7,28 +7,34 @@ struct ShareButton: View {
@EnvironmentObject<AccountsModel> private var accounts
var body: some View {
Button {
#if os(iOS)
presentingShareSheet = true
#else
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(shareURL, forType: .string)
#endif
} label: {
#if os(iOS)
Label("Share", systemImage: "square.and.arrow.up")
#else
Group {
if let url = shareURL {
Button {
#if os(iOS)
presentingShareSheet = true
#else
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(url, forType: .string)
#endif
} label: {
#if os(iOS)
Label("Share", systemImage: "square.and.arrow.up")
#else
EmptyView()
#endif
}
.keyboardShortcut("c")
.foregroundColor(.blue)
.buttonStyle(.plain)
.labelStyle(.iconOnly)
} else {
EmptyView()
#endif
}
}
.keyboardShortcut("c")
.foregroundColor(.blue)
.buttonStyle(.plain)
.labelStyle(.iconOnly)
}
private var shareURL: String {
accounts.api.shareURL(contentItem).absoluteString
private var shareURL: String? {
accounts.api.shareURL(contentItem)?.absoluteString
}
}

View File

@@ -7,6 +7,7 @@ struct VideoContextMenuView: View {
@Binding var playerNavigationLinkActive: Bool
@Environment(\.inNavigationView) private var inNavigationView
@Environment(\.inChannelView) private var inChannelView
@Environment(\.navigationStyle) private var navigationStyle
@Environment(\.currentPlaylistID) private var playlistID
@@ -27,11 +28,13 @@ struct VideoContextMenuView: View {
addToQueueButton
}
Section {
openChannelButton
if !inChannelView {
Section {
openChannelButton
if accounts.app.supportsSubscriptions {
subscriptionButton
if accounts.app.supportsSubscriptions {
subscriptionButton
}
}
}
@@ -54,6 +57,10 @@ struct VideoContextMenuView: View {
Button {
player.playNow(video)
guard !player.playingInPictureInPicture else {
return
}
if inNavigationView {
playerNavigationLinkActive = true
} else {
@@ -72,6 +79,14 @@ struct VideoContextMenuView: View {
}
}
private var isShowingChannelButton: Bool {
if case .channel = navigation.tabSelection {
return false
}
return !inChannelView
}
private var addToQueueButton: some View {
Button {
player.enqueueVideo(video)