From e669f3ad597ce5e3486af82d06e4d005c62eac03 Mon Sep 17 00:00:00 2001 From: damontecres <154766448+damontecres@users.noreply.github.com> Date: Sat, 6 Dec 2025 15:35:29 -0500 Subject: [PATCH] Fix combining continue/next-up for new episode premieres (#381) Better handling for combining continue/next-up by considering the premiere date of the episode. So episodes will use the previously watched one's last played date or the episode's premiere date, whichever is newer. This means when a new season comes out or the show returns from a break, the new episodes will show earlier in the list like the next up rows shows when not combined. Fixes #377 --- .../wholphin/services/DatePlayedService.kt | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt b/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt index 16c12fca..0a83c1c3 100644 --- a/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt +++ b/app/src/main/java/com/github/damontecres/wholphin/services/DatePlayedService.kt @@ -8,7 +8,6 @@ import com.github.damontecres.wholphin.preferences.AppPreference import com.github.damontecres.wholphin.services.hilt.IoCoroutineScope import com.github.damontecres.wholphin.util.GetEpisodesRequestHandler import com.google.common.cache.CacheBuilder -import com.google.common.cache.CacheLoader import dagger.hilt.android.qualifiers.ActivityContext import dagger.hilt.android.scopes.ActivityScoped import kotlinx.coroutines.CoroutineScope @@ -40,20 +39,20 @@ class DatePlayedService .newBuilder() .maximumSize(AppPreference.HomePageItems.max) .expireAfterWrite(2, TimeUnit.HOURS) - .build>( - object : CacheLoader>() { - override fun load(key: SeriesItemId): Deferred = getLastPlayed(key) - }, - ) + .build>() - private fun getLastPlayed(key: SeriesItemId): Deferred { + private fun getLastPlayed( + seriesId: UUID, + item: BaseItem, + ): Deferred { val request = GetEpisodesRequest( - seriesId = key.seriesId, - adjacentTo = key.itemId, + seriesId = seriesId, + adjacentTo = item.id, limit = 1, ) return scope.async(Dispatchers.IO) { + val premiereDate = item.data.premiereDate try { val result = GetEpisodesRequestHandler @@ -61,10 +60,22 @@ class DatePlayedService api, request, ).content.items - result.firstOrNull()?.userData?.lastPlayedDate ?: LocalDateTime.MIN + .firstOrNull() + ?.userData + ?.lastPlayedDate + if (premiereDate != null && premiereDate.isAfter(result)) { + premiereDate + } else { + result + } ?: LocalDateTime.MIN } catch (ex: InvalidStatusException) { - Timber.w("Error fetching %s: %s", key, ex.localizedMessage) - LocalDateTime.MIN + Timber.w( + "Error fetching series=%s, item=%s: %s", + seriesId, + item.id, + ex.localizedMessage, + ) + LocalDateTime.MIN.coerceAtLeast(premiereDate ?: LocalDateTime.MIN) } } } @@ -73,7 +84,10 @@ class DatePlayedService withContext(Dispatchers.IO) { val seriesId = item.data.seriesId return@withContext if (seriesId != null) { - datePlayedCache.get(SeriesItemId(seriesId, item.id)).await() + datePlayedCache + .get(SeriesItemId(seriesId, item.id)) { + getLastPlayed(seriesId, item) + }.await() } else { null }