From 9f7e4af924966d7884ba1d7985fe1bde039061a6 Mon Sep 17 00:00:00 2001 From: Patrick Lang Date: Fri, 15 Sep 2023 21:24:34 +0200 Subject: [PATCH] [Feature] Make category selection similar to category filter #866 First approach --- .../jtx/ui/detail/DetailsCardCategories.kt | 29 ++++++++++++++++- .../jtx/ui/detail/DetailsCardResources.kt | 31 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardCategories.kt b/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardCategories.kt index 47857dafc..909eea0f3 100644 --- a/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardCategories.kt +++ b/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardCategories.kt @@ -36,11 +36,14 @@ import androidx.compose.material3.InputChipDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Modifier @@ -60,6 +63,8 @@ import at.techbee.jtx.database.properties.Category import at.techbee.jtx.ui.reusable.elements.HeadlineWithIcon import at.techbee.jtx.ui.theme.getContrastSurfaceColorFor +const val DEFAULT_MAX_CATEGORIES = 5 + @OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable @@ -79,6 +84,7 @@ fun DetailsCardCategories( val mergedCategories = mutableListOf() mergedCategories.addAll(storedCategories) allCategories.forEach { cat -> if(mergedCategories.none { it.category == cat }) mergedCategories.add(StoredCategory(cat, null)) } + var maxEntries by rememberSaveable { mutableIntStateOf(DEFAULT_MAX_CATEGORIES) } fun addCategory() { if (newCategory.isNotEmpty() && categories.none { existing -> existing.text == newCategory }) { @@ -148,13 +154,19 @@ fun DetailsCardCategories( all.category.lowercase().contains(newCategory.lowercase()) && categories.none { existing -> existing.text.lowercase() == all.category.lowercase() } } + val categoriesToSelectFilteredSorted = + if(categoriesToSelectFiltered.size > maxEntries) + categoriesToSelectFiltered.subList(0, DEFAULT_MAX_CATEGORIES) + else + categoriesToSelectFiltered.sortedBy { it.category } + AnimatedVisibility(categoriesToSelectFiltered.isNotEmpty() && isEditMode) { LazyRow( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth() ) { - items(categoriesToSelectFiltered) { category -> + items(categoriesToSelectFilteredSorted) { category -> InputChip( onClick = { categories.add(Category(text = category.category)) @@ -176,6 +188,21 @@ fun DetailsCardCategories( modifier = Modifier.alpha(0.4f) ) } + + if(categoriesToSelectFiltered.size > maxEntries) { + item { + TextButton(onClick = { maxEntries = Int.MAX_VALUE }) { + Text(stringResource(R.string.filter_options_more_entries, categoriesToSelectFiltered.size - maxEntries)) + } + } + } + if(maxEntries == Int.MAX_VALUE) { + item { + TextButton(onClick = { maxEntries = DEFAULT_MAX_CATEGORIES }) { + Text(stringResource(R.string.filter_options_less_entries)) + } + } + } } } diff --git a/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardResources.kt b/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardResources.kt index 69bb3850a..ad0819a63 100644 --- a/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardResources.kt +++ b/app/src/main/java/at/techbee/jtx/ui/detail/DetailsCardResources.kt @@ -36,11 +36,14 @@ import androidx.compose.material3.InputChipDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Modifier @@ -61,6 +64,8 @@ import at.techbee.jtx.ui.reusable.elements.HeadlineWithIcon import at.techbee.jtx.ui.theme.getContrastSurfaceColorFor +const val DEFAULT_MAX_RESOURCES = 5 + @OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Composable fun DetailsCardResources( @@ -79,6 +84,7 @@ fun DetailsCardResources( val mergedResources = mutableListOf() mergedResources.addAll(storedResources) allResources.forEach { resource -> if(mergedResources.none { it.resource == resource }) mergedResources.add(StoredResource(resource, null)) } + var maxEntries by rememberSaveable { mutableIntStateOf(DEFAULT_MAX_CATEGORIES) } fun addResource() { if (newResource.isNotEmpty() && resources.none { existing -> existing.text == newResource }) { @@ -148,7 +154,15 @@ fun DetailsCardResources( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth() ) { - items(resourcesToSelectFiltered) { resource -> + + val resourcesToSelectFilteredSorted = + if(resourcesToSelectFiltered.size > maxEntries) + resourcesToSelectFiltered.subList(0, DEFAULT_MAX_CATEGORIES) + else + resourcesToSelectFiltered.sortedBy { it.resource } + + + items(resourcesToSelectFilteredSorted) { resource -> InputChip( onClick = { resources.add(Resource(text = resource.resource)) @@ -170,6 +184,21 @@ fun DetailsCardResources( modifier = Modifier.alpha(0.4f) ) } + + if(resourcesToSelectFiltered.size > maxEntries) { + item { + TextButton(onClick = { maxEntries = Int.MAX_VALUE }) { + Text(stringResource(R.string.filter_options_more_entries, resourcesToSelectFiltered.size - maxEntries)) + } + } + } + if(maxEntries == Int.MAX_VALUE) { + item { + TextButton(onClick = { maxEntries = DEFAULT_MAX_RESOURCES }) { + Text(stringResource(R.string.filter_options_less_entries)) + } + } + } } }