Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import androidx.compose.material.Card
import androidx.compose.material.Checkbox
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.ContentAlpha
import androidx.compose.material.Divider
import androidx.compose.material.LocalContentAlpha
Expand All @@ -42,6 +44,9 @@
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.material.contentColorFor
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.rememberScaffoldState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
Expand Down Expand Up @@ -608,8 +613,35 @@
CircularProgressIndicator()
}
} else if (listSettingDialog) {
LazyColumn {
items(state.entries, key = { (id) -> id }) { (id, entry) ->
var searchQuery by remember { mutableStateOf("") }
val filteredEntries = remember(state.entries, searchQuery) {
filterSettingEntries(state.entries, searchQuery)
}
Column {
TextField(
value = searchQuery,
onValueChange = { searchQuery = it },
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
singleLine = true,
label = { Text(stringResource(commonR.string.search)) },
leadingIcon = { Icon(Icons.Filled.Search, contentDescription = null) },
trailingIcon = if (searchQuery.isNotBlank()) {
{
IconButton(onClick = { searchQuery = "" }) {
Icon(
Icons.Filled.Clear,
contentDescription = stringResource(commonR.string.clear_search),
)
}
}
} else {
null
},
)
LazyColumn(modifier = Modifier.weight(1f)) {
items(filteredEntries, key = { (id) -> id }) { (id, entry) ->
SensorDetailSettingRow(
label = entry,
checked = if (state.setting.valueType ==
Expand All @@ -634,6 +666,7 @@
},
)
}
}
}
} else {
TextField(
Expand Down Expand Up @@ -734,6 +767,17 @@
)
}

/**
* Filters setting entries by matching the query against entry labels (case-insensitive).
* Returns all entries when the query is blank.
*/
internal fun filterSettingEntries(
entries: List<Pair<String, String>>,
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
query: String,
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
): List<Pair<String, String>> =
if (query.isBlank()) entries
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
else entries.filter { (_, label) -> label.contains(query.trim(), ignoreCase = true) }
Comment thread
danielgomezrico marked this conversation as resolved.
Outdated
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed
Comment thread
danielgomezrico marked this conversation as resolved.
Fixed

@Composable
fun SensorDetailSettingRow(
label: String,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.homeassistant.companion.android.settings.sensor.views

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class SensorDetailSettingDialogFilterTest {

private val entries = listOf(
"com.google.chrome" to "Chrome\n(com.google.chrome)",
"org.mozilla.firefox" to "Firefox\n(org.mozilla.firefox)",
"com.example.app" to "Example App\n(com.example.app)",
)

@Test
fun `Given empty query when filtering then return all entries`() {
val result = filterSettingEntries(entries, query = "")

assertEquals(entries, result)
}

@Test
fun `Given blank query when filtering then return all entries`() {
val result = filterSettingEntries(entries, query = " ")

assertEquals(entries, result)
}

@Test
fun `Given query matching app name when filtering then return matching entries`() {
val result = filterSettingEntries(entries, query = "Chrome")

assertEquals(listOf(entries[0]), result)
}

@Test
fun `Given query matching package name in label when filtering then return matching entries`() {
val result = filterSettingEntries(entries, query = "com.google")

assertEquals(listOf(entries[0]), result)
}

@Test
fun `Given case-insensitive query when filtering then return matches`() {
val result = filterSettingEntries(entries, query = "CHROME")

assertEquals(listOf(entries[0]), result)
}

@Test
fun `Given query matching no entries when filtering then return empty list`() {
val result = filterSettingEntries(entries, query = "nonexistent")

assertEquals(emptyList<Pair<String, String>>(), result)
}

@Test
fun `Given query with leading and trailing spaces when filtering then trim and match`() {
val result = filterSettingEntries(entries, query = " Chrome ")

assertEquals(listOf(entries[0]), result)
}
}
Loading