Add badges to TmdbEntityBrowser

This commit is contained in:
skoruppa 2026-07-31 12:46:59 +02:00
parent 0e1e12a8fc
commit abbfb62b4e
4 changed files with 32 additions and 2 deletions

View file

@ -90,6 +90,7 @@ fun TmdbEntityBrowseScreen(
WatchedRepository.ensureLoaded()
WatchedRepository.uiState
}.collectAsStateWithLifecycle()
val fullyWatchedSeriesKeys by WatchedRepository.fullyWatchedSeriesKeys.collectAsStateWithLifecycle()
val loadFailedMessage = stringResource(Res.string.details_browse_load_failed, entityName)
LaunchedEffect(entityKind, entityId) {
@ -122,6 +123,7 @@ fun TmdbEntityBrowseScreen(
data = state.data,
sourceType = sourceType,
watchedKeys = watchedUiState.watchedKeys,
fullyWatchedSeriesKeys = fullyWatchedSeriesKeys,
onOpenMeta = onOpenMeta,
)
}
@ -150,6 +152,7 @@ private fun EntityBrowseContent(
data: TmdbEntityBrowseData,
sourceType: String,
watchedKeys: Set<String>,
fullyWatchedSeriesKeys: Set<String>,
onOpenMeta: (MetaPreview) -> Unit,
) {
val backgroundUrl = remember(data.rails, sourceType) {
@ -192,6 +195,7 @@ private fun EntityBrowseContent(
WideEntityBrowseContent(
data = data,
watchedKeys = watchedKeys,
fullyWatchedSeriesKeys = fullyWatchedSeriesKeys,
onOpenMeta = onOpenMeta,
)
} else if (data.rails.isEmpty()) {
@ -225,6 +229,7 @@ private fun EntityBrowseContent(
title = entityRailTitle(rail),
items = rail.items,
watchedKeys = watchedKeys,
fullyWatchedSeriesKeys = fullyWatchedSeriesKeys,
headerHorizontalPadding = 20.dp,
onPosterClick = onOpenMeta,
)
@ -242,6 +247,7 @@ private fun EntityBrowseContent(
private fun WideEntityBrowseContent(
data: TmdbEntityBrowseData,
watchedKeys: Set<String>,
fullyWatchedSeriesKeys: Set<String>,
onOpenMeta: (MetaPreview) -> Unit,
) {
Row(
@ -292,6 +298,7 @@ private fun WideEntityBrowseContent(
title = entityRailTitle(rail),
items = rail.items,
watchedKeys = watchedKeys,
fullyWatchedSeriesKeys = fullyWatchedSeriesKeys,
headerHorizontalPadding = 0.dp,
onPosterClick = onOpenMeta,
)

View file

@ -25,6 +25,7 @@ fun DetailPosterRailSection(
items: List<MetaPreview>,
watchedKeys: Set<String>,
modifier: Modifier = Modifier,
fullyWatchedSeriesKeys: Set<String> = emptySet(),
showHeader: Boolean = true,
headerHorizontalPadding: Dp = 0.dp,
horizontalScrollPadding: Dp = 0.dp,
@ -50,6 +51,7 @@ fun DetailPosterRailSection(
isWatched = WatchingState.isPosterWatched(
watchedKeys = watchedKeys,
item = item,
fullyWatchedSeriesKeys = fullyWatchedSeriesKeys,
),
onClick = onPosterClick?.let { { it(item) } },
onLongClick = onPosterLongClick?.let { { it(item) } },

View file

@ -63,14 +63,15 @@ object SimklWatchedSyncAdapter : TrackingWatchedProvider {
intent = TrackingRefreshIntent.AUTOMATIC,
origin = SimklRefreshOrigin.WATCHED_ITEMS,
)
return SimklSyncRepository.state.value.snapshot.animeAlternateWatchedKeys()
val snapshot = SimklSyncRepository.state.value.snapshot
return snapshot.animeAlternateWatchedKeys() + snapshot.movieAlternateWatchedKeys()
}
override fun observeExtraWatchedKeys(profileId: Int): kotlinx.coroutines.flow.Flow<Set<String>> =
SimklSyncRepository.state
.map { state ->
SimklAnimeWatchedFallback.clearOptimisticRemovals()
state.snapshot.animeAlternateWatchedKeys()
state.snapshot.animeAlternateWatchedKeys() + state.snapshot.movieAlternateWatchedKeys()
}
.distinctUntilChanged()

View file

@ -142,6 +142,26 @@ internal fun SimklSyncSnapshot.animeAlternateWatchedKeys(): Set<String> {
return extraKeys
}
/**
* Builds watched keys under alternate content IDs for completed/watched movies.
* This allows entity browsers showing movies under tmdb: IDs to display watched badges
* even though the primary watched key uses an IMDB ID.
*/
internal fun SimklSyncSnapshot.movieAlternateWatchedKeys(): Set<String> {
val extraKeys = linkedSetOf<String>()
entries.forEach { entry ->
if (entry.mediaType != SimklMediaType.MOVIES) return@forEach
if (entry.lastWatchedAt == null && entry.status != SimklListStatus.COMPLETED) return@forEach
val media = entry.media ?: return@forEach
val contentId = media.canonicalContentId() ?: return@forEach
val alternateIds = media.alternateContentIds() - contentId
alternateIds.forEach { altId ->
extraKeys += watchedItemKey("movie", altId)
}
}
return extraKeys
}
internal fun SimklSyncSnapshot.toSimklProgressEntries(): List<WatchProgressEntry> =
playback
.mapNotNull(SimklPlaybackSession::toWatchProgressEntry)