feat(app): improve search function by removing search suggestions

This commit is contained in:
Anthony 2024-06-30 22:06:37 +02:00
parent 1b94c0a694
commit 64c2e13a6f
3 changed files with 54 additions and 64 deletions

View File

@ -1,15 +1,10 @@
package component
import androidx.compose.animation.AnimatedContent
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material.icons.filled.Search
@ -27,13 +22,11 @@ import androidx.compose.ui.semantics.traversalIndex
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import data.ENumber
import tab.Licenses
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Search(eNumbers: List<ENumber>) {
var text by rememberSaveable { mutableStateOf("") }
fun Search(text: MutableState<String>) {
var expanded by rememberSaveable { mutableStateOf(false) }
val menuExpanded = remember { mutableStateOf(false) }
@ -47,32 +40,24 @@ fun Search(eNumbers: List<ENumber>) {
modifier = Modifier
.align(Alignment.CenterHorizontally)
.semantics { traversalIndex = 0f },
query = text,
onQueryChange = { text = it },
query = text.value,
onQueryChange = { text.value = it },
onSearch = { expanded = false },
onActiveChange = { expanded = it },
onActiveChange = { /* Do nothing */ },
active = expanded,
placeholder = { Text("Search E Numbers") },
leadingIcon = {
IconButton(
enabled = expanded,
onClick = { if (expanded) expanded = false }
enabled = false,
onClick = { /* Do nothing */ }
) {
AnimatedContent(
targetState = expanded,
) { targetExpanded ->
if (targetExpanded) {
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Exit Search")
} else {
Icon(Icons.Filled.Search, "Navigation Menu")
}
}
Icon(Icons.Filled.Search, "Navigation Menu")
}
},
trailingIcon = {
Row {
if (text.isNotEmpty()) {
IconButton(onClick = { text = "" }) {
if (text.value.isNotEmpty()) {
IconButton(onClick = { text.value = "" }) {
Icon(imageVector = Icons.Filled.Clear, contentDescription = "Clear Search")
}
}
@ -84,22 +69,7 @@ fun Search(eNumbers: List<ENumber>) {
}
}
}
) {
Column(Modifier.verticalScroll(rememberScrollState())) {
searchSuggestion(query = text, eNumbers = eNumbers).forEach {
ListItem(
headlineContent = { Text(text = it.number) },
modifier = Modifier
.clickable {
text = it.number
expanded = false
}
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 4.dp)
)
}
}
}
) { /* No search content - done externally */ }
}
}
@ -128,15 +98,3 @@ private fun OptionsMenu(expanded: MutableState<Boolean>) {
)
}
}
private fun searchSuggestion(query: String, eNumbers: List<ENumber>): List<ENumber> {
if (query.isEmpty()) {
return eNumbers
}
val filtered = eNumbers.filter { eNumber ->
eNumber.number.contains(query, ignoreCase = true)
}
return filtered
}

View File

@ -2,6 +2,7 @@ package tab.list
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
@ -17,21 +18,41 @@ import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.core.screen.Screen
import data.EGroup
import data.ENumber
class ENumberList(private val eNumbers: List<EGroup>) : Screen {
class ENumberList(private val eNumbers: List<EGroup>, private val searchText: MutableState<String>) : Screen {
@OptIn(ExperimentalFoundationApi::class)
@Composable
override fun Content() {
val displayItems = searchFilter(query = searchText.value, eGroups = eNumbers)
println(displayItems)
if (displayItems.isEmpty()) {
Column (
modifier = Modifier
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = "Sorry, we couldn't find any results :(")
}
return
}
LazyColumn(contentPadding = PaddingValues(6.dp)) {
eNumbers.forEach { eGroup ->
stickyHeader {
Header(group = eGroup.group)
displayItems.forEach { eGroup ->
if (displayItems.isNotEmpty()) {
stickyHeader {
Header(group = eGroup.group)
}
}
items(eGroup.numbers) { eNumber ->
@ -88,4 +109,18 @@ class ENumberList(private val eNumbers: List<EGroup>) : Screen {
contentDescription = status
)
}
private fun searchFilter(query: String, eGroups: List<EGroup>): List<EGroup> {
if (query.isEmpty()) {
return eGroups
}
val filtered = eGroups.map { eGroup ->
eGroup.copy(numbers = eGroup.numbers.filter { eNumber ->
eNumber.number.contains(query, ignoreCase = true)
})
}.filter { it.numbers.isNotEmpty() }
return filtered
}
}

View File

@ -7,6 +7,7 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import cafe.adriel.voyager.core.model.rememberNavigatorScreenModel
@ -38,18 +39,14 @@ object ListMain : Tab {
val screenModel = navigator.rememberNavigatorScreenModel { ListScreenModel() }
val state by screenModel.state.collectAsState()
val searchText = rememberSaveable { mutableStateOf("") }
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
when (val s = state) {
is ListScreenModel.State.Result -> {
val ungroupedENumbers = s.eNumbers.flatMap { it.numbers }
Search(ungroupedENumbers)
}
else -> Unit
}
Search(text = searchText)
}
) { innerPadding ->
Column(
@ -57,7 +54,7 @@ object ListMain : Tab {
) {
when (val s = state) {
is ListScreenModel.State.Loading -> LoadingScreen("E Numbers").Content()
is ListScreenModel.State.Result -> ENumberList(s.eNumbers).Content()
is ListScreenModel.State.Result -> ENumberList(s.eNumbers, searchText = searchText).Content()
}
}
}