NuvioStreaming/patch.diff
harrydbarnes b73cccc43b feat: Add local filters to Trakt Library view all screen
- Added "All", "Movies", and "Series" FilterChips to the `CatalogHeader`.
- Computed `filteredItems` to apply filtering for the Trakt Library screen based on the item type (movies vs series/tv).
- Applied Material Theme `FilterChipDefaults` properties to ensure accurate theming.
2026-05-02 18:36:31 +00:00

120 lines
5.6 KiB
Diff

--- composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt
+++ composeApp/src/commonMain/kotlin/com/nuvio/app/features/catalog/CatalogScreen.kt
@@ -10,6 +10,7 @@
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
@@ -19,6 +20,8 @@
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.FilterChip
+import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -83,6 +86,16 @@
var headerHeightPx by remember { mutableIntStateOf(0) }
var observedOfflineState by remember { mutableStateOf(false) }
+ val isTraktLibrary = manifestUrl == INTERNAL_LIBRARY_MANIFEST_URL &&
+ subtitle == stringResource(Res.string.compose_catalog_subtitle_trakt_library)
+ var selectedFilter by remember { mutableIntStateOf(0) }
+
+ val filteredItems = remember(uiState.items, selectedFilter) {
+ if (selectedFilter == 1) uiState.items.filter { it.type.lowercase() in listOf("movie", "film") }
+ else if (selectedFilter == 2) uiState.items.filter { it.type.lowercase() in listOf("series", "tv", "show") }
+ else uiState.items
+ }
+
LaunchedEffect(manifestUrl, type, catalogId, genre, supportsPagination) {
CatalogRepository.load(
manifestUrl = manifestUrl,
@@ -149,11 +162,11 @@
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(18.dp),
) {
- if (uiState.items.isEmpty() && uiState.isLoading) {
+ if (filteredItems.isEmpty() && uiState.isLoading) {
items(columns * 3) {
CatalogSkeletonTile(cornerRadiusDp = posterCardStyle.cornerRadiusDp)
}
- } else if (uiState.items.isEmpty()) {
+ } else if (filteredItems.isEmpty()) {
item(span = { GridItemSpan(maxLineSpan) }) {
CatalogEmptyState(
errorMessage = uiState.errorMessage,
@@ -172,7 +185,7 @@
}
} else {
items(
- items = uiState.items.withDuplicateSafeLazyKeys { item -> item.stableKey() },
+ items = filteredItems.withDuplicateSafeLazyKeys { item -> item.stableKey() },
key = { item -> item.lazyKey },
) { keyedItem ->
val item = keyedItem.value
@@ -194,6 +207,9 @@
CatalogHeader(
title = title,
subtitle = subtitle,
+ showFilters = isTraktLibrary,
+ selectedFilter = selectedFilter,
+ onFilterSelected = { selectedFilter = it },
modifier = Modifier.onSizeChanged { headerHeightPx = it.height },
onBack = onBack,
)
@@ -206,6 +222,9 @@
private fun CatalogHeader(
title: String,
subtitle: String,
+ showFilters: Boolean = false,
+ selectedFilter: Int = 0,
+ onFilterSelected: (Int) -> Unit = {},
onBack: () -> Unit,
modifier: Modifier = Modifier,
) {
@@ -237,6 +256,41 @@
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
+ if (showFilters) {
+ Spacer(modifier = Modifier.height(12.dp))
+ Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
+ FilterChip(
+ selected = selectedFilter == 0,
+ onClick = { onFilterSelected(0) },
+ label = { Text(stringResource(Res.string.collections_tab_all)) },
+ colors = FilterChipDefaults.filterChipColors(
+ selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
+ selectedLabelColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ ),
+ shape = RoundedCornerShape(16.dp),
+ )
+ FilterChip(
+ selected = selectedFilter == 1,
+ onClick = { onFilterSelected(1) },
+ label = { Text(stringResource(Res.string.media_movies)) },
+ colors = FilterChipDefaults.filterChipColors(
+ selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
+ selectedLabelColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ ),
+ shape = RoundedCornerShape(16.dp),
+ )
+ FilterChip(
+ selected = selectedFilter == 2,
+ onClick = { onFilterSelected(2) },
+ label = { Text(stringResource(Res.string.media_series)) },
+ colors = FilterChipDefaults.filterChipColors(
+ selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
+ selectedLabelColor = MaterialTheme.colorScheme.onPrimaryContainer,
+ ),
+ shape = RoundedCornerShape(16.dp),
+ )
+ }
+ }
}
}