From 41a3644417f9b3b8113c251320785915f1b43814 Mon Sep 17 00:00:00 2001 From: Min-Yih Hsu Date: Tue, 8 Feb 2022 19:42:51 +0800 Subject: [PATCH] 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. --- .../ItemViewModel/SeasonItemViewModel.swift | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/Shared/ViewModels/ItemViewModel/SeasonItemViewModel.swift b/Shared/ViewModels/ItemViewModel/SeasonItemViewModel.swift index 08efba23..edb9fb87 100644 --- a/Shared/ViewModels/ItemViewModel/SeasonItemViewModel.swift +++ b/Shared/ViewModels/ItemViewModel/SeasonItemViewModel.swift @@ -53,36 +53,58 @@ final class SeasonItemViewModel: ItemViewModel, EpisodesRowManager { .sink(receiveCompletion: { [weak self] completion in self?.handleAPIRequestError(completion: completion) }, receiveValue: { [weak self] response in - self?.episodes = response.items ?? [] - LogManager.shared.log.debug("Retrieved \(String(self?.episodes.count ?? 0)) episodes") + guard let self = self else { return } + self.episodes = response.items ?? [] + LogManager.shared.log.debug("Retrieved \(String(self.episodes.count)) episodes") - self?.setNextUpInSeason() + self.setNextUpInSeason() }) .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() { - 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 { - guard let played = episode.userData?.played else { continue } - if !played { - firstUnwatchedSearch = episode - break - } - } + // Find the nextup item that belongs to current season. + if let nextUpItem = (response.items ?? []).first(where: { episode in + !episode.unaired && !episode.missing && episode.seasonId ?? "" == self.item.id! + }) { + self.playButtonItem = nextUpItem + LogManager.shared.log.debug("Nextup in season \(self.item.id!) (\(self.item.name!)): \(nextUpItem.id!)") + } - if let firstUnwatched = firstUnwatchedSearch { - playButtonItem = firstUnwatched - } else { - guard let firstEpisode = episodes.first else { return } - playButtonItem = firstEpisode - } + if self.playButtonItem == nil && !self.episodes.isEmpty { + // Fallback to the old mechanism: + // 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. + 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() {