mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
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:
parent
39ad7e564f
commit
45567bf4eb
13 changed files with 287 additions and 161 deletions
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()) },
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ fun CollectionFolderLiveTv(
|
|||
onClickItem = onClickItem,
|
||||
itemId = folders[folderIndex].id,
|
||||
initialFilter = GetItemsFilter(),
|
||||
showTitle = showHeader,
|
||||
showTitle = false,
|
||||
recursive = false,
|
||||
sortOptions = VideoSortOptions,
|
||||
modifier =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
?: context.getString(R.string.recently_added)
|
||||
val viewId =
|
||||
if (view.collectionType == CollectionType.LIVETV) {
|
||||
api.liveTvApi
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
BaseItemKind.COLLECTION_FOLDER ->
|
||||
CollectionFolder(
|
||||
preferences = preferences,
|
||||
destination = destination,
|
||||
collectionType = destination.item?.data?.collectionType,
|
||||
usePostersOverride = null,
|
||||
recursiveOverride = null,
|
||||
modifier = 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.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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ val supportedCollectionTypes =
|
|||
CollectionType.PLAYLISTS,
|
||||
CollectionType.BOXSETS,
|
||||
CollectionType.LIVETV,
|
||||
CollectionType.MUSICVIDEOS,
|
||||
CollectionType.FOLDERS,
|
||||
null, // Mixed
|
||||
)
|
||||
|
||||
val supportedPlayableTypes =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue