Update item fields queried & expand usage of primary aspect ratio (#1852)

## Description
Slight optimization to remove "child count" for grid pages. Adds back
"primary image aspect ratio" for several queries where its necessary.

Also updates extras cards to use the "primary image aspect ratio"
instead of a hard coded value.

Dev note: some light refactoring is also in this PR including renaming
the item fields lists to better reflect the intended usage in code

### Related issues
Fixes #1843

### Testing
Emulator, I tested many pages and views, but probably need to do "real
world" testing to see if I missed anything

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-08-17 22:54:15 -04:00 • committed by GitHub
parent c4264a3263
commit b064af7c4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 105 additions and 83 deletions

View file

@ -27,6 +27,7 @@ sealed interface ExtrasItem {
val subtitle: String? val subtitle: String?
val isPlayed: Boolean val isPlayed: Boolean
val playedPercentage: Double val playedPercentage: Double
val aspectRatio: Float?
/** /**
* Represents multiple extras of the same type * Represents multiple extras of the same type
@ -39,6 +40,7 @@ sealed interface ExtrasItem {
override val title: String, override val title: String,
override val subtitle: String, override val subtitle: String,
override val isPlayed: Boolean, override val isPlayed: Boolean,
override val aspectRatio: Float?,
) : ExtrasItem { ) : ExtrasItem {
override val destination: Destination = override val destination: Destination =
Destination.ItemGrid( Destination.ItemGrid(
@ -82,6 +84,8 @@ sealed interface ExtrasItem {
get() = item.played get() = item.played
override val playedPercentage override val playedPercentage
get() = item.data.userData?.playedPercentage ?: 0.0 get() = item.data.userData?.playedPercentage ?: 0.0
override val aspectRatio: Float?
get() = item.aspectRatio
} }
} }

View file

@ -74,6 +74,7 @@ class ExtrasService
items.size, items.size,
items.size, items.size,
) )
val itemForImage = items.random()
ExtrasItem.Group( ExtrasItem.Group(
parentId = itemId, parentId = itemId,
type = type, type = type,
@ -83,9 +84,10 @@ class ExtrasService
isPlayed = items.all { it.played }, isPlayed = items.all { it.played },
imageUrl = imageUrl =
imageUrlService.getItemImageUrl( imageUrlService.getItemImageUrl(
items.random(), itemForImage,
ImageType.PRIMARY, ImageType.PRIMARY,
), ),
aspectRatio = itemForImage.aspectRatio,
) )
} else { } else {
null null

View file

@ -15,7 +15,7 @@ import com.github.damontecres.wholphin.data.model.AudioItem
import com.github.damontecres.wholphin.data.model.BaseItem import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.preferences.get import com.github.damontecres.wholphin.preferences.get
import com.github.damontecres.wholphin.services.hilt.DefaultCoroutineScope import com.github.damontecres.wholphin.services.hilt.DefaultCoroutineScope
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.DetailItemFields
import com.github.damontecres.wholphin.ui.gt import com.github.damontecres.wholphin.ui.gt
import com.github.damontecres.wholphin.ui.main.settings.MoveDirection import com.github.damontecres.wholphin.ui.main.settings.MoveDirection
import com.github.damontecres.wholphin.ui.onMain import com.github.damontecres.wholphin.ui.onMain
@ -180,7 +180,7 @@ class MusicService
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
itemId = itemId, itemId = itemId,
limit = 200, limit = 200,
fields = DefaultItemFields, fields = DetailItemFields,
).content.items ).content.items
.map { BaseItem(it, false) } .map { BaseItem(it, false) }
setQueue(items, false) setQueue(items, false)

View file

@ -8,7 +8,7 @@ import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.data.model.Playlist import com.github.damontecres.wholphin.data.model.Playlist
import com.github.damontecres.wholphin.data.model.PlaylistInfo import com.github.damontecres.wholphin.data.model.PlaylistInfo
import com.github.damontecres.wholphin.data.model.PlaylistItem import com.github.damontecres.wholphin.data.model.PlaylistItem
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.DetailItemFields
import com.github.damontecres.wholphin.ui.components.baseItemKinds import com.github.damontecres.wholphin.ui.components.baseItemKinds
import com.github.damontecres.wholphin.ui.data.SortAndDirection import com.github.damontecres.wholphin.ui.data.SortAndDirection
import com.github.damontecres.wholphin.ui.gt import com.github.damontecres.wholphin.ui.gt
@ -65,7 +65,7 @@ class PlaylistCreator
GetEpisodesRequest( GetEpisodesRequest(
seriesId = seriesId, seriesId = seriesId,
seasonId = seasonId, seasonId = seasonId,
fields = DefaultItemFields, fields = DetailItemFields,
startItemId = episodeId, startItemId = episodeId,
sortBy = if (shuffled) ItemSortBy.RANDOM else null, sortBy = if (shuffled) ItemSortBy.RANDOM else null,
limit = Playlist.MAX_SIZE, limit = Playlist.MAX_SIZE,
@ -94,7 +94,7 @@ class PlaylistCreator
GetItemsRequest( GetItemsRequest(
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
parentId = playlistId, parentId = playlistId,
fields = DefaultItemFields, fields = DetailItemFields,
startIndex = startIndex, startIndex = startIndex,
limit = Playlist.MAX_SIZE, limit = Playlist.MAX_SIZE,
sortBy = listOf(sortAndDirection.sort), sortBy = listOf(sortAndDirection.sort),
@ -135,7 +135,7 @@ class PlaylistCreator
excludeItemIds = listOf(item.id), excludeItemIds = listOf(item.id),
sortBy = sortAndDirection?.let { listOf(sortAndDirection.sort) }, sortBy = sortAndDirection?.let { listOf(sortAndDirection.sort) },
sortOrder = sortAndDirection?.let { listOf(sortAndDirection.direction) }, sortOrder = sortAndDirection?.let { listOf(sortAndDirection.direction) },
fields = DefaultItemFields, fields = DetailItemFields,
startIndex = startIndex, startIndex = startIndex,
limit = Playlist.MAX_SIZE, limit = Playlist.MAX_SIZE,
excludeLocationTypes = listOf(LocationType.VIRTUAL), excludeLocationTypes = listOf(LocationType.VIRTUAL),
@ -208,7 +208,7 @@ class PlaylistCreator
seasonId = item.id, seasonId = item.id,
limit = Playlist.MAX_SIZE, limit = Playlist.MAX_SIZE,
sortBy = ItemSortBy.RANDOM, sortBy = ItemSortBy.RANDOM,
fields = DefaultItemFields, fields = DetailItemFields,
).content.items ).content.items
.convertAndAddParts() .convertAndAddParts()
.let { .let {
@ -236,7 +236,7 @@ class PlaylistCreator
seriesId = item.id, seriesId = item.id,
limit = Playlist.MAX_SIZE, limit = Playlist.MAX_SIZE,
sortBy = ItemSortBy.RANDOM, sortBy = ItemSortBy.RANDOM,
fields = DefaultItemFields, fields = DetailItemFields,
).content.items ).content.items
.convertAndAddParts() .convertAndAddParts()
.let { .let {

View file

@ -45,11 +45,10 @@ object AppColors {
const val DEFAULT_PAGE_SIZE = 100 const val DEFAULT_PAGE_SIZE = 100
/** /**
* The default [ItemFields] to fetch for most queries * The [ItemFields] to fetch for detailed paged and playback
*/ */
val DefaultItemFields = val DetailItemFields =
listOf( listOf(
ItemFields.CHILD_COUNT,
ItemFields.OVERVIEW, ItemFields.OVERVIEW,
ItemFields.TRICKPLAY, ItemFields.TRICKPLAY,
ItemFields.SORT_NAME, ItemFields.SORT_NAME,
@ -57,6 +56,7 @@ val DefaultItemFields =
ItemFields.MEDIA_SOURCES, ItemFields.MEDIA_SOURCES,
ItemFields.MEDIA_SOURCE_COUNT, ItemFields.MEDIA_SOURCE_COUNT,
ItemFields.CAN_DELETE, ItemFields.CAN_DELETE,
ItemFields.PRIMARY_IMAGE_ASPECT_RATIO,
) )
/** /**
@ -64,13 +64,17 @@ val DefaultItemFields =
*/ */
val SlimItemFields = val SlimItemFields =
listOf( listOf(
ItemFields.CHILD_COUNT,
ItemFields.OVERVIEW, ItemFields.OVERVIEW,
ItemFields.SORT_NAME, ItemFields.SORT_NAME,
ItemFields.MEDIA_SOURCE_COUNT, ItemFields.MEDIA_SOURCE_COUNT,
ItemFields.CAN_DELETE, ItemFields.CAN_DELETE,
) )
/**
* ItemFields for displaying items in rows such as in a [com.github.damontecres.wholphin.ui.cards.ItemRow] with [com.github.damontecres.wholphin.ui.cards.SeasonCard]
*/
val ItemRowFields = SlimItemFields + ItemFields.PRIMARY_IMAGE_ASPECT_RATIO
val HomeItemFields = val HomeItemFields =
listOf( listOf(
ItemFields.OVERVIEW, ItemFields.OVERVIEW,
@ -78,13 +82,13 @@ val HomeItemFields =
) )
val PhotoItemFields = val PhotoItemFields =
DefaultItemFields + DetailItemFields +
listOf( listOf(
ItemFields.WIDTH, ItemFields.WIDTH,
ItemFields.HEIGHT, ItemFields.HEIGHT,
) )
val ProgramItemFields = DefaultItemFields + listOf(ItemFields.CHANNEL_INFO) val ProgramItemFields = DetailItemFields + listOf(ItemFields.CHANNEL_INFO)
object Cards { object Cards {
const val HEIGHT_2X3_DP = 172 const val HEIGHT_2X3_DP = 172

View file

@ -38,7 +38,7 @@ fun ExtrasRow(
unplayedItemCount = -1, unplayedItemCount = -1,
playedPercentage = item?.playedPercentage ?: 0.0, playedPercentage = item?.playedPercentage ?: 0.0,
numberOfVersions = -1, numberOfVersions = -1,
aspectRatio = AspectRatios.FOUR_THREE, // TODO aspectRatio = item?.aspectRatio ?: AspectRatios.WIDE,
) )
}, },
modifier = modifier, modifier = modifier,

View file

@ -71,7 +71,6 @@ import com.github.damontecres.wholphin.util.GetArtistsHandler
import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler
import com.github.damontecres.wholphin.util.GetPersonsHandler import com.github.damontecres.wholphin.util.GetPersonsHandler
import com.github.damontecres.wholphin.util.LoadingState import com.github.damontecres.wholphin.util.LoadingState
import com.github.damontecres.wholphin.util.RequestHandler
import com.github.damontecres.wholphin.util.WholphinDispatchers import com.github.damontecres.wholphin.util.WholphinDispatchers
import com.github.damontecres.wholphin.util.successValue import com.github.damontecres.wholphin.util.successValue
import dagger.assisted.Assisted import dagger.assisted.Assisted
@ -476,13 +475,16 @@ class CollectionFolderViewModel
when (filter.override) { when (filter.override) {
GetItemsFilterOverride.ARTIST -> { GetItemsFilterOverride.ARTIST -> {
GetArtistsHandler.countMatching( GetArtistsHandler.countMatching(
createGetArtistsRequest(filter).copy( api = api,
enableImageTypes = null, request =
fields = null, createGetArtistsRequest(filter).copy(
nameLessThan = letter.toString(), enableImageTypes = null,
limit = 0, fields = null,
enableTotalRecordCount = true, nameLessThan = letter.toString(),
), limit = 0,
enableTotalRecordCount = true,
enableUserData = false,
),
) )
} }
@ -494,30 +496,25 @@ class CollectionFolderViewModel
GetItemsFilterOverride.NONE -> { GetItemsFilterOverride.NONE -> {
GetItemsRequestHandler.countMatching( GetItemsRequestHandler.countMatching(
createGetItemsRequest( api = api,
sortAndDirection = state.value.sortAndDirection, request =
recursive = recursive, createGetItemsRequest(
filter = filter, sortAndDirection = state.value.sortAndDirection,
).copy( recursive = recursive,
enableImageTypes = null, filter = filter,
fields = null, ).copy(
nameLessThan = letter.toString(), enableImageTypes = null,
limit = 0, fields = null,
enableTotalRecordCount = true, nameLessThan = letter.toString(),
), limit = 0,
enableTotalRecordCount = true,
enableUserData = false,
),
) )
} }
} }
} }
/**
* [request] must ask for the count, ie `limit = 0` and `enableTotalRecordCount = true`
*/
private suspend fun <T> RequestHandler<T>.countMatching(request: T): Int {
val result by execute(api, request)
return result.totalRecordCount
}
override fun setWatched( override fun setWatched(
position: Int, position: Int,
itemId: UUID, itemId: UUID,

View file

@ -149,16 +149,17 @@ class GenreViewModel
suspend fun positionOfLetter(letter: Char): Int = suspend fun positionOfLetter(letter: Char): Int =
withContext(WholphinDispatchers.IO) { withContext(WholphinDispatchers.IO) {
val request = GetGenresRequestHandler.countMatching(
GetGenresRequest( api = api,
parentId = itemId, request =
nameLessThan = letter.toString(), GetGenresRequest(
limit = 0, parentId = itemId,
enableTotalRecordCount = true, nameLessThan = letter.toString(),
includeItemTypes = includeItemTypes, limit = 0,
) enableTotalRecordCount = true,
val result by GetGenresRequestHandler.execute(api, request) includeItemTypes = includeItemTypes,
return@withContext result.totalRecordCount ),
)
} }
} }

View file

@ -120,17 +120,18 @@ class StudioViewModel
suspend fun positionOfLetter(letter: Char): Int = suspend fun positionOfLetter(letter: Char): Int =
withContext(WholphinDispatchers.IO) { withContext(WholphinDispatchers.IO) {
val request = GetStudiosRequestHandler.countMatching(
GetStudiosRequest( api = api,
userId = serverRepository.currentUser?.id, request =
parentId = itemId, GetStudiosRequest(
nameLessThan = letter.toString(), userId = serverRepository.currentUser?.id,
limit = 0, parentId = itemId,
enableTotalRecordCount = true, nameLessThan = letter.toString(),
includeItemTypes = includeItemTypes, limit = 0,
) enableTotalRecordCount = true,
val result by GetStudiosRequestHandler.execute(api, request) includeItemTypes = includeItemTypes,
return@withContext result.totalRecordCount ),
)
} }
} }

View file

@ -70,7 +70,7 @@ import com.github.damontecres.wholphin.services.MediaReportService
import com.github.damontecres.wholphin.services.MusicService import com.github.damontecres.wholphin.services.MusicService
import com.github.damontecres.wholphin.services.MusicServiceState import com.github.damontecres.wholphin.services.MusicServiceState
import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.cards.ItemCardImage import com.github.damontecres.wholphin.ui.cards.ItemCardImage
import com.github.damontecres.wholphin.ui.components.BasicDialog import com.github.damontecres.wholphin.ui.components.BasicDialog
import com.github.damontecres.wholphin.ui.components.ContextMenu import com.github.damontecres.wholphin.ui.components.ContextMenu
@ -225,7 +225,7 @@ class PlaylistViewModel
GetItemsRequest( GetItemsRequest(
parentId = itemId, parentId = itemId,
userId = user.id, userId = user.id,
fields = DefaultItemFields, fields = SlimItemFields,
sortBy = listOf(sortAndDirection.sort), sortBy = listOf(sortAndDirection.sort),
sortOrder = listOf(sortAndDirection.direction), sortOrder = listOf(sortAndDirection.direction),
), ),

View file

@ -26,7 +26,7 @@ import com.github.damontecres.wholphin.services.ThemeSongPlayer
import com.github.damontecres.wholphin.services.TrailerService import com.github.damontecres.wholphin.services.TrailerService
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.services.deleteItem import com.github.damontecres.wholphin.services.deleteItem
import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.ItemRowFields
import com.github.damontecres.wholphin.ui.launchDefault import com.github.damontecres.wholphin.ui.launchDefault
import com.github.damontecres.wholphin.ui.launchIO import com.github.damontecres.wholphin.ui.launchIO
import com.github.damontecres.wholphin.ui.letNotEmpty import com.github.damontecres.wholphin.ui.letNotEmpty
@ -168,7 +168,7 @@ class MovieViewModel
GetSimilarItemsRequest( GetSimilarItemsRequest(
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
itemId = itemId, itemId = itemId,
fields = SlimItemFields, fields = ItemRowFields,
limit = 25, limit = 25,
), ),
).content.items ).content.items

View file

@ -58,7 +58,7 @@ import com.github.damontecres.wholphin.services.MusicService
import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.ItemRowFields
import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle
import com.github.damontecres.wholphin.ui.cards.ExtrasRow import com.github.damontecres.wholphin.ui.cards.ExtrasRow
@ -211,7 +211,7 @@ class AlbumViewModel
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
albumIds = listOf(itemId), albumIds = listOf(itemId),
parentId = null, parentId = null,
fields = DefaultItemFields, fields = ItemRowFields,
recursive = true, recursive = true,
includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO), includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO),
) )
@ -563,7 +563,7 @@ fun AlbumDetailsPage(
item = item, item = item,
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
aspectRatio = AspectRatios.WIDE, aspectRatio = item?.aspectRatio ?: AspectRatios.WIDE,
played = item?.played ?: false, played = item?.played ?: false,
playPercent = item?.data?.userData?.playedPercentage ?: 0.0, playPercent = item?.data?.userData?.playedPercentage ?: 0.0,
favorite = item?.favorite ?: false, favorite = item?.favorite ?: false,

View file

@ -54,7 +54,7 @@ import com.github.damontecres.wholphin.services.MusicService
import com.github.damontecres.wholphin.services.NavigationManager import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.ui.AspectRatios import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.ItemRowFields
import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle import com.github.damontecres.wholphin.ui.cards.BannerCardWithTitle
import com.github.damontecres.wholphin.ui.cards.ItemRow import com.github.damontecres.wholphin.ui.cards.ItemRow
@ -157,7 +157,7 @@ class ArtistViewModel
GetItemsRequest( GetItemsRequest(
albumArtistIds = listOf(itemId), albumArtistIds = listOf(itemId),
recursive = true, recursive = true,
fields = DefaultItemFields, fields = SlimItemFields,
includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM), includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM),
sortBy = sortBy =
listOf( listOf(
@ -174,7 +174,7 @@ class ArtistViewModel
GetItemsRequest( GetItemsRequest(
contributingArtistIds = listOf(itemId), contributingArtistIds = listOf(itemId),
recursive = true, recursive = true,
fields = DefaultItemFields, fields = SlimItemFields,
includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM), includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM),
sortBy = sortBy =
listOf( listOf(
@ -208,7 +208,7 @@ class ArtistViewModel
val request = val request =
GetItemsRequest( GetItemsRequest(
artistIds = listOf(itemId), artistIds = listOf(itemId),
fields = DefaultItemFields, fields = SlimItemFields,
recursive = true, recursive = true,
includeItemTypes = listOf(BaseItemKind.AUDIO), includeItemTypes = listOf(BaseItemKind.AUDIO),
minCommunityRating = 1.0, minCommunityRating = 1.0,
@ -266,7 +266,7 @@ class ArtistViewModel
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
artistIds = listOf(itemId), artistIds = listOf(itemId),
parentId = null, parentId = null,
fields = DefaultItemFields, fields = ItemRowFields,
recursive = true, recursive = true,
includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO), includeItemTypes = listOf(BaseItemKind.MUSIC_VIDEO),
) )
@ -671,7 +671,7 @@ fun ArtistDetailsPage(
item = item, item = item,
onClick = onClick, onClick = onClick,
onLongClick = onLongClick, onLongClick = onLongClick,
aspectRatio = AspectRatios.WIDE, aspectRatio = item?.aspectRatio ?: AspectRatios.WIDE,
played = item?.played ?: false, played = item?.played ?: false,
playPercent = item?.data?.userData?.playedPercentage ?: 0.0, playPercent = item?.data?.userData?.playedPercentage ?: 0.0,
favorite = item?.favorite ?: false, favorite = item?.favorite ?: false,

View file

@ -2,7 +2,7 @@ package com.github.damontecres.wholphin.ui.detail.music
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.github.damontecres.wholphin.ui.DefaultItemFields import com.github.damontecres.wholphin.ui.DetailItemFields
import com.github.damontecres.wholphin.util.ApiRequestPager import com.github.damontecres.wholphin.util.ApiRequestPager
import com.github.damontecres.wholphin.util.GetItemsRequestHandler import com.github.damontecres.wholphin.util.GetItemsRequestHandler
import org.jellyfin.sdk.api.client.ApiClient import org.jellyfin.sdk.api.client.ApiClient
@ -19,7 +19,7 @@ suspend fun ViewModel.getPagerForAlbum(
GetItemsRequest( GetItemsRequest(
parentId = albumId, parentId = albumId,
includeItemTypes = listOf(BaseItemKind.AUDIO), includeItemTypes = listOf(BaseItemKind.AUDIO),
fields = DefaultItemFields, fields = DetailItemFields,
sortBy = sortBy =
listOf( listOf(
ItemSortBy.PARENT_INDEX_NUMBER, ItemSortBy.PARENT_INDEX_NUMBER,
@ -39,7 +39,7 @@ suspend fun ViewModel.getPagerForArtist(
artistIds = listOf(artistId), artistIds = listOf(artistId),
recursive = true, recursive = true,
includeItemTypes = listOf(BaseItemKind.AUDIO), includeItemTypes = listOf(BaseItemKind.AUDIO),
fields = DefaultItemFields, fields = DetailItemFields,
// TODO better sort // TODO better sort
sortBy = sortBy =
listOf( listOf(
@ -60,7 +60,7 @@ suspend fun ViewModel.getPagerForPlaylist(
parentId = playlistId, parentId = playlistId,
recursive = true, recursive = true,
includeItemTypes = listOf(BaseItemKind.AUDIO), includeItemTypes = listOf(BaseItemKind.AUDIO),
fields = DefaultItemFields, fields = DetailItemFields,
sortBy = sortBy =
listOf( listOf(
ItemSortBy.DEFAULT, ItemSortBy.DEFAULT,

View file

@ -27,7 +27,7 @@ import com.github.damontecres.wholphin.services.ThemeSongPlayer
import com.github.damontecres.wholphin.services.TrailerService import com.github.damontecres.wholphin.services.TrailerService
import com.github.damontecres.wholphin.services.UserPreferencesService import com.github.damontecres.wholphin.services.UserPreferencesService
import com.github.damontecres.wholphin.services.deleteItem import com.github.damontecres.wholphin.services.deleteItem
import com.github.damontecres.wholphin.ui.SlimItemFields import com.github.damontecres.wholphin.ui.ItemRowFields
import com.github.damontecres.wholphin.ui.equalsNotNull import com.github.damontecres.wholphin.ui.equalsNotNull
import com.github.damontecres.wholphin.ui.gt import com.github.damontecres.wholphin.ui.gt
import com.github.damontecres.wholphin.ui.launchDefault import com.github.damontecres.wholphin.ui.launchDefault
@ -232,7 +232,7 @@ class SeriesViewModel
GetSimilarItemsRequest( GetSimilarItemsRequest(
userId = serverRepository.currentUser?.id, userId = serverRepository.currentUser?.id,
itemId = seriesId, itemId = seriesId,
fields = SlimItemFields, fields = ItemRowFields,
limit = 25, limit = 25,
), ),
).content.items ).content.items

View file

@ -131,6 +131,19 @@ sealed interface RequestHandler<T> {
api: ApiClient, api: ApiClient,
request: T, request: T,
): Response<BaseItemDtoQueryResult> ): Response<BaseItemDtoQueryResult>
/**
* Count the total number of possible results for the request.
*
* [request] should be efficient and use `limit = 0` and `enableTotalRecordCount = true`
*/
suspend fun countMatching(
api: ApiClient,
request: T,
): Int {
val result by execute(api, request)
return result.totalRecordCount
}
} }
@Serializable @Serializable