refactor(repository): reorder state updates to prevent empty intermediate states

This commit is contained in:
2026-06-22 20:30:31 +02:00
parent 8c758e8262
commit f0a7828613

View File

@@ -329,15 +329,6 @@ class InMemoryAppContentRepository @Inject constructor(
}
if (suggestionsItems == null) return@run
suggestionsState.value = suggestionsItems.mapNotNull { item ->
when (item.type) {
BaseItemKind.MOVIE -> Media.MovieMedia(movieId = item.id)
BaseItemKind.EPISODE -> Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
else -> throw UnsupportedOperationException("Unsupported item type: ${item.type}")
}
}
// Upsert full details so the home viewmodel can look up each item.
suggestionsItems.forEach { item ->
when (item.type) {
BaseItemKind.MOVIE -> onlineMediaRepository.upsertMovies(listOf(item.toMovie(url)))
@@ -345,6 +336,14 @@ class InMemoryAppContentRepository @Inject constructor(
else -> {}
}
}
suggestionsState.value = suggestionsItems.mapNotNull { item ->
when (item.type) {
BaseItemKind.MOVIE -> Media.MovieMedia(movieId = item.id)
BaseItemKind.EPISODE -> Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
else -> throw UnsupportedOperationException("Unsupported item type: ${item.type}")
}
}
}
private suspend fun loadContinueWatching() = singleFlight.run("AppContent:loadContinueWatching") {
@@ -362,14 +361,12 @@ class InMemoryAppContentRepository @Inject constructor(
}
if (continueWatchingItems == null) return@run
continueWatchingState.value = continueWatchingItems.mapNotNull { item ->
when (item.type) {
BaseItemKind.MOVIE -> Media.MovieMedia(movieId = item.id)
BaseItemKind.EPISODE -> Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
else -> throw UnsupportedOperationException("Unsupported item type: ${item.type}")
}
}
// Upsert full details BEFORE publishing the new row, so the
// home viewmodel's `combine` of this flow with the local media
// repository never observes an empty intermediate state. If we
// assigned continueWatchingState first, the new episode/movie IDs
// would be unresolvable for a single emission and the Continue
// Watching section would briefly drop from the home screen.
continueWatchingItems.forEach { item ->
when (item.type) {
BaseItemKind.MOVIE -> onlineMediaRepository.upsertMovies(listOf(item.toMovie(url)))
@@ -377,6 +374,14 @@ class InMemoryAppContentRepository @Inject constructor(
else -> {}
}
}
continueWatchingState.value = continueWatchingItems.mapNotNull { item ->
when (item.type) {
BaseItemKind.MOVIE -> Media.MovieMedia(movieId = item.id)
BaseItemKind.EPISODE -> Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
else -> throw UnsupportedOperationException("Unsupported item type: ${item.type}")
}
}
}
private suspend fun loadNextUp() = singleFlight.run("AppContent:loadNextUp") {
@@ -394,13 +399,19 @@ class InMemoryAppContentRepository @Inject constructor(
}
if (nextUpItems == null) return@run
nextUpState.value = nextUpItems.map { item ->
Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
}
// Upsert full details BEFORE publishing the new row, so the
// home viewmodel's `combine` of this flow with the local media
// repository never observes an empty intermediate state. If we
// assigned nextUpState first, the new episode IDs would be
// unresolvable for a single emission and the Next Up section
// would briefly drop from the home screen.
nextUpItems.forEach { item ->
onlineMediaRepository.upsertEpisodes(listOf(item.toEpisode(url)))
}
nextUpState.value = nextUpItems.map { item ->
Media.EpisodeMedia(episodeId = item.id, seriesId = item.seriesId!!)
}
}
private suspend fun loadLatestLibraryContent() = singleFlight.run("AppContent:loadLatestLibraryContent") {