Skip to content
Snippets Groups Projects
Verified Commit dc26e76e authored by Mikolai Gütschow's avatar Mikolai Gütschow
Browse files

move contact list filtering to view model

parent 7aeb9788
No related branches found
No related tags found
1 merge request!33Finish view model for contact list
...@@ -31,7 +31,6 @@ import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp ...@@ -31,7 +31,6 @@ import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp
@Composable @Composable
fun ContactCard( fun ContactCard(
contact: Contact, contact: Contact,
selContact: Contact,
onSel: (Contact) -> Unit, onSel: (Contact) -> Unit,
selected: Boolean, selected: Boolean,
drawNotifications: Boolean drawNotifications: Boolean
......
...@@ -57,7 +57,7 @@ fun ContactDrawerMakeIntro(contact: Contact, contacts: List<Contact>, setInfoDra ...@@ -57,7 +57,7 @@ fun ContactDrawerMakeIntro(contact: Contact, contacts: List<Contact>, setInfoDra
Column(Modifier.verticalScroll(rememberScrollState())) { Column(Modifier.verticalScroll(rememberScrollState())) {
for (c in contacts) { for (c in contacts) {
if (c.id != contact.id) { if (c.id != contact.id) {
ContactCard(c, contact, { onCancelSel(c); introNextPg = true }, false, false) ContactCard(c, { onCancelSel(c); introNextPg = true }, false, false)
} }
} }
} }
......
...@@ -5,41 +5,22 @@ import androidx.compose.foundation.layout.fillMaxHeight ...@@ -5,41 +5,22 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.briar.desktop.theme.surfaceVariant import org.briarproject.briar.desktop.theme.surfaceVariant
import org.briarproject.briar.desktop.ui.Constants.CONTACTLIST_WIDTH import org.briarproject.briar.desktop.ui.Constants.CONTACTLIST_WIDTH
import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
@Composable @Composable
fun ContactList( fun ContactList(
contact: Contact, contacts: ContactsViewModel,
contacts: List<Contact>, onContactAdd: () -> Unit,
onContactSelect: (Contact) -> Unit,
onContactAdd: (Boolean) -> Unit
) { ) {
var searchValue by remember { mutableStateOf("") }
val filteredContacts = if (searchValue.isEmpty()) {
ArrayList(contacts)
} else {
val resultList = ArrayList<Contact>()
for (c in contacts) {
if (c.author.name.lowercase().contains(searchValue.lowercase())) {
resultList.add(c)
}
}
resultList
}
Scaffold( Scaffold(
modifier = Modifier.fillMaxHeight().width(CONTACTLIST_WIDTH), modifier = Modifier.fillMaxHeight().width(CONTACTLIST_WIDTH),
backgroundColor = MaterialTheme.colors.surfaceVariant, backgroundColor = MaterialTheme.colors.surfaceVariant,
...@@ -47,13 +28,17 @@ fun ContactList( ...@@ -47,13 +28,17 @@ fun ContactList(
Column( Column(
modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp), modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp),
) { ) {
SearchTextField(searchValue, onValueChange = { searchValue = it }, onContactAdd) SearchTextField(
contacts.filterBy.value,
onValueChange = contacts::setFilterBy,
onContactAdd
)
} }
}, },
content = { content = {
Column(Modifier.verticalScroll(rememberScrollState())) { LazyColumn {
for (c in filteredContacts) { itemsIndexed(contacts.contactList) { index, contact ->
ContactCard(c, contact, onContactSelect, contact.id == c.id, true) ContactCard(contact, { contacts.selectContact(index) }, contacts.isSelected(index), true)
} }
} }
}, },
......
package org.briarproject.briar.desktop.contact package org.briarproject.briar.desktop.contact
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import org.briarproject.bramble.api.contact.Contact import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactManager import org.briarproject.bramble.api.contact.ContactManager
import java.util.logging.Logger import java.util.logging.Logger
...@@ -16,17 +18,43 @@ constructor( ...@@ -16,17 +18,43 @@ constructor(
private val LOG = Logger.getLogger(ContactsViewModel::class.java.name) private val LOG = Logger.getLogger(ContactsViewModel::class.java.name)
} }
internal val contacts = mutableStateListOf<Contact>() private val _contactList = mutableListOf<Contact>()
private val _filteredContactList = mutableStateListOf<Contact>()
private val _filterBy = mutableStateOf("")
private var _selectedContactIndex = -1;
private val _selectedContact = mutableStateOf<Contact?>(null)
val contactList: List<Contact> = _filteredContactList
val filterBy: State<String> = _filterBy
val selectedContact: State<Contact?> = _selectedContact
internal fun loadContacts() { internal fun loadContacts() {
val contacts = contactManager.contacts _contactList.apply {
for (contact in contacts) { clear()
LOG.info("loaded contact: ${contact.author.name} (${contact.alias})") addAll(contactManager.contacts)
this.contacts.add(contact) }
updateFilteredList()
}
fun selectContact(index: Int) {
_selectedContactIndex = index
_selectedContact.value = _filteredContactList[index]
}
fun isSelected(index: Int) = _selectedContactIndex == index
private fun updateFilteredList() {
_filteredContactList.apply {
clear()
addAll(_contactList.filter {
// todo: also filter on alias?
it.author.name.lowercase().contains(_filterBy.value)
})
} }
} }
fun getFirst(): Contact? { fun setFilterBy(filter: String) {
return if (contacts.isEmpty()) null else contacts[0] _filterBy.value = filter
updateFilteredList()
} }
} }
...@@ -22,7 +22,7 @@ import androidx.compose.ui.unit.dp ...@@ -22,7 +22,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@Composable @Composable
fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onContactAdd: (Boolean) -> Unit) { fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onContactAdd: () -> Unit) {
TextField( TextField(
value = searchValue, value = searchValue,
onValueChange = onValueChange, onValueChange = onValueChange,
...@@ -36,7 +36,7 @@ fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onCont ...@@ -36,7 +36,7 @@ fun SearchTextField(searchValue: String, onValueChange: (String) -> Unit, onCont
}, },
trailingIcon = { trailingIcon = {
IconButton( IconButton(
onClick = { onContactAdd(true) }, onClick = onContactAdd,
modifier = Modifier.padding(end = 10.dp).size(32.dp) modifier = Modifier.padding(end = 10.dp).size(32.dp)
.background(MaterialTheme.colors.primary, CircleShape) .background(MaterialTheme.colors.primary, CircleShape)
) { ) {
......
...@@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable ...@@ -8,7 +8,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.briar.desktop.contact.AddContactDialog import org.briarproject.briar.desktop.contact.AddContactDialog
import org.briarproject.briar.desktop.contact.ContactInfoDrawerState.MakeIntro import org.briarproject.briar.desktop.contact.ContactInfoDrawerState.MakeIntro
import org.briarproject.briar.desktop.contact.ContactList import org.briarproject.briar.desktop.contact.ContactList
...@@ -17,9 +16,7 @@ import org.briarproject.briar.desktop.ui.VerticalDivider ...@@ -17,9 +16,7 @@ import org.briarproject.briar.desktop.ui.VerticalDivider
@Composable @Composable
fun PrivateMessageView( fun PrivateMessageView(
contact: Contact,
contacts: ContactsViewModel, contacts: ContactsViewModel,
onContactSelect: (Contact) -> Unit
) { ) {
val (isDialogVisible, setDialogVisibility) = remember { mutableStateOf(false) } val (isDialogVisible, setDialogVisibility) = remember { mutableStateOf(false) }
val (dropdownExpanded, setExpanded) = remember { mutableStateOf(false) } val (dropdownExpanded, setExpanded) = remember { mutableStateOf(false) }
...@@ -27,18 +24,20 @@ fun PrivateMessageView( ...@@ -27,18 +24,20 @@ fun PrivateMessageView(
val (contactDrawerState, setDrawerState) = remember { mutableStateOf(MakeIntro) } val (contactDrawerState, setDrawerState) = remember { mutableStateOf(MakeIntro) }
AddContactDialog(isDialogVisible, setDialogVisibility) AddContactDialog(isDialogVisible, setDialogVisibility)
Row(modifier = Modifier.fillMaxWidth()) { Row(modifier = Modifier.fillMaxWidth()) {
ContactList(contact, contacts.contacts, onContactSelect, setDialogVisibility) ContactList(contacts) { setDialogVisibility(true) }
VerticalDivider() VerticalDivider()
Column(modifier = Modifier.weight(1f).fillMaxHeight()) { Column(modifier = Modifier.weight(1f).fillMaxHeight()) {
Conversation( contacts.selectedContact.value?.let { selectedContact ->
contact, Conversation(
contacts.contacts, selectedContact,
dropdownExpanded, contacts.contactList,
setExpanded, dropdownExpanded,
infoDrawer, setExpanded,
setInfoDrawer, infoDrawer,
contactDrawerState setInfoDrawer,
) contactDrawerState
)
}
} }
} }
} }
...@@ -28,19 +28,12 @@ fun MainScreen( ...@@ -28,19 +28,12 @@ fun MainScreen(
) { ) {
// current selected mode, changed using the sidebar buttons // current selected mode, changed using the sidebar buttons
val (uiMode, setUiMode) = remember { mutableStateOf(UiMode.CONTACTS) } val (uiMode, setUiMode) = remember { mutableStateOf(UiMode.CONTACTS) }
// TODO Figure out how to handle accounts with 0 contacts
// current selected contact
val (contact, setContact) = remember { mutableStateOf(contactsViewModel.getFirst()) }
// Other global state that we need to track should go here also // Other global state that we need to track should go here also
Row { Row {
BriarSidebar(uiMode, setUiMode) BriarSidebar(uiMode, setUiMode)
VerticalDivider() VerticalDivider()
when (uiMode) { when (uiMode) {
UiMode.CONTACTS -> if (contact != null) PrivateMessageView( UiMode.CONTACTS -> PrivateMessageView(contactsViewModel)
contact,
contactsViewModel,
setContact
)
UiMode.SETTINGS -> PlaceHolderSettingsView(isDark, setDark) UiMode.SETTINGS -> PlaceHolderSettingsView(isDark, setDark)
else -> Surface(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.background)) { else -> Surface(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.background)) {
Text("TBD") Text("TBD")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment