Support collections

This commit is contained in:
Damontecres 2025-10-13 21:58:55 -04:00
parent a93f183f5f
commit b40db0074f
No known key found for this signature in database
11 changed files with 64 additions and 14 deletions

View file

@ -98,7 +98,7 @@ fun GridCard(
.fillMaxWidth(),
) {
Text(
text = item?.name ?: "",
text = item?.title ?: "",
maxLines = 1,
textAlign = TextAlign.Center,
overflow = TextOverflow.Ellipsis,
@ -109,7 +109,7 @@ fun GridCard(
.enableMarquee(focusedAfterDelay),
)
Text(
text = item?.data?.productionYear?.toString() ?: "",
text = item?.subtitle ?: "",
maxLines = 1,
textAlign = TextAlign.Center,
modifier =

View file

@ -72,6 +72,7 @@ class CollectionFolderViewModel
itemId: UUID,
potential: BaseItem?,
sortAndDirection: SortAndDirection,
recursive: Boolean,
): Job =
viewModelScope.launch(
LoadingExceptionHandler(
@ -80,10 +81,13 @@ class CollectionFolderViewModel
) + Dispatchers.IO,
) {
fetchItem(itemId, potential)
loadResults(sortAndDirection)
loadResults(sortAndDirection, recursive)
}
fun loadResults(sortAndDirection: SortAndDirection) {
fun loadResults(
sortAndDirection: SortAndDirection,
recursive: Boolean,
) {
item.value?.let { item ->
viewModelScope.launch(Dispatchers.IO) {
withContext(Dispatchers.Main) {
@ -96,6 +100,15 @@ class CollectionFolderViewModel
CollectionType.MOVIES -> listOf(BaseItemKind.MOVIE)
CollectionType.TVSHOWS -> listOf(BaseItemKind.SERIES)
CollectionType.HOMEVIDEOS -> listOf(BaseItemKind.VIDEO)
CollectionType.MUSIC ->
listOf(
BaseItemKind.AUDIO,
BaseItemKind.MUSIC_ARTIST,
BaseItemKind.MUSIC_ALBUM,
)
CollectionType.BOXSETS -> listOf(BaseItemKind.BOX_SET)
CollectionType.PLAYLISTS -> listOf(BaseItemKind.PLAYLIST)
else -> listOf()
}
@ -104,7 +117,8 @@ class CollectionFolderViewModel
parentId = item.id,
enableImageTypes = listOf(ImageType.PRIMARY, ImageType.THUMB),
includeItemTypes = includeItemTypes,
recursive = true,
recursive = recursive,
excludeItemIds = listOf(item.id),
sortBy =
listOf(
sortAndDirection.sort,
@ -120,7 +134,13 @@ class CollectionFolderViewModel
fields = DefaultItemFields,
)
val newPager =
ApiRequestPager(api, request, GetItemsRequestHandler, viewModelScope)
ApiRequestPager(
api,
request,
GetItemsRequestHandler,
viewModelScope,
useSeriesForPrimary = true,
)
newPager.init()
if (newPager.isNotEmpty()) newPager.getBlocking(0)
withContext(Dispatchers.Main) {
@ -164,6 +184,7 @@ class CollectionFolderViewModel
fun CollectionFolderGrid(
preferences: UserPreferences,
destination: Destination.MediaItem,
recursive: Boolean,
onClickItem: (BaseItem) -> Unit,
modifier: Modifier = Modifier,
viewModel: CollectionFolderViewModel = hiltViewModel(),
@ -176,7 +197,7 @@ fun CollectionFolderGrid(
positionCallback: ((columns: Int, position: Int) -> Unit)? = null,
) {
OneTimeLaunchedEffect {
viewModel.init(destination.itemId, destination.item, initialSortAndDirection)
viewModel.init(destination.itemId, destination.item, initialSortAndDirection, recursive)
}
val sortAndDirection by viewModel.sortAndDirection.observeAsState(initialSortAndDirection)
val loading by viewModel.loading.observeAsState(LoadingState.Loading)
@ -198,7 +219,7 @@ fun CollectionFolderGrid(
modifier = modifier,
onClickItem = onClickItem,
onSortChange = {
viewModel.loadResults(it)
viewModel.loadResults(it, recursive)
},
showTitle = showTitle,
positionCallback = positionCallback,
@ -263,7 +284,7 @@ fun CollectionFolderGridContent(
CardGrid(
pager = pager,
onClickItem = onClickItem,
longClicker = {},
onLongClickItem = {},
letterPosition = letterPosition,
gridFocusRequester = gridFocusRequester,
showJumpButtons = false, // TODO add preference

View file

@ -69,7 +69,7 @@ private const val DEBUG = false
fun CardGrid(
pager: List<BaseItem?>,
onClickItem: (BaseItem) -> Unit,
longClicker: (BaseItem) -> Unit,
onLongClickItem: (BaseItem) -> Unit,
letterPosition: suspend (Char) -> Int,
gridFocusRequester: FocusRequester,
showJumpButtons: Boolean,
@ -257,7 +257,7 @@ fun CardGrid(
onClickItem.invoke(item)
}
},
onLongClick = { if (item != null) longClicker.invoke(item) },
onLongClick = { if (item != null) onLongClickItem.invoke(item) },
modifier =
mod
.ifElse(index == 0, Modifier.focusRequester(zeroFocus))

View file

@ -18,6 +18,7 @@ import com.github.damontecres.dolphin.ui.preferences.PreferencesViewModel
fun CollectionFolderGeneric(
preferences: UserPreferences,
destination: Destination.MediaItem,
recursive: Boolean,
modifier: Modifier = Modifier,
preferencesViewModel: PreferencesViewModel = hiltViewModel(),
) {
@ -27,6 +28,7 @@ fun CollectionFolderGeneric(
onClickItem = { preferencesViewModel.navigationManager.navigateTo(it.destination()) },
destination = destination,
showTitle = showHeader,
recursive = recursive,
modifier =
modifier
.padding(start = 16.dp),

View file

@ -156,6 +156,7 @@ fun CollectionFolderMovie(
onClickItem = onClickItem,
destination = destination,
showTitle = false,
recursive = true,
modifier =
Modifier
.padding(start = 16.dp)

View file

@ -155,6 +155,7 @@ fun CollectionFolderTv(
preferences = preferences,
destination = destination,
showTitle = false,
recursive = true,
modifier =
Modifier
.padding(start = 16.dp)

View file

@ -61,13 +61,14 @@ abstract class ItemViewModel<T>(
abstract class LoadingItemViewModel<T>(
api: ApiClient,
) : ItemViewModel<T>(api) {
val loading = MutableLiveData<LoadingState>(LoadingState.Loading)
val loading = MutableLiveData<LoadingState>(LoadingState.Pending)
open fun init(
itemId: UUID,
potential: BaseItem?,
): Job? =
viewModelScope.launch(
): Job? {
loading.value = LoadingState.Loading
return viewModelScope.launch(
LoadingExceptionHandler(
loading,
"Error loading item $itemId",
@ -86,3 +87,4 @@ abstract class LoadingItemViewModel<T>(
}
}
}
}

View file

@ -106,6 +106,14 @@ fun DestinationContent(
modifier,
)
BaseItemKind.BOX_SET ->
CollectionFolderGeneric(
preferences,
destination,
false,
modifier,
)
BaseItemKind.COLLECTION_FOLDER -> {
when (destination.item?.data?.collectionType) {
CollectionType.TVSHOWS ->
@ -122,10 +130,19 @@ fun DestinationContent(
modifier,
)
CollectionType.BOXSETS ->
CollectionFolderGeneric(
preferences,
destination,
true,
modifier,
)
else ->
CollectionFolderGeneric(
preferences,
destination,
false,
modifier,
)
}
@ -141,6 +158,7 @@ fun DestinationContent(
CollectionFolderGeneric(
preferences,
destination,
true,
modifier,
)

View file

@ -318,6 +318,8 @@ fun NavigationDrawerScope.LibraryNavItem(
CollectionType.HOMEVIDEOS -> R.string.fa_video
CollectionType.LIVETV -> R.string.fa_tv
CollectionType.MUSIC -> R.string.fa_music
CollectionType.BOXSETS -> R.string.fa_open_folder
CollectionType.PLAYLISTS -> R.string.fa_list_ul
else -> R.string.fa_film
}
val isFocused = interactionSource.collectIsFocusedAsState().value

View file

@ -28,4 +28,5 @@ val supportedCollectionTypes =
CollectionType.TVSHOWS,
CollectionType.HOMEVIDEOS,
CollectionType.PLAYLISTS,
CollectionType.BOXSETS,
)

View file

@ -32,4 +32,6 @@
<string name="fa_eye_slash" translatable="false">&#xf070;</string>
<string name="fa_arrow_left_arrow_right" translatable="false">&#xf0ec;</string>
<string name="fa_shuffle" translatable="false">&#xf074;</string>
<string name="fa_open_folder" translatable="false">&#xf07c;</string>
<string name="fa_list_ul" translatable="false">&#xf0ca;</string>
</resources>