Add more sort options to different types (#1488)

## Description
Adds more sorting options, notably premier date & ratings, to different
media types.

### Related issues
Closes #1417
Closes #1429
Replaces #1420

### Testing
Emulator on movie genre's items and music video libraries

## Screenshots
N/A

## AI or LLM usage
None
This commit is contained in:
Damontecres 2026-05-30 16:56:33 -04:00 • committed by GitHub
parent 81e5f31401
commit 273a6138c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 63 additions and 0 deletions

View file

@ -24,6 +24,7 @@ import kotlinx.serialization.Transient
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.extensions.ticks
import java.util.Locale
import java.util.UUID
@ -283,6 +284,7 @@ fun createGenreDestination(
parentId: UUID,
parentName: String?,
includeItemTypes: List<BaseItemKind>?,
collectionType: CollectionType,
) = Destination.FilteredCollection(
itemId = parentId,
parentType = BaseItemKind.GENRE,
@ -301,6 +303,7 @@ fun createGenreDestination(
useSavedLibraryDisplayInfo = false,
),
recursive = true,
collectionType = collectionType,
)
fun createStudioDestination(
@ -327,6 +330,7 @@ fun createStudioDestination(
useSavedLibraryDisplayInfo = false,
),
recursive = true,
collectionType = CollectionType.UNKNOWN,
)
val BaseItem.studioNames get() = data.studios?.mapNotNull { it.name }.orEmpty()

View file

@ -693,6 +693,9 @@ class HomeSettingsService
listOf(it)
}
},
collectionType =
library?.collectionType
?: CollectionType.UNKNOWN,
),
)
}

View file

@ -51,6 +51,7 @@ import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.userLibraryApi
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.ImageType
import org.jellyfin.sdk.model.api.ItemFields
import org.jellyfin.sdk.model.api.ItemSortBy
@ -255,6 +256,7 @@ data class Genre(
fun GenreCardGrid(
itemId: UUID,
includeItemTypes: List<BaseItemKind>?,
collectionType: CollectionType,
modifier: Modifier = Modifier,
initialPosition: Int = 0,
viewModel: GenreViewModel =
@ -308,6 +310,7 @@ fun GenreCardGrid(
parentId = itemId,
parentName = item.title,
includeItemTypes = includeItemTypes,
collectionType = collectionType,
),
)
},

View file

@ -1,8 +1,12 @@
package com.github.damontecres.wholphin.ui.data
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.github.damontecres.wholphin.R
import kotlinx.serialization.Serializable
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.ItemSortBy
import org.jellyfin.sdk.model.api.SortOrder
@ -46,6 +50,7 @@ val SeriesSortOptions =
ItemSortBy.DATE_LAST_CONTENT_ADDED,
ItemSortBy.DATE_PLAYED,
ItemSortBy.COMMUNITY_RATING,
ItemSortBy.CRITIC_RATING,
ItemSortBy.OFFICIAL_RATING,
ItemSortBy.RANDOM,
)
@ -53,19 +58,27 @@ val SeriesSortOptions =
val EpisodeSortOptions =
listOf(
ItemSortBy.SORT_NAME,
ItemSortBy.PREMIERE_DATE,
ItemSortBy.DATE_CREATED,
ItemSortBy.DATE_PLAYED,
ItemSortBy.AIRED_EPISODE_ORDER,
ItemSortBy.COMMUNITY_RATING,
ItemSortBy.CRITIC_RATING,
ItemSortBy.OFFICIAL_RATING,
ItemSortBy.RUNTIME,
ItemSortBy.PLAY_COUNT,
ItemSortBy.RANDOM,
)
val VideoSortOptions =
listOf(
ItemSortBy.SORT_NAME,
ItemSortBy.PREMIERE_DATE,
ItemSortBy.DATE_CREATED,
ItemSortBy.DATE_PLAYED,
ItemSortBy.COMMUNITY_RATING,
ItemSortBy.CRITIC_RATING,
ItemSortBy.OFFICIAL_RATING,
ItemSortBy.RUNTIME,
ItemSortBy.PLAY_COUNT,
ItemSortBy.RANDOM,
@ -80,6 +93,7 @@ val PlaylistSortOptions =
ItemSortBy.DATE_PLAYED,
ItemSortBy.COMMUNITY_RATING,
ItemSortBy.CRITIC_RATING,
ItemSortBy.OFFICIAL_RATING,
ItemSortBy.RUNTIME,
ItemSortBy.PLAY_COUNT,
ItemSortBy.RANDOM,
@ -180,3 +194,31 @@ fun getStringRes(sort: ItemSortBy): Int =
else -> throw IllegalArgumentException("Unsupported sort option: $sort")
}
@Composable
fun rememberSortOptions(collectionType: CollectionType): List<ItemSortBy> =
remember(collectionType) {
when (collectionType) {
CollectionType.MOVIES -> MovieSortOptions
CollectionType.TVSHOWS -> SeriesSortOptions
CollectionType.MUSIC -> AlbumSortOptions
CollectionType.BOXSETS -> BoxSetSortOptions
else -> VideoSortOptions
}
}
@Composable
fun rememberSortOptions(type: BaseItemKind): List<ItemSortBy> =
remember(type) {
when (type) {
BaseItemKind.MOVIE -> MovieSortOptions
BaseItemKind.SERIES -> SeriesSortOptions
BaseItemKind.SEASON -> SeriesSortOptions
BaseItemKind.EPISODE -> EpisodeSortOptions
BaseItemKind.AUDIO -> SongSortOptions
BaseItemKind.MUSIC_ALBUM -> AlbumSortOptions
BaseItemKind.MUSIC_ARTIST -> ArtistSortOptions
BaseItemKind.BOX_SET -> BoxSetSortOptions
else -> VideoSortOptions
}
}

View file

@ -36,6 +36,7 @@ import com.github.damontecres.wholphin.ui.logTab
import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
@Composable
fun CollectionFolderMovie(
@ -173,6 +174,7 @@ fun CollectionFolderMovie(
GenreCardGrid(
itemId = destination.itemId,
includeItemTypes = listOf(BaseItemKind.MOVIE),
collectionType = CollectionType.MOVIES,
modifier =
Modifier
.fillMaxSize()

View file

@ -53,6 +53,7 @@ import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.request.GetItemsRequest
import java.util.UUID
@ -267,6 +268,7 @@ fun CollectionFolderMusic(
GenreCardGrid(
itemId = destination.itemId,
includeItemTypes = listOf(BaseItemKind.MUSIC_ALBUM),
collectionType = CollectionType.MUSIC,
modifier =
Modifier
.fillMaxSize()

View file

@ -39,6 +39,7 @@ import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
import com.github.damontecres.wholphin.ui.tryRequestFocus
import org.jellyfin.sdk.model.api.BaseItemKind
import org.jellyfin.sdk.model.api.CollectionType
@Composable
fun CollectionFolderTv(
@ -148,6 +149,7 @@ fun CollectionFolderTv(
GenreCardGrid(
itemId = destination.itemId,
includeItemTypes = listOf(BaseItemKind.SERIES),
collectionType = CollectionType.TVSHOWS,
modifier =
Modifier
.fillMaxSize()

View file

@ -73,6 +73,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.CollectionType
import org.jellyfin.sdk.model.api.MediaType
import timber.log.Timber
import java.util.UUID
@ -299,6 +300,7 @@ fun HomeRowGrid(
includeItemTypes = null,
modifier = Modifier.fillMaxSize(),
initialPosition = destination.initialPosition,
collectionType = CollectionType.UNKNOWN,
)
}

View file

@ -106,6 +106,7 @@ sealed class Destination(
val parentType: BaseItemKind,
val filter: CollectionFolderFilter,
val recursive: Boolean,
val collectionType: CollectionType,
) : Destination(false)
@Serializable

View file

@ -13,6 +13,7 @@ import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.components.ItemGrid
import com.github.damontecres.wholphin.ui.components.LicenseInfo
import com.github.damontecres.wholphin.ui.data.MovieSortOptions
import com.github.damontecres.wholphin.ui.data.rememberSortOptions
import com.github.damontecres.wholphin.ui.detail.CollectionFolderGeneric
import com.github.damontecres.wholphin.ui.detail.CollectionFolderLiveTv
import com.github.damontecres.wholphin.ui.detail.CollectionFolderMovie
@ -286,6 +287,7 @@ fun DestinationContent(
BaseItemKind.STUDIO -> DefaultForStudiosFilterOptions
else -> throw IllegalArgumentException("Unsupported parentType ${destination.parentType}")
},
sortOptions = rememberSortOptions(destination.collectionType),
modifier = modifier,
)
}