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

unify filter approach in view models, fix selection of contacts after filtering the list

parent 2cbc4d42
No related branches found
No related tags found
1 merge request!33Finish view model for contact list
Pipeline #7950 passed
......@@ -6,7 +6,7 @@ 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.itemsIndexed
import androidx.compose.foundation.lazy.items
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.runtime.Composable
......@@ -45,8 +45,12 @@ fun ContactList(
},
content = {
LazyColumn {
itemsIndexed(viewModel.contactList) { index, contactItem ->
ContactCard(contactItem, { viewModel.selectContact(index) }, viewModel.isSelected(index))
items(viewModel.contactList) { contactItem ->
ContactCard(
contactItem,
{ viewModel.selectContact(contactItem.contact) },
viewModel.isSelected(contactItem.contact)
)
}
}
},
......
package org.briarproject.briar.desktop.contact
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import org.briarproject.bramble.api.connection.ConnectionRegistry
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.contact.event.ContactAliasChangedEvent
import org.briarproject.bramble.api.event.Event
......@@ -32,44 +31,32 @@ constructor(
eventBus.addListener(this)
}
private val _filteredContactList = mutableStateListOf<ContactItem>()
private val _filterBy = mutableStateOf("")
private var _selectedContactIndex = -1
private val _selectedContact = mutableStateOf<ContactItem?>(null)
private val _selectedContact = mutableStateOf<Contact?>(null)
override val contactList: List<ContactItem> = _filteredContactList
val filterBy: State<String> = _filterBy
val selectedContact: State<ContactItem?> = _selectedContact
val selectedContact: State<Contact?> = _selectedContact
override fun loadContacts() {
super.loadContacts()
updateFilteredList()
fun selectContact(contact: Contact) {
_selectedContact.value = contact
}
fun selectContact(index: Int) {
_selectedContactIndex = index
_selectedContact.value = _filteredContactList[index]
}
fun isSelected(contact: Contact) = _selectedContact.value?.id == contact.id
fun isSelected(index: Int) = _selectedContactIndex == index
private fun updateFilteredList() {
_filteredContactList.apply {
clear()
addAll(
_contactList.filter {
// todo: also filter on alias?
it.contact.author.name.lowercase().contains(_filterBy.value)
}
)
}
}
override fun filterContact(contact: Contact) =
// todo: also filter on alias
contact.author.name.contains(_filterBy.value, ignoreCase = true)
fun setFilterBy(filter: String) {
_filterBy.value = filter
updateFilteredList()
}
override fun updateFilteredList() {
super.updateFilteredList()
_selectedContact.value?.let { if (!filterContact(it)) _selectedContact.value = null }
}
override fun eventOccurred(e: Event?) {
super.eventOccurred(e)
when (e) {
......@@ -83,14 +70,4 @@ constructor(
}
}
}
override fun updateItem(contactId: ContactId, update: (ContactItem) -> ContactItem) {
super.updateItem(contactId, update)
updateFilteredList()
}
override fun removeItem(contactId: ContactId) {
super.removeItem(contactId)
updateFilteredList()
}
}
package org.briarproject.briar.desktop.contact
import androidx.compose.runtime.mutableStateListOf
import org.briarproject.bramble.api.connection.ConnectionRegistry
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactId
......@@ -25,17 +26,18 @@ abstract class ContactsViewModel(
private val LOG = Logger.getLogger(ContactsViewModel::class.java.name)
}
protected val _contactList = mutableListOf<ContactItem>()
private val _fullContactList = mutableListOf<ContactItem>()
private val _filteredContactList = mutableStateListOf<ContactItem>()
abstract val contactList: List<ContactItem>
val contactList: List<ContactItem> = _filteredContactList
protected open fun filterContact(contact: Contact) = true
open fun loadContacts() {
_contactList.apply {
_fullContactList.apply {
clear()
addAll(
contactManager.contacts.filter(::filterContact).map { contact ->
contactManager.contacts.map { contact ->
ContactItem(
contact,
connectionRegistry.isConnected(contact.id),
......@@ -44,6 +46,15 @@ abstract class ContactsViewModel(
}
)
}
updateFilteredList()
}
// todo: when migrated to StateFlow, this could be done implicitly instead
protected open fun updateFilteredList() {
_filteredContactList.apply {
clear()
addAll(_fullContactList.filter { filterContact(it.contact) })
}
}
override fun eventOccurred(e: Event?) {
......@@ -68,10 +79,12 @@ abstract class ContactsViewModel(
}
protected open fun updateItem(contactId: ContactId, update: (ContactItem) -> ContactItem) {
_contactList.replaceFirst({ it.contact.id == contactId }, update)
_fullContactList.replaceFirst({ it.contact.id == contactId }, update)
updateFilteredList()
}
protected open fun removeItem(contactId: ContactId) {
_contactList.removeFirst { it.contact.id == contactId }
_fullContactList.removeFirst { it.contact.id == contactId }
updateFilteredList()
}
}
......@@ -25,7 +25,7 @@ fun PrivateMessageView(
Column(modifier = Modifier.weight(1f).fillMaxHeight()) {
contactListViewModel.selectedContact.value?.also { selectedContact ->
Conversation(
selectedContact.contact,
selectedContact,
introductionViewModel
)
} ?: UiPlaceholder()
......
......@@ -7,7 +7,6 @@ import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.event.EventBus
import org.briarproject.briar.api.conversation.ConversationManager
import org.briarproject.briar.desktop.contact.ContactItem
import org.briarproject.briar.desktop.contact.ContactsViewModel
import java.util.logging.Logger
import javax.inject.Inject
......@@ -35,7 +34,6 @@ constructor(
private val _secondScreen = mutableStateOf(false)
private val _introductionMessage = mutableStateOf("")
override val contactList: List<ContactItem> = _contactList
val firstContact: State<Contact?> = _firstContact
val secondContact: State<Contact?> = _secondContact
val secondScreen: State<Boolean> = _secondScreen
......@@ -54,6 +52,7 @@ constructor(
fun backToFirstScreen() {
_secondScreen.value = false
_introductionMessage.value = ""
}
fun setIntroductionMessage(msg: String) {
......@@ -61,6 +60,6 @@ constructor(
}
override fun filterContact(contact: Contact): Boolean {
return _firstContact.value!!.id != contact.id
return _firstContact.value?.id != contact.id
}
}
......@@ -104,7 +104,6 @@ constructor(
when (screenState) {
Screen.REGISTRATION ->
Registration(registrationViewModel) {
contactListViewModel.loadContacts()
screenState = Screen.MAIN
}
Screen.LOGIN ->
......
  • Nico @nico

    mentioned in commit 5bfcc450

    ·

    mentioned in commit 5bfcc450

    Toggle commit list
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