mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 15:50:16 +02:00
Add playlist & collection specific grid layout UIs (#246)
Adds grid layouts specifically for playlists and collections/boxsets instead of falling back to the generic grid. In #238, the generic grid was updated to show 4 columns of 16x9 cards. Now, collections will use 2x3 (poster) cards (like Movies) and playlists will use square cards. This also means collections & playlists have more relevant sort options. Fixes #243 Closes #226
This commit is contained in:
parent
cda5b118a3
commit
1fd497d18c
6 changed files with 183 additions and 18 deletions
|
|
@ -78,6 +78,7 @@ object AspectRatios {
|
||||||
const val WIDE = 16f / 9f
|
const val WIDE = 16f / 9f
|
||||||
const val FOUR_THREE = 4f / 3f
|
const val FOUR_THREE = 4f / 3f
|
||||||
const val TALL = 2f / 3f
|
const val TALL = 2f / 3f
|
||||||
|
const val SQUARE = 1f
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(
|
@Preview(
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import androidx.compose.ui.layout.ContentScale
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
|
|
@ -468,6 +469,10 @@ fun CollectionFolderGridContent(
|
||||||
showHeader,
|
showHeader,
|
||||||
enter = slideInVertically() + fadeIn(),
|
enter = slideInVertically() + fadeIn(),
|
||||||
exit = slideOutVertically() + fadeOut(),
|
exit = slideOutVertically() + fadeOut(),
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
) {
|
) {
|
||||||
if (showTitle) {
|
if (showTitle) {
|
||||||
Text(
|
Text(
|
||||||
|
|
@ -475,6 +480,8 @@ fun CollectionFolderGridContent(
|
||||||
style = MaterialTheme.typography.displayMedium,
|
style = MaterialTheme.typography.displayMedium,
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
|
maxLines = 1,
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -487,6 +494,7 @@ fun CollectionFolderGridContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
CardGrid(
|
CardGrid(
|
||||||
pager = pager,
|
pager = pager,
|
||||||
onClickItem = onClickItem,
|
onClickItem = onClickItem,
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,19 @@ val VideoSortOptions =
|
||||||
ItemSortBy.RANDOM,
|
ItemSortBy.RANDOM,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val PlaylistSortOptions =
|
||||||
|
listOf(
|
||||||
|
ItemSortBy.SORT_NAME,
|
||||||
|
ItemSortBy.PREMIERE_DATE,
|
||||||
|
ItemSortBy.DATE_CREATED,
|
||||||
|
ItemSortBy.DATE_PLAYED,
|
||||||
|
ItemSortBy.COMMUNITY_RATING,
|
||||||
|
ItemSortBy.CRITIC_RATING,
|
||||||
|
ItemSortBy.RUNTIME,
|
||||||
|
ItemSortBy.PLAY_COUNT,
|
||||||
|
ItemSortBy.RANDOM,
|
||||||
|
)
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
fun getStringRes(sort: ItemSortBy): Int =
|
fun getStringRes(sort: ItemSortBy): Int =
|
||||||
when (sort) {
|
when (sort) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
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.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
|
||||||
|
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CollectionFolderBoxSet(
|
||||||
|
preferences: UserPreferences,
|
||||||
|
itemId: UUID,
|
||||||
|
item: BaseItem?,
|
||||||
|
recursive: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
filter: GetItemsFilter = GetItemsFilter(),
|
||||||
|
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()) },
|
||||||
|
itemId = itemId,
|
||||||
|
initialFilter = filter,
|
||||||
|
showTitle = showHeader,
|
||||||
|
recursive = recursive,
|
||||||
|
sortOptions = MovieSortOptions,
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.padding(start = 16.dp),
|
||||||
|
positionCallback = { columns, position ->
|
||||||
|
showHeader = position < columns
|
||||||
|
},
|
||||||
|
params = params,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,66 @@
|
||||||
|
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.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
|
||||||
|
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CollectionFolderPlaylist(
|
||||||
|
preferences: UserPreferences,
|
||||||
|
itemId: UUID,
|
||||||
|
item: BaseItem?,
|
||||||
|
recursive: Boolean,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
filter: GetItemsFilter = GetItemsFilter(),
|
||||||
|
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()) },
|
||||||
|
itemId = itemId,
|
||||||
|
initialFilter = filter,
|
||||||
|
showTitle = showHeader,
|
||||||
|
recursive = recursive,
|
||||||
|
sortOptions = PlaylistSortOptions,
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.padding(start = 16.dp),
|
||||||
|
positionCallback = { columns, position ->
|
||||||
|
showHeader = position < columns
|
||||||
|
},
|
||||||
|
params = params,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,11 @@ import androidx.tv.material3.Text
|
||||||
import com.github.damontecres.wholphin.preferences.UserPreferences
|
import com.github.damontecres.wholphin.preferences.UserPreferences
|
||||||
import com.github.damontecres.wholphin.ui.components.ItemGrid
|
import com.github.damontecres.wholphin.ui.components.ItemGrid
|
||||||
import com.github.damontecres.wholphin.ui.components.LicenseInfo
|
import com.github.damontecres.wholphin.ui.components.LicenseInfo
|
||||||
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderBoxSet
|
||||||
import com.github.damontecres.wholphin.ui.detail.CollectionFolderGeneric
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderGeneric
|
||||||
import com.github.damontecres.wholphin.ui.detail.CollectionFolderLiveTv
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderLiveTv
|
||||||
import com.github.damontecres.wholphin.ui.detail.CollectionFolderMovie
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderMovie
|
||||||
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderPlaylist
|
||||||
import com.github.damontecres.wholphin.ui.detail.CollectionFolderTv
|
import com.github.damontecres.wholphin.ui.detail.CollectionFolderTv
|
||||||
import com.github.damontecres.wholphin.ui.detail.DebugPage
|
import com.github.damontecres.wholphin.ui.detail.DebugPage
|
||||||
import com.github.damontecres.wholphin.ui.detail.FavoritesPage
|
import com.github.damontecres.wholphin.ui.detail.FavoritesPage
|
||||||
|
|
@ -97,7 +99,7 @@ fun DestinationContent(
|
||||||
)
|
)
|
||||||
|
|
||||||
BaseItemKind.BOX_SET ->
|
BaseItemKind.BOX_SET ->
|
||||||
CollectionFolderGeneric(
|
CollectionFolderBoxSet(
|
||||||
preferences,
|
preferences,
|
||||||
destination.itemId,
|
destination.itemId,
|
||||||
destination.item,
|
destination.item,
|
||||||
|
|
@ -122,7 +124,7 @@ fun DestinationContent(
|
||||||
)
|
)
|
||||||
|
|
||||||
CollectionType.BOXSETS ->
|
CollectionType.BOXSETS ->
|
||||||
CollectionFolderGeneric(
|
CollectionFolderBoxSet(
|
||||||
preferences,
|
preferences,
|
||||||
destination.itemId,
|
destination.itemId,
|
||||||
destination.item,
|
destination.item,
|
||||||
|
|
@ -170,6 +172,15 @@ fun DestinationContent(
|
||||||
modifier,
|
modifier,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
CollectionType.PLAYLISTS ->
|
||||||
|
CollectionFolderPlaylist(
|
||||||
|
preferences,
|
||||||
|
destination.itemId,
|
||||||
|
destination.item,
|
||||||
|
true,
|
||||||
|
modifier,
|
||||||
|
)
|
||||||
|
|
||||||
else ->
|
else ->
|
||||||
CollectionFolderGeneric(
|
CollectionFolderGeneric(
|
||||||
preferences,
|
preferences,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue