mirror of
https://github.com/yattee/yattee.git
synced 2025-12-14 03:58:14 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b01adf6eb | ||
|
|
444f6bcc03 | ||
|
|
3f871bce2c |
@@ -1,4 +1,4 @@
|
||||
## Build 188
|
||||
## Build 189
|
||||
* Improved thumbnail handling by @stonerl in https://github.com/yattee/yattee/pull/740
|
||||
* iOS: make timestamps in comments touchable by @stonerl in https://github.com/yattee/yattee/pull/741
|
||||
* Improvements to opening channels from Videos by @stonerl in https://github.com/yattee/yattee/pull/742
|
||||
@@ -8,6 +8,7 @@
|
||||
* Xcode 16 - update recommended settings by @stonerl in https://github.com/yattee/yattee/pull/737
|
||||
* Translations update from Hosted Weblate by @weblate in https://github.com/yattee/yattee/pull/724
|
||||
* Updated dependencies
|
||||
* Fixed crashes
|
||||
* Other minor changes and improvements
|
||||
|
||||
## Previous builds
|
||||
|
||||
@@ -360,8 +360,8 @@ final class MPVBackend: PlayerBackend {
|
||||
setRate(model.currentRate)
|
||||
|
||||
// After the video has ended, hitting play restarts the video from the beginning.
|
||||
if currentTime?.seconds.formattedAsPlaybackTime() == model.playerTime.duration.seconds.formattedAsPlaybackTime() &&
|
||||
currentTime!.seconds > 0 && model.playerTime.duration.seconds > 0
|
||||
if let currentTime, currentTime.seconds.formattedAsPlaybackTime() == model.playerTime.duration.seconds.formattedAsPlaybackTime() &&
|
||||
currentTime.seconds > 0 && model.playerTime.duration.seconds > 0
|
||||
{
|
||||
seek(to: 0, seekType: .loopRestart)
|
||||
}
|
||||
|
||||
@@ -69,7 +69,10 @@ final class PlaylistsModel: ObservableObject {
|
||||
.onSuccess { resource in
|
||||
self.error = nil
|
||||
if let playlists: [Playlist] = resource.typedContent() {
|
||||
self.playlists = playlists
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else { return }
|
||||
self.playlists = playlists
|
||||
}
|
||||
PlaylistsCacheModel.shared.storePlaylist(account: account, playlists: playlists)
|
||||
onSuccess()
|
||||
}
|
||||
|
||||
@@ -1,211 +0,0 @@
|
||||
import AVKit
|
||||
import Defaults
|
||||
import SwiftUI
|
||||
|
||||
final class PlayerViewController: UIViewController {
|
||||
var playerLoaded = false
|
||||
var commentsModel: CommentsModel!
|
||||
var navigationModel: NavigationModel!
|
||||
var playerModel: PlayerModel!
|
||||
var subscriptionsModel: SubscriptionsModel!
|
||||
var playerView = AVPlayerViewController()
|
||||
|
||||
let persistenceController = PersistenceController.shared
|
||||
|
||||
#if !os(tvOS)
|
||||
var aspectRatio: Double? {
|
||||
let ratio = Double(playerView.videoBounds.width) / Double(playerView.videoBounds.height)
|
||||
|
||||
guard ratio.isFinite else {
|
||||
return VideoPlayerView.defaultAspectRatio // swiftlint:disable:this implicit_return
|
||||
}
|
||||
|
||||
return [ratio, 1.0].max()!
|
||||
}
|
||||
#endif
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
loadPlayer()
|
||||
|
||||
#if os(tvOS)
|
||||
if !playerView.isBeingPresented, !playerView.isBeingDismissed {
|
||||
present(playerView, animated: false)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
|
||||
if !playerModel.presentingPlayer, !Defaults[.pauseOnHidingPlayer], !playerModel.isPlaying {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
||||
self?.playerModel.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
func loadPlayer() {
|
||||
guard !playerLoaded else {
|
||||
return
|
||||
}
|
||||
|
||||
playerModel.controller = self
|
||||
playerView.player = playerModel.player
|
||||
playerView.allowsPictureInPicturePlayback = true
|
||||
#if os(iOS)
|
||||
if #available(iOS 14.2, *) {
|
||||
playerView.canStartPictureInPictureAutomaticallyFromInline = true
|
||||
}
|
||||
#endif
|
||||
playerView.delegate = self
|
||||
|
||||
#if os(tvOS)
|
||||
var infoViewControllers = [UIHostingController<AnyView>]()
|
||||
if CommentsModel.enabled {
|
||||
infoViewControllers.append(infoViewController([.comments], title: "Comments"))
|
||||
}
|
||||
|
||||
var queueSections = [NowPlayingView.ViewSection.playingNext]
|
||||
if Defaults[.showHistoryInPlayer] {
|
||||
queueSections.append(.playedPreviously)
|
||||
}
|
||||
|
||||
infoViewControllers.append(contentsOf: [
|
||||
infoViewController([.related], title: "Related"),
|
||||
infoViewController(queueSections, title: "Queue")
|
||||
])
|
||||
|
||||
playerView.customInfoViewControllers = infoViewControllers
|
||||
#else
|
||||
embedViewController()
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
func infoViewController(
|
||||
_ sections: [NowPlayingView.ViewSection],
|
||||
title: String
|
||||
) -> UIHostingController<AnyView> {
|
||||
let controller = UIHostingController(
|
||||
rootView:
|
||||
AnyV/Users/arek/Developer/Yattee/Shared/Player/PlayerViewController.swift.iew(
|
||||
NowPlayingView(sections: sections, inInfoViewController: true)
|
||||
.frame(maxHeight: 600)
|
||||
.environmentObject(commentsModel)
|
||||
.environmentObject(playerModel)
|
||||
.environmentObject(subscriptionsModel)
|
||||
.environment(\.managedObjectContext, persistenceController.container.viewContext)
|
||||
)
|
||||
)
|
||||
|
||||
controller.title = title
|
||||
|
||||
return controller
|
||||
}
|
||||
#else
|
||||
func embedViewController() {
|
||||
playerView.view.frame = view.bounds
|
||||
|
||||
addChild(playerView)
|
||||
view.addSubview(playerView.view)
|
||||
|
||||
playerView.didMove(toParent: self)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extension PlayerViewController: AVPlayerViewControllerDelegate {
|
||||
func playerViewControllerShouldDismiss(_: AVPlayerViewController) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(_: AVPlayerViewController) -> Bool {
|
||||
true
|
||||
}
|
||||
|
||||
func playerViewControllerWillBeginDismissalTransition(_: AVPlayerViewController) {
|
||||
if Defaults[.pauseOnHidingPlayer] {
|
||||
playerModel.pause()
|
||||
}
|
||||
dismiss(animated: false)
|
||||
}
|
||||
|
||||
func playerViewControllerDidEndDismissalTransition(_: AVPlayerViewController) {}
|
||||
|
||||
func playerViewController(
|
||||
_: AVPlayerViewController,
|
||||
willBeginFullScreenPresentationWithAnimationCoordinator context: UIViewControllerTransitionCoordinator
|
||||
) {
|
||||
playerModel.playingFullscreen = true
|
||||
|
||||
#if os(iOS)
|
||||
if !context.isCancelled, Defaults[.lockLandscapeWhenEnteringFullscreen] {
|
||||
Orientation.lockOrientation(.landscape, andRotateTo: UIDevice.current.orientation.isLandscape ? nil : .landscapeRight)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func playerViewController(
|
||||
_: AVPlayerViewController,
|
||||
willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator
|
||||
) {
|
||||
let wasPlaying = playerModel.isPlaying
|
||||
coordinator.animate(alongsideTransition: nil) { context in
|
||||
#if os(iOS)
|
||||
if wasPlaying {
|
||||
self.playerModel.play()
|
||||
}
|
||||
#endif
|
||||
if !context.isCancelled {
|
||||
#if os(iOS)
|
||||
self.playerModel.lockedOrientation = nil
|
||||
if Defaults[.enterFullscreenInLandscape] {
|
||||
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
||||
}
|
||||
|
||||
self.playerModel.playingFullscreen = false
|
||||
|
||||
if wasPlaying {
|
||||
self.playerModel.play()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func 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.show()
|
||||
}
|
||||
|
||||
#if os(tvOS)
|
||||
if self.playerModel.playingInPictureInPicture {
|
||||
self.present(self.playerView, animated: false) {
|
||||
completionHandler(true)
|
||||
}
|
||||
}
|
||||
#else
|
||||
completionHandler(true)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
func playerViewControllerWillStartPictureInPicture(_: AVPlayerViewController) {
|
||||
playerModel.playingInPictureInPicture = true
|
||||
playerModel.playerNavigationLinkActive = false
|
||||
}
|
||||
|
||||
func playerViewControllerWillStopPictureInPicture(_: AVPlayerViewController) {
|
||||
playerModel.playingInPictureInPicture = false
|
||||
}
|
||||
}
|
||||
@@ -4103,7 +4103,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Open in Yattee";
|
||||
@@ -4134,7 +4134,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||
@@ -4165,7 +4165,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
@@ -4185,7 +4185,7 @@
|
||||
buildSettings = {
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 11.0;
|
||||
@@ -4348,7 +4348,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = "iOS/Yattee (iOS).entitlements";
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
@@ -4400,7 +4400,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "GLES_SILENCE_DEPRECATION=1";
|
||||
@@ -4452,7 +4452,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
@@ -4491,7 +4491,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = 78Z5H3M6RJ;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
@@ -4525,7 +4525,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4548,7 +4548,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4573,7 +4573,7 @@
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4597,7 +4597,7 @@
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -4623,7 +4623,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
ENABLE_PREVIEWS = YES;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -4663,7 +4663,7 @@
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Distribution";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
"DEVELOPMENT_TEAM[sdk=appletvos*]" = 78Z5H3M6RJ;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -4703,7 +4703,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
@@ -4726,7 +4726,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 188;
|
||||
CURRENT_PROJECT_VERSION = 189;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
||||
Reference in New Issue
Block a user