Use new search bar in filter picker

pull/2919/head
Alex Baker 1 week ago
parent 007c536312
commit bada09f5c2

@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
@ -63,12 +64,17 @@ class FilterSelectionActivity : AppCompatActivity() {
state.query.isNotBlank()
}
}
BackHandler {
if (searching) {
viewModel.onQueryChange("")
} else {
finish()
}
}
SearchableFilterPicker(
filters = if (searching) state.searchResults else state.filters,
query = state.query,
onQueryChange = { viewModel.onQueryChange(it) },
active = true,
dismiss = { finish() },
getIcon = { ImageVector.vectorResource(id = viewModel.getIcon(it)) },
getColor = { viewModel.getColor(it) },
selected = selected,

@ -32,7 +32,6 @@ fun FilterPickerPreview() {
),
query = "",
onQueryChange = {},
active = true,
selected = null,
onClick = {},
getIcon = { when (it.icon) {
@ -40,7 +39,6 @@ fun FilterPickerPreview() {
else -> Icons.Outlined.QuestionMark
} },
getColor = { 0 },
dismiss = {},
)
}
}

@ -1,32 +1,28 @@
package org.tasks.compose.pickers
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Clear
import androidx.compose.material.icons.outlined.PeopleOutline
import androidx.compose.material.icons.outlined.PermIdentity
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import org.jetbrains.compose.resources.stringResource
import org.tasks.compose.components.SearchBar
import org.tasks.filters.CaldavFilter
import org.tasks.filters.Filter
import org.tasks.filters.FilterListItem
@ -34,124 +30,78 @@ import org.tasks.filters.NavigationDrawerSubheader
import tasks.kmp.generated.resources.Res
import tasks.kmp.generated.resources.search
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SearchableFilterPicker(
filters: List<FilterListItem>,
query: String,
onQueryChange: (String) -> Unit,
active: Boolean,
selected: Filter?,
onClick: (FilterListItem) -> Unit,
getIcon: @Composable (Filter) -> ImageVector,
getColor: (Filter) -> Int,
dismiss: () -> Unit,
) {
val searching by remember(query) {
derivedStateOf {
query.isNotBlank()
}
}
val filtered by remember (filters, query) {
derivedStateOf {
filters.filter {
when (it) {
is NavigationDrawerSubheader -> true
is Filter -> {
it.title!!.contains(query, ignoreCase = true)
}
else -> throw IllegalArgumentException()
LazyColumn(
modifier = Modifier
.background(
color = MaterialTheme.colorScheme.surface,
shape = MaterialTheme.shapes.medium
),
contentPadding = PaddingValues(top = 16.dp),
) {
item {
SearchBar(
modifier = Modifier
.padding(start = 8.dp, end = 8.dp, bottom = 4.dp)
.fillMaxWidth(),
text = query,
onTextChange = { onQueryChange(it) },
placeHolder = stringResource(Res.string.search),
onCloseClicked = { onQueryChange("") },
onSearchClicked = {
// TODO: close keyboard
}
}
}
}
SearchBar(
colors = SearchBarDefaults.colors(
containerColor = MaterialTheme.colorScheme.surface,
inputFieldColors = TextFieldDefaults.colors(
focusedContainerColor = MaterialTheme.colorScheme.surface,
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
)
),
query = query,
onQueryChange = onQueryChange,
onSearch = {
// TODO: close keyboard?
},
leadingIcon = {
Icon(
imageVector = Icons.Outlined.Search,
contentDescription = null,
)
},
placeholder = {
Text(
text = stringResource(Res.string.search),
color = MaterialTheme.colorScheme.onSurface,
)
},
trailingIcon = {
if (searching) {
IconButton(onClick = { onQueryChange("") }) {
Icon(
imageVector = Icons.Outlined.Clear,
contentDescription = "Clear query",
}
items(filters) { filter ->
when (filter) {
is NavigationDrawerSubheader -> {
CollapsibleRow(
text = filter.title!!,
collapsed = filter.isCollapsed,
onClick = { onClick(filter) },
)
}
}
},
active = active,
onActiveChange = {
when {
it -> {}
query.isNotBlank() -> onQueryChange("")
else -> dismiss()
}
},
content = {
Column(
modifier = Modifier.verticalScroll(rememberScrollState())
) {
filtered.forEach { filter ->
when (filter) {
is NavigationDrawerSubheader -> {
CollapsibleRow(
is Filter -> {
CheckableIconRow(
icon = getIcon(filter),
tint = remember(filter) { Color(getColor(filter)) },
selected = filter == selected,
onClick = { onClick(filter) },
) {
Row(verticalAlignment = CenterVertically) {
Text(
text = filter.title!!,
collapsed = filter.isCollapsed,
onClick = { onClick(filter) },
style = MaterialTheme.typography.bodyMedium.copy(
fontWeight = FontWeight.Medium,
color = MaterialTheme.colorScheme.onSurface,
),
modifier = Modifier.weight(1f),
)
}
is Filter -> {
CheckableIconRow(
icon = getIcon(filter),
tint = remember(filter) { Color(getColor(filter)) },
selected = filter == selected,
onClick = { onClick(filter) },
) {
Row(verticalAlignment = CenterVertically) {
Text(
text = filter.title!!,
style = MaterialTheme.typography.bodyMedium.copy(
fontWeight = FontWeight.Medium
),
modifier = Modifier.weight(1f),
)
if (filter is CaldavFilter && filter.principals > 0) {
Icon(
imageVector = when (filter.principals) {
in 2..Int.MAX_VALUE -> Icons.Outlined.PeopleOutline
else -> Icons.Outlined.PermIdentity
},
contentDescription = null,
)
}
}
if (filter is CaldavFilter && filter.principals > 0) {
Icon(
imageVector = when (filter.principals) {
in 2..Int.MAX_VALUE -> Icons.Outlined.PeopleOutline
else -> Icons.Outlined.PermIdentity
},
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurface,
)
}
}
}
}
}
},
)
}
}
}

Loading…
Cancel
Save