Skip to content

Commit cf59033

Browse files
authored
Clearer node filter options (#3250)
1 parent 6abe012 commit cf59033

File tree

2 files changed

+84
-87
lines changed

2 files changed

+84
-87
lines changed

app/src/main/java/com/geeksville/mesh/ui/node/components/NodeFilterTextField.kt

Lines changed: 82 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -17,30 +17,34 @@
1717

1818
package com.geeksville.mesh.ui.node.components
1919

20-
import androidx.compose.animation.AnimatedVisibility
2120
import androidx.compose.foundation.background
2221
import androidx.compose.foundation.clickable
2322
import androidx.compose.foundation.layout.Box
2423
import androidx.compose.foundation.layout.Column
2524
import androidx.compose.foundation.layout.Row
2625
import androidx.compose.foundation.layout.defaultMinSize
2726
import androidx.compose.foundation.layout.fillMaxWidth
27+
import androidx.compose.foundation.layout.height
2828
import androidx.compose.foundation.layout.heightIn
2929
import androidx.compose.foundation.layout.padding
30+
import androidx.compose.foundation.layout.wrapContentHeight
3031
import androidx.compose.foundation.text.KeyboardActions
3132
import androidx.compose.foundation.text.KeyboardOptions
3233
import androidx.compose.material.icons.Icons
3334
import androidx.compose.material.icons.automirrored.filled.Sort
3435
import androidx.compose.material.icons.filled.Clear
3536
import androidx.compose.material.icons.filled.Done
3637
import androidx.compose.material.icons.filled.Search
38+
import androidx.compose.material3.Checkbox
3739
import androidx.compose.material3.DropdownMenu
3840
import androidx.compose.material3.DropdownMenuItem
3941
import androidx.compose.material3.HorizontalDivider
4042
import androidx.compose.material3.Icon
4143
import androidx.compose.material3.IconButton
4244
import androidx.compose.material3.MaterialTheme
45+
import androidx.compose.material3.MenuDefaults
4346
import androidx.compose.material3.OutlinedTextField
47+
import androidx.compose.material3.RadioButton
4448
import androidx.compose.material3.Text
4549
import androidx.compose.runtime.Composable
4650
import androidx.compose.runtime.getValue
@@ -54,6 +58,7 @@ import androidx.compose.ui.platform.LocalFocusManager
5458
import androidx.compose.ui.res.stringResource
5559
import androidx.compose.ui.text.font.FontWeight
5660
import androidx.compose.ui.text.input.ImeAction
61+
import androidx.compose.ui.text.style.TextAlign
5762
import androidx.compose.ui.tooling.preview.PreviewLightDark
5863
import androidx.compose.ui.unit.dp
5964
import com.geeksville.mesh.ui.common.preview.LargeFontPreview
@@ -184,104 +189,94 @@ private fun NodeSortButton(
184189
onDismissRequest = { expanded = false },
185190
modifier = Modifier.background(MaterialTheme.colorScheme.background.copy(alpha = 1f)),
186191
) {
192+
DropdownMenuTitle(text = stringResource(R.string.node_sort_title))
193+
187194
NodeSortOption.entries.forEach { sort ->
188-
DropdownMenuItem(
189-
onClick = {
190-
onSortSelect(sort)
191-
expanded = false
192-
},
193-
text = {
194-
Text(
195-
text = stringResource(id = sort.stringRes),
196-
fontWeight = if (sort == currentSortOption) FontWeight.ExtraBold else null,
197-
)
198-
},
195+
DropdownMenuRadio(
196+
text = stringResource(id = sort.stringRes),
197+
selected = sort == currentSortOption,
198+
onClick = { onSortSelect(sort) },
199199
)
200200
}
201-
HorizontalDivider()
202-
DropdownMenuItem(
203-
onClick = {
204-
toggles.onToggleIncludeUnknown()
205-
expanded = false
206-
},
207-
text = {
208-
Row {
209-
AnimatedVisibility(visible = toggles.includeUnknown) {
210-
Icon(
211-
imageVector = Icons.Default.Done,
212-
contentDescription = null,
213-
modifier = Modifier.padding(end = 4.dp),
214-
)
215-
}
216-
Text(text = stringResource(id = R.string.node_filter_include_unknown))
217-
}
218-
},
201+
202+
HorizontalDivider(modifier = Modifier.padding(MenuDefaults.DropdownMenuItemContentPadding))
203+
204+
DropdownMenuTitle(text = stringResource(R.string.node_filter_title))
205+
206+
DropdownMenuCheck(
207+
text = stringResource(R.string.node_filter_include_unknown),
208+
checked = toggles.includeUnknown,
209+
onClick = toggles.onToggleIncludeUnknown,
219210
)
220-
DropdownMenuItem(
221-
onClick = {
222-
toggles.onToggleOnlyOnline()
223-
expanded = false
224-
},
225-
text = {
226-
Row {
227-
AnimatedVisibility(visible = toggles.onlyOnline) {
228-
Icon(
229-
imageVector = Icons.Default.Done,
230-
contentDescription = null,
231-
modifier = Modifier.padding(end = 4.dp),
232-
)
233-
}
234-
Text(text = stringResource(id = R.string.node_filter_only_online))
235-
}
236-
},
211+
212+
DropdownMenuCheck(
213+
text = stringResource(R.string.node_filter_only_online),
214+
checked = toggles.onlyOnline,
215+
onClick = toggles.onToggleOnlyOnline,
237216
)
238-
DropdownMenuItem(
239-
onClick = {
240-
toggles.onToggleOnlyDirect()
241-
expanded = false
242-
},
243-
text = {
244-
Row {
245-
AnimatedVisibility(visible = toggles.onlyDirect) {
246-
Icon(
247-
imageVector = Icons.Default.Done,
248-
contentDescription = null,
249-
modifier = Modifier.padding(end = 4.dp),
250-
)
251-
}
252-
Text(text = stringResource(id = R.string.node_filter_only_direct))
253-
}
254-
},
217+
218+
DropdownMenuCheck(
219+
text = stringResource(R.string.node_filter_only_direct),
220+
checked = toggles.onlyDirect,
221+
onClick = toggles.onToggleOnlyDirect,
255222
)
256-
HorizontalDivider()
257-
DropdownMenuItem(
258-
onClick = {
259-
toggles.onToggleShowIgnored()
260-
expanded = false
261-
},
262-
text = {
263-
Row {
264-
AnimatedVisibility(visible = toggles.showIgnored) {
265-
Icon(
266-
imageVector = Icons.Default.Done,
267-
contentDescription = null,
268-
modifier = Modifier.padding(end = 4.dp),
269-
)
270-
}
271-
Text(text = stringResource(id = R.string.node_filter_show_ignored))
272-
if (toggles.ignoredNodeCount > 0) {
273-
Text(
274-
text = " (${toggles.ignoredNodeCount})",
275-
color = MaterialTheme.colorScheme.primary,
276-
modifier = Modifier.padding(start = 4.dp),
277-
)
278-
}
223+
224+
DropdownMenuCheck(
225+
text = stringResource(R.string.node_filter_show_ignored),
226+
checked = toggles.showIgnored,
227+
onClick = toggles.onToggleShowIgnored,
228+
trailing =
229+
if (toggles.ignoredNodeCount > 0) {
230+
{
231+
Text(
232+
text = " (${toggles.ignoredNodeCount})",
233+
color = MaterialTheme.colorScheme.primary,
234+
modifier = Modifier.padding(start = 4.dp),
235+
)
279236
}
237+
} else {
238+
null
280239
},
281240
)
282241
}
283242
}
284243

244+
@Composable
245+
private fun DropdownMenuTitle(text: String) {
246+
Text(
247+
text = text,
248+
modifier =
249+
Modifier.height(48.dp)
250+
.padding(MenuDefaults.DropdownMenuItemContentPadding)
251+
.wrapContentHeight(align = Alignment.CenterVertically),
252+
fontWeight = FontWeight.ExtraBold,
253+
)
254+
}
255+
256+
@Composable
257+
private fun DropdownMenuRadio(text: String, selected: Boolean, onClick: () -> Unit) {
258+
DropdownMenuItem(
259+
onClick = onClick,
260+
leadingIcon = { RadioButton(selected = selected, onClick = null) },
261+
text = { Text(text = text) },
262+
)
263+
}
264+
265+
@Composable
266+
private fun DropdownMenuCheck(
267+
text: String,
268+
checked: Boolean,
269+
onClick: () -> Unit,
270+
trailing: @Composable (() -> Unit)? = null,
271+
) {
272+
DropdownMenuItem(
273+
onClick = onClick,
274+
leadingIcon = { Checkbox(checked = checked, onCheckedChange = null) },
275+
trailingIcon = trailing,
276+
text = { Text(text = text) },
277+
)
278+
}
279+
285280
@PreviewLightDark
286281
@LargeFontPreview
287282
@Composable

core/strings/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@
3131
<string name="fallback_node_name">Meshtastic %s</string>
3232
<string name="node_filter_placeholder">Filter</string>
3333
<string name="desc_node_filter_clear">clear node filter</string>
34+
<string name="node_filter_title">Filter by</string>
3435
<string name="node_filter_include_unknown">Include unknown</string>
3536
<string name="node_filter_only_online">Hide offline nodes</string>
3637
<string name="node_filter_only_direct">Only show direct nodes</string>
3738
<string name="node_filter_ignored">You are viewing ignored nodes,\nPress to return to the node list.</string>
3839
<string name="node_filter_show_details">Show details</string>
40+
<string name="node_sort_title">Sort by</string>
3941
<string name="node_sort_button">Node sorting options</string>
4042
<string name="node_sort_alpha">A-Z</string>
4143
<string name="node_sort_channel">Channel</string>

0 commit comments

Comments
 (0)