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,10 +1,15 @@
package com.github.damontecres.wholphin.services
import android.content.Context
import com.github.damontecres.wholphin.R
import com.github.damontecres.wholphin.data.ExtrasItem
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.pluralRes
import dagger.hilt.android.qualifiers.ApplicationContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
import org.jellyfin.sdk.model.api.ExtraType
import org.jellyfin.sdk.model.api.ImageType
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton
@ -19,6 +24,8 @@ class ExtrasService
@Inject
constructor(
private val api: ApiClient,
@param:ApplicationContext private val context: Context,
private val imageUrlService: ImageUrlService,
) {
/**
* Get the [ExtrasItem]s for the given item
@ -39,9 +46,45 @@ class ExtrasService
extrasMap
.mapNotNull { (type, items) ->
if (items.size == 1) {
ExtrasItem.Single(itemId, type, items.first())
val item = items.first()
val title =
item.title ?: context.resources.getQuantityString(type.pluralRes, 1)
val subtitle =
if (item.title == null) {
context.resources.getQuantityString(type.pluralRes, 1)
} else {
null
}
ExtrasItem.Single(
parentId = itemId,
type = type,
item = item,
title = title,
subtitle = subtitle,
imageUrl = imageUrlService.getItemImageUrl(item, ImageType.PRIMARY),
)
} else if (items.size > 1) {
ExtrasItem.Group(itemId, type, items)
val title =
context.resources.getQuantityString(type.pluralRes, items.size)
val subtitle =
context.resources.getQuantityString(
R.plurals.items,
items.size,
items.size,
)
ExtrasItem.Group(
parentId = itemId,
type = type,
items = items,
title = title,
subtitle = subtitle,
isPlayed = items.all { it.played },
imageUrl =
imageUrlService.getItemImageUrl(
items.random(),
ImageType.PRIMARY,
),
)
} else {
null
}