Variety of UI changes for grids, home page order, & tv guide (#272)

## Details
This PR ended up being larger than I meant. It contains some UI changes
and code organization.

## TV & DVR
- Uses the "Recordings" library position to order "Recently added in
Recordings" instead of Live TV position
- The times at the top of the TV guide are more distinguishable from
each other
- Removes the duplicate title on the Live TV->Recordings tab

## Other libraries
- Bare-bone support for "Music Video" libraries. Full support for "Music
Video" is work-in-progress in #267, but the libraries should be
browseable now.
- Bare-bone support for "Other" (aka Mixed Movies & TV Shows) libraries.
Note: this type of library is considered [broken and
deprecated](https://jellyfin.org/docs/general/server/media/mixed-movies-and-shows),
so this won't be expanded any further


## Grids
Updates various grid types to use poster vs wide cards. For example,
Favorite TV Episodes will use episode images in a wide card now.

## Issues
Closes #249 
Closes #271
This commit is contained in:
damontecres 2025-11-20 17:00:11 -05:00 committed by GitHub
parent 39ad7e564f
commit 45567bf4eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 287 additions and 161 deletions

View file

@ -4,11 +4,13 @@ import android.content.Context
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
import com.github.damontecres.wholphin.data.model.NavPinType
import com.github.damontecres.wholphin.ui.nav.Destination
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
import com.github.damontecres.wholphin.util.supportedCollectionTypes
import dagger.hilt.android.qualifiers.ApplicationContext
import org.jellyfin.sdk.api.client.ApiClient
import org.jellyfin.sdk.api.client.extensions.liveTvApi
import org.jellyfin.sdk.api.client.extensions.userViewsApi
import org.jellyfin.sdk.model.api.CollectionType
import javax.inject.Inject
@ -24,21 +26,33 @@ class NavDrawerItemRepository
private val serverPreferencesDao: ServerPreferencesDao,
) {
suspend fun getNavDrawerItems(): List<NavDrawerItem> {
val user = serverRepository.currentUser
val user = serverRepository.currentUser.value
val userViews =
api.userViewsApi
.getUserViews(userId = user.value?.id)
.getUserViews(userId = user?.id)
.content.items
val recordingFolders =
api.liveTvApi
.getRecordingFolders(userId = user?.id)
.content.items
.map { it.id }
.toSet()
val builtins = listOf(NavDrawerItem.Favorites)
val libraries =
userViews
.filter { it.collectionType in supportedCollectionTypes }
.filter { it.collectionType in supportedCollectionTypes || it.id in recordingFolders }
.map {
val destination =
if (it.id in recordingFolders) {
Destination.Recordings(it.id)
} else {
BaseItem.from(it, api).destination()
}
ServerNavDrawerItem(
itemId = it.id,
name = it.name ?: it.id.toString(),
destination = BaseItem.from(it, api).destination(),
destination = destination,
type = it.collectionType ?: CollectionType.UNKNOWN,
)
}

View file

@ -42,6 +42,7 @@ import com.github.damontecres.wholphin.data.model.LibraryDisplayInfo
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.services.FavoriteWatchManager
import com.github.damontecres.wholphin.services.NavigationManager
import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.OneTimeLaunchedEffect
import com.github.damontecres.wholphin.ui.SlimItemFields
import com.github.damontecres.wholphin.ui.cards.GridCard
@ -96,11 +97,14 @@ class CollectionFolderViewModel
val sortAndDirection = MutableLiveData<SortAndDirection>()
val filter = MutableLiveData<GetItemsFilter>(GetItemsFilter())
private var useSeriesForPrimary: Boolean = true
fun init(
itemId: String,
initialSortAndDirection: SortAndDirection?,
recursive: Boolean,
filter: GetItemsFilter,
useSeriesForPrimary: Boolean,
): Job =
viewModelScope.launch(
LoadingExceptionHandler(
@ -108,6 +112,7 @@ class CollectionFolderViewModel
context.getString(R.string.error_loading_collection, itemId),
) + Dispatchers.IO,
) {
this@CollectionFolderViewModel.useSeriesForPrimary = useSeriesForPrimary
this@CollectionFolderViewModel.itemId = itemId
itemId?.toUUIDOrNull()?.let {
fetchItem(it)
@ -121,7 +126,7 @@ class CollectionFolderViewModel
} ?: SortAndDirection.DEFAULT
)
loadResults(sortAndDirection, recursive, filter)
loadResults(sortAndDirection, recursive, filter, useSeriesForPrimary)
}
fun onSortChange(
@ -141,13 +146,14 @@ class CollectionFolderViewModel
libraryDisplayInfoDao.saveItem(libraryDisplayInfo)
}
}
loadResults(sortAndDirection, recursive, filter)
loadResults(sortAndDirection, recursive, filter, useSeriesForPrimary)
}
private fun loadResults(
sortAndDirection: SortAndDirection,
recursive: Boolean,
filter: GetItemsFilter,
useSeriesForPrimary: Boolean,
) {
viewModelScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
@ -156,7 +162,7 @@ class CollectionFolderViewModel
this@CollectionFolderViewModel.sortAndDirection.value = sortAndDirection
this@CollectionFolderViewModel.filter.value = filter
}
val newPager = createPager(sortAndDirection, recursive, filter)
val newPager = createPager(sortAndDirection, recursive, filter, useSeriesForPrimary)
newPager.init()
if (newPager.isNotEmpty()) newPager.getBlocking(0)
withContext(Dispatchers.Main) {
@ -170,6 +176,7 @@ class CollectionFolderViewModel
sortAndDirection: SortAndDirection,
recursive: Boolean,
filter: GetItemsFilter,
useSeriesForPrimary: Boolean,
): ApiRequestPager<out Any> {
val item = item.value
return when (filter.override) {
@ -228,7 +235,7 @@ class CollectionFolderViewModel
request,
GetItemsRequestHandler,
viewModelScope,
useSeriesForPrimary = true,
useSeriesForPrimary = useSeriesForPrimary,
)
newPager
}
@ -246,7 +253,7 @@ class CollectionFolderViewModel
request,
GetPersonsHandler,
viewModelScope,
useSeriesForPrimary = true,
useSeriesForPrimary = useSeriesForPrimary,
)
newPager
}
@ -344,10 +351,17 @@ fun CollectionFolderGrid(
showTitle: Boolean = true,
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
params: CollectionFolderGridParameters = CollectionFolderGridParameters(),
useSeriesForPrimary: Boolean = true,
) {
val context = LocalContext.current
OneTimeLaunchedEffect {
viewModel.init(itemId, initialSortAndDirection, recursive, initialFilter)
viewModel.init(
itemId,
initialSortAndDirection,
recursive,
initialFilter,
useSeriesForPrimary,
)
}
val sortAndDirection by viewModel.sortAndDirection.observeAsState()
val filter by viewModel.filter.observeAsState(initialFilter)
@ -538,4 +552,52 @@ data class CollectionFolderGridParameters(
modifier = mod,
)
},
)
) {
companion object {
val POSTER =
CollectionFolderGridParameters(
columns = 6,
spacing = 16.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.FillBounds,
imageAspectRatio = AspectRatios.TALL,
modifier = mod,
)
},
)
val WIDE =
CollectionFolderGridParameters(
columns = 4,
spacing = 24.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.Crop,
imageAspectRatio = AspectRatios.WIDE,
modifier = mod,
)
},
)
val SQUARE =
CollectionFolderGridParameters(
columns = 6,
spacing = 16.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.FillBounds,
imageAspectRatio = AspectRatios.SQUARE,
modifier = mod,
)
},
)
}
}

View file

@ -7,14 +7,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.cards.GridCard
import com.github.damontecres.wholphin.ui.components.CollectionFolderGrid
import com.github.damontecres.wholphin.ui.components.CollectionFolderGridParameters
import com.github.damontecres.wholphin.ui.data.MovieSortOptions
@ -32,21 +29,6 @@ fun CollectionFolderBoxSet(
preferencesViewModel: PreferencesViewModel = hiltViewModel(),
) {
var showHeader by remember { mutableStateOf(true) }
val params =
CollectionFolderGridParameters(
columns = 6,
spacing = 16.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.FillBounds,
imageAspectRatio = AspectRatios.TALL,
modifier = mod,
)
},
)
CollectionFolderGrid(
preferences = preferences,
onClickItem = { _, item -> preferencesViewModel.navigationManager.navigateTo(item.destination()) },
@ -61,6 +43,6 @@ fun CollectionFolderBoxSet(
positionCallback = { columns, position ->
showHeader = position < columns
},
params = params,
params = CollectionFolderGridParameters.POSTER,
)
}

View file

@ -7,14 +7,10 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.cards.GridCard
import com.github.damontecres.wholphin.ui.components.CollectionFolderGrid
import com.github.damontecres.wholphin.ui.components.CollectionFolderGridParameters
import com.github.damontecres.wholphin.ui.data.VideoSortOptions
@ -25,7 +21,7 @@ import java.util.UUID
fun CollectionFolderGeneric(
preferences: UserPreferences,
itemId: UUID,
item: BaseItem?,
usePosters: Boolean,
recursive: Boolean,
modifier: Modifier = Modifier,
filter: GetItemsFilter = GetItemsFilter(),
@ -33,20 +29,13 @@ fun CollectionFolderGeneric(
) {
var showHeader by remember { mutableStateOf(true) }
val params =
CollectionFolderGridParameters(
columns = 4,
spacing = 24.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.Crop,
imageAspectRatio = AspectRatios.WIDE,
modifier = mod,
)
},
)
remember(usePosters) {
if (usePosters) {
CollectionFolderGridParameters.POSTER
} else {
CollectionFolderGridParameters.WIDE
}
}
CollectionFolderGrid(
preferences = preferences,
onClickItem = { _, item -> preferencesViewModel.navigationManager.navigateTo(item.destination()) },

View file

@ -160,7 +160,7 @@ fun CollectionFolderLiveTv(
onClickItem = onClickItem,
itemId = folders[folderIndex].id,
initialFilter = GetItemsFilter(),
showTitle = showHeader,
showTitle = false,
recursive = false,
sortOptions = VideoSortOptions,
modifier =

View file

@ -7,14 +7,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.github.damontecres.wholphin.data.model.BaseItem
import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.AspectRatios
import com.github.damontecres.wholphin.ui.cards.GridCard
import com.github.damontecres.wholphin.ui.components.CollectionFolderGrid
import com.github.damontecres.wholphin.ui.components.CollectionFolderGridParameters
import com.github.damontecres.wholphin.ui.data.PlaylistSortOptions
@ -32,21 +29,6 @@ fun CollectionFolderPlaylist(
preferencesViewModel: PreferencesViewModel = hiltViewModel(),
) {
var showHeader by remember { mutableStateOf(true) }
val params =
CollectionFolderGridParameters(
columns = 6,
spacing = 16.dp,
cardContent = { item, onClick, onLongClick, mod ->
GridCard(
item = item,
onClick = onClick,
onLongClick = onLongClick,
imageContentScale = ContentScale.FillBounds,
imageAspectRatio = AspectRatios.SQUARE,
modifier = mod,
)
},
)
CollectionFolderGrid(
preferences = preferences,
onClickItem = { _, item -> preferencesViewModel.navigationManager.navigateTo(item.destination()) },
@ -61,6 +43,6 @@ fun CollectionFolderPlaylist(
positionCallback = { columns, position ->
showHeader = position < columns
},
params = params,
params = CollectionFolderGridParameters.SQUARE,
)
}

View file

@ -0,0 +1,46 @@
package com.github.damontecres.wholphin.ui.detail
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.components.CollectionFolderGrid
import com.github.damontecres.wholphin.ui.components.CollectionFolderGridParameters
import com.github.damontecres.wholphin.ui.data.MovieSortOptions
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
import java.util.UUID
@Composable
fun CollectionFolderRecordings(
preferences: UserPreferences,
itemId: UUID,
recursive: Boolean,
modifier: Modifier = Modifier,
filter: GetItemsFilter = GetItemsFilter(),
preferencesViewModel: PreferencesViewModel = hiltViewModel(),
) {
var showHeader by remember { mutableStateOf(true) }
CollectionFolderGrid(
preferences = preferences,
onClickItem = { _, item -> preferencesViewModel.navigationManager.navigateTo(item.destination()) },
itemId = itemId,
initialFilter = filter,
showTitle = showHeader,
recursive = recursive,
sortOptions = MovieSortOptions,
modifier =
modifier
.padding(start = 16.dp),
positionCallback = { columns, position ->
showHeader = position < columns
},
params = CollectionFolderGridParameters.POSTER,
)
}

View file

@ -28,6 +28,7 @@ import com.github.damontecres.wholphin.data.model.GetItemsFilter
import com.github.damontecres.wholphin.data.model.GetItemsFilterOverride
import com.github.damontecres.wholphin.preferences.UserPreferences
import com.github.damontecres.wholphin.ui.components.CollectionFolderGrid
import com.github.damontecres.wholphin.ui.components.CollectionFolderGridParameters
import com.github.damontecres.wholphin.ui.components.ErrorMessage
import com.github.damontecres.wholphin.ui.components.TabRow
import com.github.damontecres.wholphin.ui.data.EpisodeSortOptions
@ -163,6 +164,8 @@ fun FavoritesPage(
showTitle = false,
recursive = true,
sortOptions = EpisodeSortOptions,
params = CollectionFolderGridParameters.WIDE,
useSeriesForPrimary = false,
modifier =
Modifier
.padding(start = 16.dp)
@ -186,6 +189,7 @@ fun FavoritesPage(
showTitle = false,
recursive = true,
sortOptions = VideoSortOptions,
params = CollectionFolderGridParameters.WIDE,
modifier =
Modifier
.padding(start = 16.dp)
@ -209,6 +213,7 @@ fun FavoritesPage(
showTitle = false,
recursive = true,
sortOptions = VideoSortOptions,
params = CollectionFolderGridParameters.SQUARE,
modifier =
Modifier
.padding(start = 16.dp)

View file

@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@ -453,8 +454,16 @@ fun TvGuideGridContent(
Box(
modifier =
Modifier
// Intentionally set background twice
// The second is padded so there are gaps between times
// The first covers those gaps
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = 2.dp)
.fillMaxSize()
.background(MaterialTheme.colorScheme.surface),
.background(
MaterialTheme.colorScheme.surfaceVariant,
shape = RoundedCornerShape(4.dp),
),
) {
val differentDay =
start.toLocalDate() !=
@ -472,7 +481,8 @@ fun TvGuideGridContent(
)
Text(
text = time.toString(),
modifier = Modifier.background(MaterialTheme.colorScheme.background),
color = MaterialTheme.colorScheme.onSurface,
modifier = Modifier.padding(2.dp),
)
}
}

View file

@ -217,14 +217,12 @@ class HomeViewModel
views.items
.filter {
it.id in includedIds && it.id !in excluded &&
it.collectionType in supportedLatestCollectionTypes
// Exclude Live TV because a recording folder view will be used instead
it.collectionType != CollectionType.LIVETV
}.mapNotNull { view ->
val title =
if (view.collectionType == CollectionType.LIVETV) {
context.getString(R.string.recently_recorded)
} else {
view.name?.let { context.getString(R.string.recently_added_in, it) }
} ?: context.getString(R.string.recently_added)
view.name?.let { context.getString(R.string.recently_added_in, it) }
?: context.getString(R.string.recently_added)
val viewId =
if (view.collectionType == CollectionType.LIVETV) {
api.liveTvApi

View file

@ -69,6 +69,11 @@ sealed class Destination(
"MediaItem(itemId=$itemId, type=$type, seasonEpisode=$seasonEpisode, collectionType=${item?.data?.collectionType})"
}
@Serializable
data class Recordings(
val itemId: UUID,
) : Destination()
@Serializable
data class Playback(
val itemId: UUID,

View file

@ -11,6 +11,7 @@ import com.github.damontecres.wholphin.ui.detail.CollectionFolderGeneric
import com.github.damontecres.wholphin.ui.detail.CollectionFolderLiveTv
import com.github.damontecres.wholphin.ui.detail.CollectionFolderMovie
import com.github.damontecres.wholphin.ui.detail.CollectionFolderPlaylist
import com.github.damontecres.wholphin.ui.detail.CollectionFolderRecordings
import com.github.damontecres.wholphin.ui.detail.CollectionFolderTv
import com.github.damontecres.wholphin.ui.detail.DebugPage
import com.github.damontecres.wholphin.ui.detail.FavoritesPage
@ -107,97 +108,40 @@ fun DestinationContent(
modifier,
)
BaseItemKind.COLLECTION_FOLDER -> {
when (destination.item?.data?.collectionType) {
CollectionType.TVSHOWS ->
CollectionFolderTv(
preferences,
destination,
modifier,
)
CollectionType.MOVIES ->
CollectionFolderMovie(
preferences,
destination,
modifier,
)
CollectionType.BOXSETS ->
CollectionFolderBoxSet(
preferences,
destination.itemId,
destination.item,
false,
modifier,
)
else ->
CollectionFolderGeneric(
preferences,
destination.itemId,
destination.item,
false,
modifier,
)
}
}
BaseItemKind.PLAYLIST ->
PlaylistDetails(
destination = destination,
modifier = modifier,
)
BaseItemKind.USER_VIEW ->
when (destination.item?.data?.collectionType) {
CollectionType.TVSHOWS ->
CollectionFolderTv(
preferences,
destination,
modifier,
)
CollectionType.MOVIES ->
CollectionFolderMovie(
preferences,
destination,
modifier,
)
CollectionType.LIVETV ->
CollectionFolderLiveTv(
preferences,
destination,
modifier,
)
CollectionType.PLAYLISTS ->
CollectionFolderPlaylist(
preferences,
destination.itemId,
destination.item,
true,
modifier,
)
else ->
CollectionFolderGeneric(
preferences,
destination.itemId,
destination.item,
true,
modifier,
)
}
BaseItemKind.COLLECTION_FOLDER ->
CollectionFolder(
preferences = preferences,
destination = destination,
collectionType = destination.item?.data?.collectionType,
usePostersOverride = null,
recursiveOverride = null,
modifier = modifier,
)
BaseItemKind.FOLDER ->
CollectionFolderGeneric(
preferences,
destination.itemId,
destination.item,
false,
modifier,
CollectionFolder(
preferences = preferences,
destination = destination,
collectionType = destination.item?.data?.collectionType,
usePostersOverride = true,
recursiveOverride = null,
modifier = modifier,
)
BaseItemKind.USER_VIEW ->
CollectionFolder(
preferences = preferences,
destination = destination,
collectionType = destination.item?.data?.collectionType,
usePostersOverride = null,
recursiveOverride = true,
modifier = modifier,
)
BaseItemKind.PERSON ->
@ -217,12 +161,20 @@ fun DestinationContent(
CollectionFolderGeneric(
preferences = preferences,
itemId = destination.itemId,
item = null,
filter = destination.filter,
recursive = destination.recursive,
usePosters = true,
modifier = modifier,
)
is Destination.Recordings ->
CollectionFolderRecordings(
preferences,
destination.itemId,
false,
modifier,
)
is Destination.ItemGrid ->
ItemGrid(
destination,
@ -248,3 +200,81 @@ fun DestinationContent(
Destination.Debug -> DebugPage(preferences, modifier)
}
}
@Composable
fun CollectionFolder(
preferences: UserPreferences,
destination: Destination.MediaItem,
collectionType: CollectionType?,
usePostersOverride: Boolean?,
recursiveOverride: Boolean?,
modifier: Modifier = Modifier,
) {
when (collectionType) {
CollectionType.TVSHOWS ->
CollectionFolderTv(
preferences,
destination,
modifier,
)
CollectionType.MOVIES ->
CollectionFolderMovie(
preferences,
destination,
modifier,
)
CollectionType.BOXSETS ->
CollectionFolderBoxSet(
preferences,
destination.itemId,
destination.item,
false,
modifier,
)
CollectionType.PLAYLISTS ->
CollectionFolderPlaylist(
preferences,
destination.itemId,
destination.item,
true,
modifier,
)
CollectionType.LIVETV ->
CollectionFolderLiveTv(
preferences = preferences,
destination = destination,
modifier = modifier,
)
CollectionType.HOMEVIDEOS,
CollectionType.MUSICVIDEOS,
CollectionType.MUSIC,
CollectionType.BOOKS,
CollectionType.PHOTOS,
->
CollectionFolderGeneric(
preferences,
destination.itemId,
usePosters = usePostersOverride ?: false,
recursive = recursiveOverride ?: false,
modifier = modifier,
)
CollectionType.FOLDERS,
CollectionType.TRAILERS,
CollectionType.UNKNOWN,
null,
->
CollectionFolderGeneric(
preferences,
destination.itemId,
usePosters = usePostersOverride ?: false,
recursive = recursiveOverride ?: false,
modifier = modifier,
)
}
}

View file

@ -29,6 +29,9 @@ val supportedCollectionTypes =
CollectionType.PLAYLISTS,
CollectionType.BOXSETS,
CollectionType.LIVETV,
CollectionType.MUSICVIDEOS,
CollectionType.FOLDERS,
null, // Mixed
)
val supportedPlayableTypes =