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

use ContactItem for UI representation of Contact

parent 021283f5
No related branches found
No related tags found
1 merge request!33Finish view model for contact list
...@@ -19,19 +19,17 @@ import androidx.compose.ui.Modifier ...@@ -19,19 +19,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.drawscope.withTransform import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.briar.desktop.theme.outline import org.briarproject.briar.desktop.theme.outline
import org.briarproject.briar.desktop.theme.selectedCard import org.briarproject.briar.desktop.theme.selectedCard
import org.briarproject.briar.desktop.theme.surfaceVariant import org.briarproject.briar.desktop.theme.surfaceVariant
import org.briarproject.briar.desktop.ui.CVM
import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE
import org.briarproject.briar.desktop.ui.HorizontalDivider import org.briarproject.briar.desktop.ui.HorizontalDivider
import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp
@Composable @Composable
fun ContactCard( fun ContactCard(
contact: Contact, contactItem: ContactItem,
onSel: (Contact) -> Unit, onSel: () -> Unit,
selected: Boolean, selected: Boolean,
drawNotifications: Boolean drawNotifications: Boolean
) { ) {
...@@ -42,7 +40,7 @@ fun ContactCard( ...@@ -42,7 +40,7 @@ fun ContactCard(
val briarSurfaceVar = MaterialTheme.colors.surfaceVariant val briarSurfaceVar = MaterialTheme.colors.surfaceVariant
Card( Card(
modifier = Modifier.fillMaxWidth().height(HEADER_SIZE).clickable(onClick = { onSel(contact) }), modifier = Modifier.fillMaxWidth().height(HEADER_SIZE).clickable(onClick = onSel),
shape = RoundedCornerShape(0.dp), shape = RoundedCornerShape(0.dp),
backgroundColor = bgColor, backgroundColor = bgColor,
contentColor = MaterialTheme.colors.onSurface contentColor = MaterialTheme.colors.onSurface
...@@ -50,7 +48,7 @@ fun ContactCard( ...@@ -50,7 +48,7 @@ fun ContactCard(
Row(horizontalArrangement = Arrangement.SpaceBetween) { Row(horizontalArrangement = Arrangement.SpaceBetween) {
Row(modifier = Modifier.align(Alignment.CenterVertically).padding(horizontal = 16.dp)) { Row(modifier = Modifier.align(Alignment.CenterVertically).padding(horizontal = 16.dp)) {
// TODO Pull profile pictures // TODO Pull profile pictures
ProfileCircle(36.dp, contact.author.id.bytes) ProfileCircle(36.dp, contactItem.contact.author.id.bytes)
// Draw notification badges // Draw notification badges
if (drawNotifications) { if (drawNotifications) {
Canvas( Canvas(
...@@ -66,13 +64,12 @@ fun ContactCard( ...@@ -66,13 +64,12 @@ fun ContactCard(
} }
Column(modifier = Modifier.align(Alignment.CenterVertically).padding(start = 12.dp)) { Column(modifier = Modifier.align(Alignment.CenterVertically).padding(start = 12.dp)) {
Text( Text(
contact.author.name, contactItem.contact.author.name,
fontSize = 14.sp, fontSize = 14.sp,
modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp) modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp)
) )
val latestMsgTime = CVM.current.getGroupCount(contact.id).latestMsgTime
Text( Text(
getFormattedTimestamp(latestMsgTime), if (contactItem.isEmpty) "No messages." else getFormattedTimestamp(contactItem.timestamp),
fontSize = 10.sp, fontSize = 10.sp,
modifier = Modifier.align(Alignment.Start) modifier = Modifier.align(Alignment.Start)
) )
...@@ -81,14 +78,12 @@ fun ContactCard( ...@@ -81,14 +78,12 @@ fun ContactCard(
Canvas( Canvas(
modifier = Modifier.padding(start = 32.dp, end = 18.dp).size(22.dp).align(Alignment.CenterVertically), modifier = Modifier.padding(start = 32.dp, end = 18.dp).size(22.dp).align(Alignment.CenterVertically),
onDraw = { onDraw = {
val size = 16.dp.toPx() val size = 16.dp
drawCircle(color = outlineColor, radius = size / 2f) drawCircle(color = outlineColor, radius = size.toPx() / 2f)
// TODO check if contact online drawCircle(
if (true) { color = if (contactItem.isConnected) briarSecondary else briarSurfaceVar,
drawCircle(color = briarSecondary, radius = 14.dp.toPx() / 2f) radius = (size - 2.dp).toPx() / 2f
} else { )
drawCircle(color = briarSurfaceVar, radius = 14.dp.toPx() / 2f)
}
} }
) )
} }
......
...@@ -57,7 +57,8 @@ fun ContactDrawerMakeIntro(contact: Contact, contacts: List<Contact>, setInfoDra ...@@ -57,7 +57,8 @@ 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, { onCancelSel(c); introNextPg = true }, false, false) // todo: refactor to use contactItem in IntroductionViewModel
//ContactCard(c, { onCancelSel(c); introNextPg = true }, false, false)
} }
} }
} }
......
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.identity.AuthorInfo
data class ContactItem(
val contact: Contact,
private val authorInfo: AuthorInfo,
val isConnected: Boolean,
private val groupCount: MessageTracker.GroupCount
) {
val isEmpty = groupCount.msgCount == 0
val unread = groupCount.unreadCount
val timestamp = groupCount.latestMsgTime
}
...@@ -37,8 +37,8 @@ fun ContactList( ...@@ -37,8 +37,8 @@ fun ContactList(
}, },
content = { content = {
LazyColumn { LazyColumn {
itemsIndexed(viewModel.contactList) { index, contact -> itemsIndexed(viewModel.contactList) { index, contactItem ->
ContactCard(contact, { viewModel.selectContact(index) }, viewModel.isSelected(index), true) ContactCard(contactItem, { viewModel.selectContact(index) }, viewModel.isSelected(index), true)
} }
} }
}, },
......
...@@ -4,12 +4,14 @@ import androidx.compose.runtime.State ...@@ -4,12 +4,14 @@ import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import org.briarproject.bramble.api.FormatException import org.briarproject.bramble.api.FormatException
import org.briarproject.bramble.api.contact.Contact import org.briarproject.bramble.api.connection.ConnectionRegistry
import org.briarproject.bramble.api.contact.ContactManager import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.db.ContactExistsException import org.briarproject.bramble.api.db.ContactExistsException
import org.briarproject.bramble.api.db.PendingContactExistsException import org.briarproject.bramble.api.db.PendingContactExistsException
import org.briarproject.bramble.api.identity.AuthorConstants import org.briarproject.bramble.api.identity.AuthorConstants
import org.briarproject.bramble.util.StringUtils import org.briarproject.bramble.util.StringUtils
import org.briarproject.briar.api.conversation.ConversationManager
import org.briarproject.briar.api.identity.AuthorManager
import java.security.GeneralSecurityException import java.security.GeneralSecurityException
import java.util.logging.Logger import java.util.logging.Logger
import javax.inject.Inject import javax.inject.Inject
...@@ -18,37 +20,48 @@ class ContactsViewModel ...@@ -18,37 +20,48 @@ class ContactsViewModel
@Inject @Inject
constructor( constructor(
private val contactManager: ContactManager, private val contactManager: ContactManager,
private val authorManager: AuthorManager,
private val conversationManager: ConversationManager,
private val connectionRegistry: ConnectionRegistry,
) { ) {
companion object { companion object {
private val LOG = Logger.getLogger(ContactsViewModel::class.java.name) private val LOG = Logger.getLogger(ContactsViewModel::class.java.name)
} }
private val _contactList = mutableListOf<Contact>() private val _contactList = mutableListOf<ContactItem>()
private val _filteredContactList = mutableStateListOf<Contact>() private val _filteredContactList = mutableStateListOf<ContactItem>()
private val _filterBy = mutableStateOf("") private val _filterBy = mutableStateOf("")
private var _selectedContactIndex = -1; private var _selectedContactIndex = -1;
private val _selectedContact = mutableStateOf<Contact?>(null) private val _selectedContact = mutableStateOf<ContactItem?>(null)
private val _addContactDialogVisible = mutableStateOf(false) private val _addContactDialogVisible = mutableStateOf(false)
private val _addContactAlias = mutableStateOf("") private val _addContactAlias = mutableStateOf("")
private val _addContactLink = mutableStateOf("") private val _addContactLink = mutableStateOf("")
val contactList: List<Contact> = _filteredContactList val contactList: List<ContactItem> = _filteredContactList
val filterBy: State<String> = _filterBy val filterBy: State<String> = _filterBy
val selectedContact: State<Contact?> = _selectedContact val selectedContact: State<ContactItem?> = _selectedContact
val addContactDialogVisible: State<Boolean> = _addContactDialogVisible val addContactDialogVisible: State<Boolean> = _addContactDialogVisible
val addContactAlias: State<String> = _addContactAlias val addContactAlias: State<String> = _addContactAlias
val addContactLink: State<String> = _addContactLink val addContactLink: State<String> = _addContactLink
val addContactOwnLink = contactManager.handshakeLink var addContactOwnLink = ""
internal fun loadContacts() { internal fun loadContacts() {
_contactList.apply { _contactList.apply {
clear() clear()
addAll(contactManager.contacts) addAll(contactManager.contacts.map { contact ->
ContactItem(
contact,
authorManager.getAuthorInfo(contact),
connectionRegistry.isConnected(contact.id),
conversationManager.getGroupCount(contact.id)
)
})
} }
updateFilteredList() updateFilteredList()
addContactOwnLink = contactManager.handshakeLink
} }
fun selectContact(index: Int) { fun selectContact(index: Int) {
...@@ -63,7 +76,7 @@ constructor( ...@@ -63,7 +76,7 @@ constructor(
clear() clear()
addAll(_contactList.filter { addAll(_contactList.filter {
// todo: also filter on alias? // todo: also filter on alias?
it.author.name.lowercase().contains(_filterBy.value) it.contact.author.name.lowercase().contains(_filterBy.value)
}) })
} }
} }
......
...@@ -27,8 +27,8 @@ fun PrivateMessageView( ...@@ -27,8 +27,8 @@ fun PrivateMessageView(
Column(modifier = Modifier.weight(1f).fillMaxHeight()) { Column(modifier = Modifier.weight(1f).fillMaxHeight()) {
contacts.selectedContact.value?.also { selectedContact -> contacts.selectedContact.value?.also { selectedContact ->
Conversation( Conversation(
selectedContact, selectedContact.contact,
contacts.contactList, contacts.contactList.map { c -> c.contact },
dropdownExpanded, dropdownExpanded,
setExpanded, setExpanded,
infoDrawer, infoDrawer,
......
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