diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt index f47505f6872e77ccb7717723c4cac6b3a85061b6..2d4080b4ed442b9db065a1b60b79262cb9f2e68c 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt @@ -14,10 +14,12 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent import org.briarproject.briar.api.conversation.ConversationManager +import org.briarproject.briar.desktop.utils.clearAndAddAll import org.briarproject.briar.desktop.utils.removeFirst import org.briarproject.briar.desktop.utils.replaceFirst import org.briarproject.briar.desktop.viewmodel.BriarExecutors import org.briarproject.briar.desktop.viewmodel.EventListenerDbViewModel +import org.briarproject.briar.desktop.viewmodel.UiExecutor abstract class ContactsViewModel( protected val contactManager: ContactManager, @@ -41,27 +43,32 @@ abstract class ContactsViewModel( protected open fun filterContactItem(contactItem: ContactItem) = true open fun loadContacts() { - _fullContactList.apply { - clear() - addAll( - contactManager.contacts.map { contact -> + loadOnDbThreadWithTransaction( + task = { txn -> + contactManager.getContacts(txn).map { contact -> ContactItem( contact, connectionRegistry.isConnected(contact.id), - conversationManager.getGroupCount(contact.id), + conversationManager.getGroupCount(txn, contact.id), ) } - ) - } - updateFilteredList() + }, + onResult = { contactList -> + _fullContactList.clearAndAddAll(contactList) + updateFilteredList() + }, + onError = { e -> + LOG.error("Error while loading contacts", e) + } + ) } // todo: when migrated to StateFlow, this could be done implicitly instead + @UiExecutor protected open fun updateFilteredList() { - _filteredContactList.apply { - clear() - addAll(_fullContactList.filter(::filterContactItem).sortedByDescending { it.timestamp }) - } + _filteredContactList.clearAndAddAll( + _fullContactList.filter(::filterContactItem).sortedByDescending { it.timestamp } + ) } override fun eventOccurred(e: Event?) { @@ -85,11 +92,13 @@ abstract class ContactsViewModel( } } + @UiExecutor protected open fun updateItem(contactId: ContactId, update: (ContactItem) -> ContactItem) { _fullContactList.replaceFirst({ it.contactId == contactId }, update) updateFilteredList() } + @UiExecutor protected open fun removeItem(contactId: ContactId) { _fullContactList.removeFirst { it.contactId == contactId } updateFilteredList() diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/ListUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/ListUtils.kt index 5f4b3cd60976c37d7bb95ecfcf8bef46ce72024e..0ca3ae7a713f35af520fb738f6619628c70ac9d5 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/utils/ListUtils.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/ListUtils.kt @@ -1,5 +1,10 @@ package org.briarproject.briar.desktop.utils +fun <T> MutableList<T>.clearAndAddAll(elements: Collection<T>) { + clear() + addAll(elements) +} + fun <T> MutableList<T>.replaceIf(predicate: (T) -> Boolean, transformation: (T) -> T) { val li = listIterator() while (li.hasNext()) {