Let's test Trakt Updates

This commit is contained in:
cranci1 2025-06-11 10:36:48 +02:00
parent 1a4b78e64e
commit 175f011d01
4 changed files with 99 additions and 36 deletions

View file

@ -31,13 +31,10 @@ class TraktMutation {
} }
enum ExternalIDType { enum ExternalIDType {
case imdb(String)
case tmdb(Int) case tmdb(Int)
var dictionary: [String: Any] { var dictionary: [String: Any] {
switch self { switch self {
case .imdb(let id):
return ["imdb": id]
case .tmdb(let id): case .tmdb(let id):
return ["tmdb": id] return ["tmdb": id]
} }

View file

@ -24,6 +24,9 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
let onWatchNext: () -> Void let onWatchNext: () -> Void
let aniListID: Int let aniListID: Int
var headers: [String:String]? = nil var headers: [String:String]? = nil
var tmdbID: Int? = nil
var isMovie: Bool = false
var seasonNumber: Int = 1
private var aniListUpdatedSuccessfully = false private var aniListUpdatedSuccessfully = false
private var aniListUpdateImpossible: Bool = false private var aniListUpdateImpossible: Bool = false
@ -1644,12 +1647,39 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
let remainingPercentage = (self.duration - self.currentTimeVal) / self.duration let remainingPercentage = (self.duration - self.currentTimeVal) / self.duration
if remainingPercentage < 0.1 && if remainingPercentage < 0.1 {
self.aniListID != 0 && if self.aniListID != 0 && !self.aniListUpdatedSuccessfully && !self.aniListUpdateImpossible {
!self.aniListUpdatedSuccessfully && self.tryAniListUpdate()
!self.aniListUpdateImpossible }
{
self.tryAniListUpdate() if let tmdbId = self.tmdbID {
let traktMutation = TraktMutation()
if self.isMovie {
traktMutation.markAsWatched(type: "movie", externalID: .tmdb(tmdbId)) { result in
switch result {
case .success:
Logger.shared.log("Successfully updated Trakt progress for movie", type: "General")
case .failure(let error):
Logger.shared.log("Failed to update Trakt progress: \(error.localizedDescription)", type: "Error")
}
}
} else {
traktMutation.markAsWatched(
type: "episode",
externalID: .tmdb(tmdbId),
episodeNumber: self.episodeNumber,
seasonNumber: self.seasonNumber
) { result in
switch result {
case .success:
Logger.shared.log("Successfully updated Trakt progress for episode \(self.episodeNumber)", type: "General")
case .failure(let error):
Logger.shared.log("Failed to update Trakt progress: \(error.localizedDescription)", type: "Error")
}
}
}
}
} }
self.sliderHostingController?.rootView = MusicProgressSlider( self.sliderHostingController?.rootView = MusicProgressSlider(
@ -1796,6 +1826,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
@objc func seekBackward() { @objc func seekBackward() {
let skipValue = UserDefaults.standard.double(forKey: "skipIncrement") let skipValue = UserDefaults.standard.double(forKey: "skipIncrement")
let finalSkip = skipValue > 0 ? skipValue : 10 let finalSkip = skipValue > 0 ? skipValue : 10
currentTimeVal = max(currentTimeVal - finalSkip, 0) currentTimeVal = max(currentTimeVal - finalSkip, 0)
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) { [weak self] finished in
guard self != nil else { return } guard self != nil else { return }
@ -1865,8 +1896,8 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
guard isPipAutoEnabled, guard isPipAutoEnabled,
let pip = pipController, let pip = pipController,
!pip.isPictureInPictureActive else { !pip.isPictureInPictureActive else {
return return
} }
pip.startPictureInPicture() pip.startPictureInPicture()
} }
@ -2114,13 +2145,13 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
private func processM3U8Data(data: Data?, url: URL, completion: @escaping () -> Void) { private func processM3U8Data(data: Data?, url: URL, completion: @escaping () -> Void) {
guard let data = data, guard let data = data,
let content = String(data: data, encoding: .utf8) else { let content = String(data: data, encoding: .utf8) else {
Logger.shared.log("Failed to load m3u8 file") Logger.shared.log("Failed to load m3u8 file")
DispatchQueue.main.async { DispatchQueue.main.async {
self.qualities = [] self.qualities = []
completion() completion()
} }
return return
} }
let lines = content.components(separatedBy: .newlines) let lines = content.components(separatedBy: .newlines)
var qualities: [(String, String)] = [] var qualities: [(String, String)] = []
@ -2686,7 +2717,7 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
height: 10, height: 10,
onEditingChanged: { _ in } onEditingChanged: { _ in }
) )
.shadow(color: Color.black.opacity(0.6), radius: 4, x: 0, y: 2) .shadow(color: Color.black.opacity(0.6), radius: 4, x: 0, y: 2)
} }
} }
@ -2701,11 +2732,11 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
default: return .white default: return .white
} }
} }
override var canBecomeFirstResponder: Bool { override var canBecomeFirstResponder: Bool {
return true return true
} }
override var keyCommands: [UIKeyCommand]? { override var keyCommands: [UIKeyCommand]? {
return [ return [
UIKeyCommand(input: " ", modifierFlags: [], action: #selector(handleSpaceKey), discoverabilityTitle: "Play/Pause"), UIKeyCommand(input: " ", modifierFlags: [], action: #selector(handleSpaceKey), discoverabilityTitle: "Play/Pause"),
@ -2716,39 +2747,39 @@ class CustomMediaPlayerViewController: UIViewController, UIGestureRecognizerDele
UIKeyCommand(input: UIKeyCommand.inputEscape, modifierFlags: [], action: #selector(handleEscape), discoverabilityTitle: "Dismiss Player") UIKeyCommand(input: UIKeyCommand.inputEscape, modifierFlags: [], action: #selector(handleEscape), discoverabilityTitle: "Dismiss Player")
] ]
} }
@objc private func handleSpaceKey() { @objc private func handleSpaceKey() {
togglePlayPause() togglePlayPause()
} }
@objc private func handleLeftArrow() { @objc private func handleLeftArrow() {
let skipValue = 10.0 let skipValue = 10.0
currentTimeVal = max(currentTimeVal - skipValue, 0) currentTimeVal = max(currentTimeVal - skipValue, 0)
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
animateButtonRotation(backwardButton, clockwise: false) animateButtonRotation(backwardButton, clockwise: false)
} }
@objc private func handleRightArrow() { @objc private func handleRightArrow() {
let skipValue = 10.0 let skipValue = 10.0
currentTimeVal = min(currentTimeVal + skipValue, duration) currentTimeVal = min(currentTimeVal + skipValue, duration)
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
animateButtonRotation(forwardButton) animateButtonRotation(forwardButton)
} }
@objc private func handleUpArrow() { @objc private func handleUpArrow() {
let skipValue = 60.0 let skipValue = 60.0
currentTimeVal = min(currentTimeVal + skipValue, duration) currentTimeVal = min(currentTimeVal + skipValue, duration)
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
animateButtonRotation(forwardButton) animateButtonRotation(forwardButton)
} }
@objc private func handleDownArrow() { @objc private func handleDownArrow() {
let skipValue = 60.0 let skipValue = 60.0
currentTimeVal = max(currentTimeVal - skipValue, 0) currentTimeVal = max(currentTimeVal - skipValue, 0)
player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600)) player.seek(to: CMTime(seconds: currentTimeVal, preferredTimescale: 600))
animateButtonRotation(backwardButton, clockwise: false) animateButtonRotation(backwardButton, clockwise: false)
} }
@objc private func handleEscape() { @objc private func handleEscape() {
dismiss(animated: true, completion: nil) dismiss(animated: true, completion: nil)
} }

View file

@ -20,7 +20,9 @@ class VideoPlayerViewController: UIViewController {
var aniListID: Int = 0 var aniListID: Int = 0
var headers: [String:String]? = nil var headers: [String:String]? = nil
var totalEpisodes: Int = 0 var totalEpisodes: Int = 0
var tmdbID: Int? = nil
var isMovie: Bool = false
var seasonNumber: Int = 1
var episodeNumber: Int = 0 var episodeNumber: Int = 0
var episodeImageUrl: String = "" var episodeImageUrl: String = ""
var mediaTitle: String = "" var mediaTitle: String = ""
@ -200,14 +202,45 @@ class VideoPlayerViewController: UIViewController {
let remainingPercentage = (duration - currentTime) / duration let remainingPercentage = (duration - currentTime) / duration
if remainingPercentage < 0.1 && self.aniListID != 0 { if remainingPercentage < 0.1 {
let aniListMutation = AniListMutation() if self.aniListID != 0 {
aniListMutation.updateAnimeProgress(animeId: self.aniListID, episodeNumber: self.episodeNumber) { result in let aniListMutation = AniListMutation()
switch result { aniListMutation.updateAnimeProgress(animeId: self.aniListID, episodeNumber: self.episodeNumber) { result in
case .success: switch result {
Logger.shared.log("Successfully updated AniList progress for episode \(self.episodeNumber)", type: "General") case .success:
case .failure(let error): Logger.shared.log("Successfully updated AniList progress for episode \(self.episodeNumber)", type: "General")
Logger.shared.log("Failed to update AniList progress: \(error.localizedDescription)", type: "Error") case .failure(let error):
Logger.shared.log("Failed to update AniList progress: \(error.localizedDescription)", type: "Error")
}
}
}
if let tmdbId = self.tmdbID {
let traktMutation = TraktMutation()
if self.isMovie {
traktMutation.markAsWatched(type: "movie", externalID: .tmdb(tmdbId)) { result in
switch result {
case .success:
Logger.shared.log("Successfully updated Trakt progress for movie", type: "General")
case .failure(let error):
Logger.shared.log("Failed to update Trakt progress: \(error.localizedDescription)", type: "Error")
}
}
} else {
traktMutation.markAsWatched(
type: "episode",
externalID: .tmdb(tmdbId),
episodeNumber: self.episodeNumber,
seasonNumber: self.seasonNumber
) { result in
switch result {
case .success:
Logger.shared.log("Successfully updated Trakt progress for episode \(self.episodeNumber)", type: "General")
case .failure(let error):
Logger.shared.log("Failed to update Trakt progress: \(error.localizedDescription)", type: "Error")
}
}
} }
} }
} }

View file

@ -1302,6 +1302,7 @@ struct MediaInfoView: View {
videoPlayerViewController.streamUrl = url videoPlayerViewController.streamUrl = url
videoPlayerViewController.fullUrl = fullURL videoPlayerViewController.fullUrl = fullURL
videoPlayerViewController.episodeNumber = selectedEpisodeNumber videoPlayerViewController.episodeNumber = selectedEpisodeNumber
videoPlayerViewController.seasonNumber = selectedSeason + 1
videoPlayerViewController.episodeImageUrl = selectedEpisodeImage videoPlayerViewController.episodeImageUrl = selectedEpisodeImage
videoPlayerViewController.mediaTitle = title videoPlayerViewController.mediaTitle = title
videoPlayerViewController.subtitles = subtitles ?? "" videoPlayerViewController.subtitles = subtitles ?? ""
@ -1350,6 +1351,7 @@ struct MediaInfoView: View {
episodeImageUrl: selectedEpisodeImage, episodeImageUrl: selectedEpisodeImage,
headers: headers ?? nil headers: headers ?? nil
) )
customMediaPlayer.seasonNumber = selectedSeason + 1
customMediaPlayer.modalPresentationStyle = .fullScreen customMediaPlayer.modalPresentationStyle = .fullScreen
Logger.shared.log("Opening custom media player with url: \(url)") Logger.shared.log("Opening custom media player with url: \(url)")