Show overlay for extra items (#1320)

## Description
Shows the overlay (watched, progress bar) for extras appearing as single
items. Grouped extras individually show the overlay when clicking into.
If all of the grouped are played, the group is show with the watched
indicator.

Also very slightly optimizations the UI by offloading the
title/subtitle/imageUrl to object creation time instead of when they're
shown on screen.

### Related issues
Closes #1311

### Testing
Shield testing with different extras

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-04-26 17:52:57 -04:00 • committed by GitHub
parent 8cf99900e5
commit 5571654a22
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 42 deletions

View file

@ -1,19 +1,13 @@
package com.github.damontecres.wholphin.ui.cards
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalResources
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.ExtrasItem
import com.github.damontecres.wholphin.data.pluralRes
import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.Cards
import com.github.damontecres.wholphin.ui.LocalImageUrlService
import org.jellyfin.sdk.model.api.ImageType
@Composable
fun ExtrasRow(
@ -22,52 +16,27 @@ fun ExtrasRow(
onLongClickItem: (Int, ExtrasItem) -> Unit,
modifier: Modifier = Modifier,
) {
val context = LocalContext.current
val resources = LocalResources.current
ItemRow(
title = stringResource(R.string.extras),
items = extras,
onClickItem = onClickItem,
onLongClickItem = onLongClickItem,
cardContent = { index, item, mod, onClick, onLongClick ->
val imageUrlService = LocalImageUrlService.current
val imageUrl =
remember {
val item =
when (item) {
is ExtrasItem.Group -> item.items.random()
is ExtrasItem.Single -> item.item
null -> null
}
imageUrlService.getItemImageUrl(item, ImageType.PRIMARY)
}
SeasonCard(
title =
when (item) {
is ExtrasItem.Group -> item.type.pluralRes.let { resources.getQuantityString(it, item.items.size) }
is ExtrasItem.Single -> item.title ?: item.type.pluralRes.let { resources.getQuantityString(it, 1) }
null -> null
},
title = item?.title,
name = null,
subtitle =
if (item is ExtrasItem.Single && item.title != null) {
item.type.pluralRes.let { resources.getQuantityString(it, 1) }
} else if (item is ExtrasItem.Group) {
resources.getQuantityString(R.plurals.items, item.items.size, item.items.size)
} else {
null
},
subtitle = item?.subtitle,
onClick = onClick,
onLongClick = onLongClick,
modifier = mod,
showImageOverlay = true,
imageHeight = Cards.height2x3 * .75f,
imageHeight = Cards.heightEpisode,
imageWidth = Dp.Unspecified,
imageUrl = imageUrl,
imageUrl = item?.imageUrl,
isFavorite = false,
isPlayed = false,
isPlayed = item?.isPlayed == true,
unplayedItemCount = -1,
playedPercentage = -1.0,
playedPercentage = item?.playedPercentage ?: 0.0,
numberOfVersions = -1,
aspectRatio = AspectRatios.FOUR_THREE, // TODO
)