From bb7c33ed277e6c3e9cabfb01dbf2a13c1d47baa1 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Wed, 14 Sep 2022 13:24:52 -0300 Subject: [PATCH] Add functional search bar to forum list --- .../briar/desktop/contact/ContactList.kt | 8 +- .../briar/desktop/contact/SearchTextField.kt | 16 ++-- .../briar/desktop/forums/ForumsList.kt | 73 +++++++++++++++---- .../briar/desktop/forums/ForumsScreen.kt | 3 + .../briar/desktop/forums/ForumsViewModel.kt | 16 +++- .../resources/strings/BriarDesktop.properties | 1 + 6 files changed, 93 insertions(+), 24 deletions(-) diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt index f7f6bff50d..be304ce31c 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt @@ -33,6 +33,8 @@ import androidx.compose.foundation.rememberScrollbarAdapter import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.PersonAdd import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -65,9 +67,11 @@ fun ContactList( modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp), ) { SearchTextField( - filterBy, + placeholder = i18n("contacts.search.title"), + icon = Icons.Filled.PersonAdd, + searchValue = filterBy, onValueChange = setFilterBy, - onContactAdd = onContactAdd, + onAddButtonClicked = onContactAdd, ) } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt index cbfa8141ef..6d3e564dfb 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/SearchTextField.kt @@ -27,17 +27,23 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.PersonAdd import androidx.compose.material.icons.filled.Search import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.unit.dp import org.briarproject.briar.desktop.ui.ColoredIconButton import org.briarproject.briar.desktop.utils.AccessibilityUtils.description import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n @Composable -fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onContactAdd: () -> Unit) { +fun SearchTextField( + placeholder: String, + icon: ImageVector, + searchValue: String, + onValueChange: (String) -> Unit, + onAddButtonClicked: () -> Unit, +) { TextField( value = searchValue, onValueChange = onValueChange, @@ -45,7 +51,7 @@ fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onCont textStyle = LocalTextStyle.current.copy( color = MaterialTheme.colors.onSurface ), - placeholder = { Text(i18n("contacts.search.title"), style = MaterialTheme.typography.body1) }, + placeholder = { Text(placeholder, style = MaterialTheme.typography.body1) }, shape = RoundedCornerShape(0.dp), leadingIcon = { val padding = Modifier.padding(top = 8.dp, bottom = 8.dp, start = 32.dp, end = 4.dp) @@ -53,10 +59,10 @@ fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onCont }, trailingIcon = { ColoredIconButton( - icon = Icons.Filled.PersonAdd, + icon = icon, iconSize = 20.dp, contentDescription = i18n("access.contacts.add"), - onClick = onContactAdd, + onClick = onAddButtonClicked, modifier = Modifier.padding(end = 8.dp) ) }, diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsList.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsList.kt index 067be793c1..437b5bdc06 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsList.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsList.kt @@ -18,40 +18,81 @@ package org.briarproject.briar.desktop.forums +import androidx.compose.foundation.VerticalScrollbar +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.foundation.selection.selectableGroup import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold +import androidx.compose.material.Surface +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AddComment import androidx.compose.runtime.Composable +import androidx.compose.runtime.State +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import org.briarproject.bramble.api.sync.GroupId +import org.briarproject.briar.desktop.contact.SearchTextField import org.briarproject.briar.desktop.theme.surfaceVariant +import org.briarproject.briar.desktop.ui.Constants import org.briarproject.briar.desktop.ui.Constants.COLUMN_WIDTH import org.briarproject.briar.desktop.ui.HorizontalDivider +import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n @Composable fun ForumsList( - list: List<ForumsItem>, + list: State<List<GroupItem>>, isSelected: (GroupId) -> Boolean, + filterBy: State<String>, + onFilterSet: (String) -> Unit, onGroupIdSelected: (GroupId) -> Unit, + onAddButtonClicked: () -> Unit, ) { - // TODO AddForumDialog (and search bar?) - Scaffold( + val scrollState = rememberLazyListState() + Surface( modifier = Modifier.fillMaxHeight().width(COLUMN_WIDTH), - backgroundColor = MaterialTheme.colors.surfaceVariant, - content = { - LazyColumn { - items(list) { item -> - GroupsCard( - item = item, - onGroupIdSelected = onGroupIdSelected, - selected = isSelected(item.forum.id) - ) - HorizontalDivider() + color = MaterialTheme.colors.surfaceVariant + ) { + Column { + Column( + modifier = Modifier.fillMaxWidth().height(Constants.HEADER_SIZE + 1.dp), + ) { + SearchTextField( + placeholder = i18n("forum.search.title"), + icon = Icons.Filled.AddComment, + searchValue = filterBy.value, + onValueChange = onFilterSet, + onAddButtonClicked = onAddButtonClicked, + ) + } + Box(modifier = Modifier.fillMaxSize()) { + LazyColumn( + state = scrollState, + modifier = Modifier.selectableGroup() + ) { + items(list.value) { item -> + GroupsCard( + item = item, + onGroupIdSelected = onGroupIdSelected, + selected = isSelected(item.id) + ) + HorizontalDivider() + } } + VerticalScrollbar( + adapter = rememberScrollbarAdapter(scrollState), + modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight() + ) } - }, - ) + } + } } diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsScreen.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsScreen.kt index f1a6509dcc..77f448ddf8 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsScreen.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsScreen.kt @@ -36,7 +36,10 @@ fun ForumsScreen( ForumsList( list = viewModel.groupList, isSelected = viewModel::isSelected, + filterBy = viewModel.filterBy, + onFilterSet = viewModel::setFilterBy, onGroupIdSelected = viewModel::selectGroup, + onAddButtonClicked = {}, ) VerticalDivider() Column(modifier = Modifier.weight(1f).fillMaxHeight()) { diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsViewModel.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsViewModel.kt index ea998d3efb..b92f33acdb 100644 --- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsViewModel.kt +++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/forums/ForumsViewModel.kt @@ -19,6 +19,7 @@ package org.briarproject.briar.desktop.forums import androidx.compose.runtime.State +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import org.briarproject.bramble.api.db.TransactionManager @@ -30,6 +31,7 @@ import org.briarproject.briar.api.forum.ForumManager import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.utils.clearAndAddAll import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel +import org.briarproject.briar.desktop.viewmodel.asState import javax.inject.Inject class ForumsViewModel @@ -43,11 +45,19 @@ constructor( ) : EventListenerDbViewModel(briarExecutors, lifecycleManager, db, eventBus) { private val _fullGroupList = mutableStateListOf<ForumsItem>() - val groupList: List<ForumsItem> = _fullGroupList + val groupList = derivedStateOf { + val filter = _filterBy.value + _fullGroupList.filter { item -> + item.name.contains(filter, ignoreCase = true) + }.sortedByDescending { it.timestamp } + } private val _selectedGroupId = mutableStateOf<GroupId?>(null) val selectedGroupId: State<GroupId?> = _selectedGroupId + private val _filterBy = mutableStateOf("") + val filterBy = _filterBy.asState() + override fun onInit() { super.onInit() loadGroups() @@ -76,4 +86,8 @@ constructor( } fun isSelected(privateGroupId: GroupId) = _selectedGroupId.value == privateGroupId + + fun setFilterBy(filter: String) { + _filterBy.value = filter + } } diff --git a/briar-desktop/src/main/resources/strings/BriarDesktop.properties b/briar-desktop/src/main/resources/strings/BriarDesktop.properties index f82aa0b2a7..47f782afa9 100644 --- a/briar-desktop/src/main/resources/strings/BriarDesktop.properties +++ b/briar-desktop/src/main/resources/strings/BriarDesktop.properties @@ -101,6 +101,7 @@ conversation.change.alias.dialog.title=Change contact name conversation.change.alias.dialog.description=Please enter a new name for this contact (only visible to you): # Forums +forum.search.title=Forums group.card.posts={0, plural, one {{0} post} other {{0} posts}} # Private Groups -- GitLab