Consulting the `NextUp` endpoint for next episode in a season

And fallback to the old mechanism if either the next episode in this
series doesn't match the current season or something goes wrong.
This commit is contained in:
Min-Yih Hsu 2022-02-08 19:42:51 +08:00
parent 909501b530
commit 41a3644417
1 changed files with 43 additions and 21 deletions

View File

@ -53,36 +53,58 @@ final class SeasonItemViewModel: ItemViewModel, EpisodesRowManager {
.sink(receiveCompletion: { [weak self] completion in .sink(receiveCompletion: { [weak self] completion in
self?.handleAPIRequestError(completion: completion) self?.handleAPIRequestError(completion: completion)
}, receiveValue: { [weak self] response in }, receiveValue: { [weak self] response in
self?.episodes = response.items ?? [] guard let self = self else { return }
LogManager.shared.log.debug("Retrieved \(String(self?.episodes.count ?? 0)) episodes") self.episodes = response.items ?? []
LogManager.shared.log.debug("Retrieved \(String(self.episodes.count)) episodes")
self?.setNextUpInSeason() self.setNextUpInSeason()
}) })
.store(in: &cancellables) .store(in: &cancellables)
} }
// Sets the play button item to the "Next up" in the season based upon
// the watched status of episodes in the season.
// Default to the first episode of the season if all have been watched.
private func setNextUpInSeason() { private func setNextUpInSeason() {
guard !episodes.isEmpty else { return }
var firstUnwatchedSearch: BaseItemDto? TvShowsAPI.getNextUp(userId: SessionManager.main.currentLogin.user.id,
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
seriesId: item.seriesId ?? "", enableUserData: true)
.trackActivity(loading)
.sink(receiveCompletion: { [weak self] completion in
self?.handleAPIRequestError(completion: completion)
}, receiveValue: { [weak self] response in
guard let self = self else { return }
for episode in episodes { // Find the nextup item that belongs to current season.
guard let played = episode.userData?.played else { continue } if let nextUpItem = (response.items ?? []).first(where: { episode in
if !played { !episode.unaired && !episode.missing && episode.seasonId ?? "" == self.item.id!
firstUnwatchedSearch = episode }) {
break self.playButtonItem = nextUpItem
} LogManager.shared.log.debug("Nextup in season \(self.item.id!) (\(self.item.name!)): \(nextUpItem.id!)")
} }
if let firstUnwatched = firstUnwatchedSearch { if self.playButtonItem == nil && !self.episodes.isEmpty {
playButtonItem = firstUnwatched // Fallback to the old mechanism:
} else { // Sets the play button item to the "Next up" in the season based upon
guard let firstEpisode = episodes.first else { return } // the watched status of episodes in the season.
playButtonItem = firstEpisode // Default to the first episode of the season if all have been watched.
} var firstUnwatchedSearch: BaseItemDto?
for episode in self.episodes {
guard let played = episode.userData?.played else { continue }
if !played {
firstUnwatchedSearch = episode
break
}
}
if let firstUnwatched = firstUnwatchedSearch {
self.playButtonItem = firstUnwatched
} else {
guard let firstEpisode = self.episodes.first else { return }
self.playButtonItem = firstEpisode
}
}
})
.store(in: &cancellables)
} }
private func getSeriesItem() { private func getSeriesItem() {