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

update ContactItem on events

parent 88a9fe6d
No related branches found
No related tags found
1 merge request!33Finish view model for contact list
......@@ -31,7 +31,6 @@ fun ContactCard(
contactItem: ContactItem,
onSel: () -> Unit,
selected: Boolean,
drawNotifications: Boolean
) {
val bgColor = if (selected) MaterialTheme.colors.selectedCard else MaterialTheme.colors.surfaceVariant
val outlineColor = MaterialTheme.colors.outline
......@@ -50,7 +49,7 @@ fun ContactCard(
// TODO Pull profile pictures
ProfileCircle(36.dp, contactItem.contact.author.id.bytes)
// Draw notification badges
if (drawNotifications) {
if (contactItem.unread > 0) {
Canvas(
modifier = Modifier.align(Alignment.CenterVertically),
onDraw = {
......
......@@ -2,15 +2,37 @@ package org.briarproject.briar.desktop.contact
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.briar.api.client.MessageTracker
import org.briarproject.briar.api.conversation.ConversationMessageHeader
import org.briarproject.briar.api.identity.AuthorInfo
import kotlin.math.max
data class ContactItem(
val contact: Contact,
private val authorInfo: AuthorInfo,
private val groupCount: MessageTracker.GroupCount,
val isConnected: Boolean,
private val groupCount: MessageTracker.GroupCount
val isEmpty: Boolean = groupCount.msgCount == 0,
val unread: Int = groupCount.unreadCount,
val timestamp: Long = groupCount.latestMsgTime
) {
val isEmpty = groupCount.msgCount == 0
val unread = groupCount.unreadCount
val timestamp = groupCount.latestMsgTime
fun updateFromMessageHeader(h: ConversationMessageHeader): ContactItem {
return copy(
isEmpty = false,
unread = if (h.isRead) unread else unread + 1,
timestamp = max(h.timestamp, timestamp)
)
}
fun updateIsConnected(c: Boolean): ContactItem {
return copy(isConnected = c)
}
fun updateAlias(a: String?): ContactItem {
return copy(contact = contact.updateAlias(a))
}
private fun Contact.updateAlias(a: String?): Contact {
return Contact(id, author, localAuthorId, a, handshakePublicKey, isVerified)
}
}
......@@ -38,7 +38,7 @@ fun ContactList(
content = {
LazyColumn {
itemsIndexed(viewModel.contactList) { index, contactItem ->
ContactCard(contactItem, { viewModel.selectContact(index) }, viewModel.isSelected(index), true)
ContactCard(contactItem, { viewModel.selectContact(index) }, viewModel.isSelected(index))
}
}
},
......
......@@ -5,13 +5,25 @@ import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import org.briarproject.bramble.api.FormatException
import org.briarproject.bramble.api.connection.ConnectionRegistry
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.contact.event.ContactAddedEvent
import org.briarproject.bramble.api.contact.event.ContactAliasChangedEvent
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent
import org.briarproject.bramble.api.db.ContactExistsException
import org.briarproject.bramble.api.db.PendingContactExistsException
import org.briarproject.bramble.api.event.Event
import org.briarproject.bramble.api.event.EventBus
import org.briarproject.bramble.api.event.EventListener
import org.briarproject.bramble.api.identity.AuthorConstants
import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent
import org.briarproject.bramble.api.plugin.event.ContactDisconnectedEvent
import org.briarproject.bramble.util.StringUtils
import org.briarproject.briar.api.conversation.ConversationManager
import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent
import org.briarproject.briar.api.identity.AuthorManager
import org.briarproject.briar.desktop.utils.removeFirst
import org.briarproject.briar.desktop.utils.replaceFirst
import java.security.GeneralSecurityException
import java.util.logging.Logger
import javax.inject.Inject
......@@ -23,12 +35,18 @@ constructor(
private val authorManager: AuthorManager,
private val conversationManager: ConversationManager,
private val connectionRegistry: ConnectionRegistry,
) {
private val eventBus: EventBus,
) : EventListener {
companion object {
private val LOG = Logger.getLogger(ContactsViewModel::class.java.name)
}
init {
//todo: where/when to remove listener again?
eventBus.addListener(this)
}
private val _contactList = mutableListOf<ContactItem>()
private val _filteredContactList = mutableStateListOf<ContactItem>()
private val _filterBy = mutableStateOf("")
......@@ -55,12 +73,13 @@ constructor(
ContactItem(
contact,
authorManager.getAuthorInfo(contact),
connectionRegistry.isConnected(contact.id),
conversationManager.getGroupCount(contact.id)
conversationManager.getGroupCount(contact.id),
connectionRegistry.isConnected(contact.id)
)
})
}
updateFilteredList()
//todo: do in event instead?
addContactOwnLink = contactManager.handshakeLink
}
......@@ -148,4 +167,43 @@ constructor(
val aliasUtf8 = StringUtils.toUtf8(alias)
return aliasUtf8.isEmpty() || aliasUtf8.size > AuthorConstants.MAX_AUTHOR_NAME_LENGTH
}
override fun eventOccurred(e: Event?) {
when (e) {
is ContactAddedEvent -> {
LOG.info("Contact added, reloading")
loadContacts()
}
is ContactConnectedEvent -> {
LOG.info("Contact connected, update state")
updateItem(e.contactId) { it.updateIsConnected(true) }
}
is ContactDisconnectedEvent -> {
LOG.info("Contact disconnected, update state")
updateItem(e.contactId) { it.updateIsConnected(false) }
}
is ContactRemovedEvent -> {
LOG.info("Contact removed, removing item")
removeItem(e.contactId)
}
is ConversationMessageReceivedEvent<*> -> {
LOG.info("Conversation message received, updating item")
updateItem(e.contactId) { it.updateFromMessageHeader(e.messageHeader) }
}
//is AvatarUpdatedEvent -> {}
is ContactAliasChangedEvent -> {
updateItem(e.contactId) { it.updateAlias(e.alias) }
}
}
}
private fun updateItem(contactId: ContactId, update: (ContactItem) -> ContactItem) {
_contactList.replaceFirst({ it.contact.id == contactId }, update)
updateFilteredList()
}
private fun removeItem(contactId: ContactId) {
_contactList.removeFirst { it.contact.id == contactId }
updateFilteredList()
}
}
package org.briarproject.briar.desktop.utils
fun <T> MutableList<T>.replaceFirst(predicate: (T) -> Boolean, transformation: (T) -> T) {
val li = listIterator()
while (li.hasNext()) {
val n = li.next()
if (predicate(n)) {
li.set(transformation(n))
break
}
}
}
fun <T> MutableList<T>.removeFirst(predicate: (T) -> Boolean) {
val li = listIterator()
while (li.hasNext()) {
val n = li.next()
if (predicate(n)) {
li.remove()
break
}
}
}
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