diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt index 911a05eec12604178e961ae9ec1b5489ed6919d6..2ac199acf78194d66dd3a23dd60c9b52efa298ca 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactCard.kt @@ -6,8 +6,10 @@ import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset @@ -48,7 +50,7 @@ fun main() = preview( "selected" to false, ) { ContactCard( - ContactItem( + RealContactItem( contactId = ContactId(0), authorId = AuthorId(getRandomId()), name = getStringParameter("name"), @@ -81,42 +83,18 @@ fun ContactCard( ) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Row(modifier = Modifier.align(Alignment.CenterVertically).padding(horizontal = 16.dp)) { - Box(modifier = Modifier.align(Alignment.CenterVertically)) { - // TODO Pull profile pictures - ProfileCircle(36.dp, contactItem.authorId.bytes) - // Draw new message counter - if (contactItem.unread > 0) { - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .offset(6.dp, (-6).dp) - .height(20.dp) - .widthIn(min = 20.dp, max = Dp.Infinity) - .border(2.dp, outlineColor, CircleShape) - .background(briarSecondary, CircleShape) - .padding(horizontal = 6.dp) - ) { - Text( - modifier = Modifier.align(Alignment.Center), - fontSize = 8.sp, - textAlign = TextAlign.Center, - text = contactItem.unread.toString(), - maxLines = 1 - ) - } + if (contactItem is RealContactItem) { + Box(modifier = Modifier.align(Alignment.CenterVertically)) { + // TODO Pull profile pictures + ProfileCircle(36.dp, contactItem.authorId.bytes) + MessageCounter(contactItem) } - } - Column(modifier = Modifier.align(Alignment.CenterVertically).padding(start = 12.dp)) { - Text( - contactItem.displayName, - fontSize = 14.sp, - modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp) - ) - Text( - if (contactItem.isEmpty) i18n("contacts.card.nothing") else getFormattedTimestamp(contactItem.timestamp), - fontSize = 10.sp, - modifier = Modifier.align(Alignment.Start) - ) + RealContactInfo(contactItem) + } else if (contactItem is PendingContactItem) { + Box(modifier = Modifier.align(Alignment.CenterVertically)) { + ProfileCircle(36.dp) + } + PendingContactInfo(contactItem) } } Canvas( @@ -134,3 +112,65 @@ fun ContactCard( } HorizontalDivider() } + +@Composable +fun BoxScope.MessageCounter(contactItem: ContactItem) { + val outlineColor = MaterialTheme.colors.outline + val briarSecondary = MaterialTheme.colors.secondary + if (contactItem.unread > 0) { + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .offset(6.dp, (-6).dp) + .height(20.dp) + .widthIn(min = 20.dp, max = Dp.Infinity) + .border(2.dp, outlineColor, CircleShape) + .background(briarSecondary, CircleShape) + .padding(horizontal = 6.dp) + ) { + Text( + modifier = Modifier.align(Alignment.Center), + fontSize = 8.sp, + textAlign = TextAlign.Center, + text = contactItem.unread.toString(), + maxLines = 1 + ) + } + } +} + +@Composable +fun RowScope.RealContactInfo(contactItem: RealContactItem) { + Column(modifier = Modifier.align(Alignment.CenterVertically).padding(start = 12.dp)) { + Text( + contactItem.displayName, + fontSize = 14.sp, + modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp) + ) + Text( + if (contactItem.isEmpty) i18n("contacts.card.nothing") else getFormattedTimestamp( + contactItem.timestamp + ), + fontSize = 10.sp, + modifier = Modifier.align(Alignment.Start) + ) + } +} + +@Composable +fun RowScope.PendingContactInfo(contactItem: PendingContactItem) { + Column(modifier = Modifier.align(Alignment.CenterVertically).padding(start = 12.dp)) { + Text( + contactItem.displayName, + fontSize = 14.sp, + modifier = Modifier.align(Alignment.Start).padding(bottom = 2.dp) + ) + Text( + if (contactItem.isEmpty) i18n("contacts.card.pending") else getFormattedTimestamp( + contactItem.timestamp + ), + fontSize = 10.sp, + modifier = Modifier.align(Alignment.Start) + ) + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactInfoDrawer.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactInfoDrawer.kt index 43462c4da9fe403ef300db44546669ca03b86490..e68c0c69a673e2628f50b655518a7c93efeb35e3 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactInfoDrawer.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactInfoDrawer.kt @@ -13,7 +13,7 @@ enum class ContactInfoDrawerState { @Composable fun ContactInfoDrawer( - contactItem: ContactItem, + contactItem: RealContactItem, setInfoDrawer: (Boolean) -> Unit, drawerState: ContactInfoDrawerState ) { diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt index 2ac68bc97de1277ad9e5176b913330398b2cb6a3..7509758e922afb0c223f5222b3a2dfe2fadfc080 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt @@ -1,51 +1,11 @@ package org.briarproject.briar.desktop.contact -import org.briarproject.bramble.api.contact.Contact -import org.briarproject.bramble.api.contact.ContactId -import org.briarproject.bramble.api.identity.AuthorId -import org.briarproject.briar.api.client.MessageTracker -import kotlin.math.max +sealed interface ContactItem { -data class ContactItem( - val contactId: ContactId, - val authorId: AuthorId, - val name: String, - val alias: String?, - val isConnected: Boolean, - val isEmpty: Boolean, - val unread: Int, + val contactId: Any + val displayName: String + val isConnected: Boolean + val isEmpty: Boolean + val unread: Int val timestamp: Long -) { - - val displayName = if (alias == null) name else "$alias ($name)" - - constructor(contact: Contact, isConnected: Boolean, groupCount: MessageTracker.GroupCount) : - this( - contactId = contact.id, - authorId = contact.author.id, - name = contact.author.name, - alias = contact.alias, - isConnected = isConnected, - isEmpty = groupCount.msgCount == 0, - unread = groupCount.unreadCount, - timestamp = groupCount.latestMsgTime - ) - - fun updateTimestampAndUnread(timestamp: Long, read: Boolean): ContactItem = - copy( - isEmpty = false, - unread = if (read) unread else unread + 1, - timestamp = max(timestamp, this.timestamp) - ) - - fun updateIsConnected(c: Boolean): ContactItem { - return copy(isConnected = c) - } - - fun updateAlias(a: String?): ContactItem { - return copy(alias = a) - } - - fun updateFromMessagesRead(c: Int): ContactItem = - copy(unread = unread - c) } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt index fd0d2957599f867b943d1134996179fd6cd8fbc0..66b96b6a6d2bc078e3775f5a325bae90b73084fb 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactList.kt @@ -16,7 +16,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import org.briarproject.bramble.api.contact.ContactId import org.briarproject.briar.desktop.contact.add.remote.AddContactDialog import org.briarproject.briar.desktop.theme.surfaceVariant import org.briarproject.briar.desktop.ui.Constants.CONTACTLIST_WIDTH @@ -25,8 +24,8 @@ import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE @Composable fun ContactList( contactList: List<ContactItem>, - isSelected: (ContactId) -> Boolean, - selectContact: (ContactId) -> Unit, + isSelected: (Any) -> Boolean, + selectContact: (Any) -> Unit, filterBy: String, setFilterBy: (String) -> Unit, ) { diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt index d4b8746edcf03768dac204f63d13f5bf7e4b674e..0e671a526743ca1bc5a6453facd1eab50667e481 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt @@ -3,7 +3,6 @@ package org.briarproject.briar.desktop.contact import androidx.compose.runtime.mutableStateOf import mu.KotlinLogging 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.ContactAliasChangedEvent import org.briarproject.bramble.api.db.TransactionManager @@ -41,16 +40,16 @@ constructor( } private val _filterBy = mutableStateOf("") - private val _selectedContactId = mutableStateOf<ContactId?>(null) + private val _selectedContactId = mutableStateOf<Any?>(null) val filterBy = _filterBy.asState() val selectedContactId = _selectedContactId.asState() - fun selectContact(contactId: ContactId) { + fun selectContact(contactId: Any) { _selectedContactId.value = contactId } - fun isSelected(contactId: ContactId) = _selectedContactId.value == contactId + fun isSelected(contactId: Any) = _selectedContactId.value == contactId override fun filterContactItem(contactItem: ContactItem) = contactItem.displayName.contains(_filterBy.value, ignoreCase = true) @@ -75,15 +74,26 @@ constructor( when (e) { is ConversationMessageTrackedEvent -> { LOG.info { "Conversation message tracked, updating item" } - updateItem(e.contactId) { it.updateTimestampAndUnread(e.timestamp, e.read) } + updateItem(e.contactId) { + if (it is RealContactItem) + it.updateTimestampAndUnread(e.timestamp, e.read) + else it + } } // is AvatarUpdatedEvent -> {} is ContactAliasChangedEvent -> { - updateItem(e.contactId) { it.updateAlias(e.alias) } + updateItem(e.contactId) { + if (it is RealContactItem) + it.updateAlias(e.alias) else it + } } is ConversationMessagesReadEvent -> { LOG.info("${e.count} conversation messages read, updating item") - updateItem(e.contactId) { it.updateFromMessagesRead(e.count) } + updateItem(e.contactId) { + if (it is RealContactItem) { + it.updateFromMessagesRead(e.count) + } else it + } } } } 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 564d9b2d5177e013088be1025c4df13d1d488efd..4fc4251f4d8a10f93c92fd05a7f5862739c5ab13 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactsViewModel.kt @@ -41,17 +41,28 @@ abstract class ContactsViewModel( protected open fun filterContactItem(contactItem: ContactItem) = true - open fun loadContacts() = runOnDbThreadWithTransaction(true) { txn -> - val contactList = contactManager.getContacts(txn).map { contact -> - ContactItem( - contact, - connectionRegistry.isConnected(contact.id), - conversationManager.getGroupCount(txn, contact.id), + open fun loadContacts() { + val contactList = mutableListOf<ContactItem>() + // TODO: move this inside transaction once briar has transactional method for this + contactList.addAll( + contactManager.pendingContacts.map { contact -> + PendingContactItem(contact.first) + } + ) + runOnDbThreadWithTransaction(true) { txn -> + contactList.addAll( + contactManager.getContacts(txn).map { contact -> + RealContactItem( + contact, + connectionRegistry.isConnected(contact.id), + conversationManager.getGroupCount(txn, contact.id), + ) + } ) - } - txn.attach { - _fullContactList.clearAndAddAll(contactList) - updateFilteredList() + txn.attach { + _fullContactList.clearAndAddAll(contactList) + updateFilteredList() + } } } @@ -70,11 +81,19 @@ abstract class ContactsViewModel( } is ContactConnectedEvent -> { LOG.info("Contact connected, update state") - updateItem(e.contactId) { it.updateIsConnected(true) } + updateItem(e.contactId) { + if (it is RealContactItem) + it.updateIsConnected(true) + else it + } } is ContactDisconnectedEvent -> { LOG.info("Contact disconnected, update state") - updateItem(e.contactId) { it.updateIsConnected(false) } + updateItem(e.contactId) { + if (it is RealContactItem) + it.updateIsConnected(false) + else it + } } is ContactRemovedEvent -> { LOG.info("Contact removed, removing item") @@ -84,12 +103,23 @@ abstract class ContactsViewModel( } protected open fun updateItem(contactId: ContactId, update: (ContactItem) -> ContactItem) { - _fullContactList.replaceFirst({ it.contactId == contactId }, update) + _fullContactList.replaceFirst( + { + if (it is RealContactItem) + it.contactId == contactId + else false + }, + update + ) updateFilteredList() } protected open fun removeItem(contactId: ContactId) { - _fullContactList.removeFirst { it.contactId == contactId } + _fullContactList.removeFirst { + if (it is RealContactItem) + it.contactId == contactId + else false + } updateFilteredList() } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/PendingContactItem.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/PendingContactItem.kt new file mode 100644 index 0000000000000000000000000000000000000000..1472c4c23d50c0ad0ba1b85624f73f404737b7b1 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/PendingContactItem.kt @@ -0,0 +1,31 @@ +package org.briarproject.briar.desktop.contact + +import org.briarproject.bramble.api.contact.PendingContact +import org.briarproject.bramble.api.contact.PendingContactId + +data class PendingContactItem( + override val contactId: PendingContactId, + val name: String, + val alias: String?, + override val isConnected: Boolean, + override val isEmpty: Boolean, + override val unread: Int, + override val timestamp: Long +) : ContactItem { + + override val displayName = if (alias == null) name else "$alias ($name)" + + constructor(contact: PendingContact) : this( + contactId = contact.id, + name = contact.alias, + alias = contact.alias, + isConnected = false, + isEmpty = true, + unread = 0, + timestamp = contact.timestamp + ) + + fun updateAlias(a: String?): PendingContactItem { + return copy(alias = a) + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ProfileCircle.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ProfileCircle.kt index e2fcbf24336dcbed7ecf24ba62fb52cb931eea22..34e723dafe870b63a8f552016aedfd6ec8052723 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ProfileCircle.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ProfileCircle.kt @@ -35,3 +35,13 @@ fun ProfileCircle(size: Dp, input: ByteArray) { Identicon(input, this.size.width, this.size.height).draw(this) } } + +/** + * Used for pending contacts. + */ +@Composable +fun ProfileCircle(size: Dp) { + Canvas(Modifier.size(size).clip(CircleShape).border(2.dp, MaterialTheme.colors.outline, CircleShape)) { + // TODO what to display here? + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/RealContactItem.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/RealContactItem.kt new file mode 100644 index 0000000000000000000000000000000000000000..100bc579750a1f7b8fc0f10ac9b09dfc26ca9426 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/RealContactItem.kt @@ -0,0 +1,50 @@ +package org.briarproject.briar.desktop.contact + +import org.briarproject.bramble.api.contact.Contact +import org.briarproject.bramble.api.contact.ContactId +import org.briarproject.bramble.api.identity.AuthorId +import org.briarproject.briar.api.client.MessageTracker +import kotlin.math.max + +data class RealContactItem( + override val contactId: ContactId, + val authorId: AuthorId, + val name: String, + val alias: String?, + override val isConnected: Boolean, + override val isEmpty: Boolean, + override val unread: Int, + override val timestamp: Long +) : ContactItem { + + override val displayName = if (alias == null) name else "$alias ($name)" + + constructor(contact: Contact, isConnected: Boolean, groupCount: MessageTracker.GroupCount) : this( + contactId = contact.id, + authorId = contact.author.id, + name = contact.author.name, + alias = contact.alias, + isConnected = isConnected, + isEmpty = groupCount.msgCount == 0, + unread = groupCount.unreadCount, + timestamp = groupCount.latestMsgTime + ) + + fun updateTimestampAndUnread(timestamp: Long, read: Boolean): RealContactItem = + copy( + isEmpty = false, + unread = if (read) unread else unread + 1, + timestamp = max(timestamp, this.timestamp) + ) + + fun updateIsConnected(c: Boolean): RealContactItem { + return copy(isConnected = c) + } + + fun updateAlias(a: String?): RealContactItem { + return copy(alias = a) + } + + fun updateFromMessagesRead(c: Int): RealContactItem = + copy(unread = unread - c) +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt index deeca393355e666042958afdb4135950c970ba6a..3dadbcfb8f8b595fdc6e2de8e817d390ffb5d50e 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationHeader.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.unit.sp import org.briarproject.briar.desktop.contact.ContactDropDown import org.briarproject.briar.desktop.contact.ContactItem import org.briarproject.briar.desktop.contact.ProfileCircle +import org.briarproject.briar.desktop.contact.RealContactItem import org.briarproject.briar.desktop.theme.outline import org.briarproject.briar.desktop.theme.surfaceVariant import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE @@ -42,7 +43,8 @@ fun ConversationHeader( Box(modifier = Modifier.fillMaxWidth().height(HEADER_SIZE + 1.dp)) { Row(modifier = Modifier.align(Alignment.Center)) { - ProfileCircle(36.dp, contactItem.authorId.bytes) + if (contactItem is RealContactItem) + ProfileCircle(36.dp, contactItem.authorId.bytes) Canvas( modifier = Modifier.align(Alignment.CenterVertically), onDraw = { diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt index b4356dc1cac2ec71607efd126e3618d0591fab00..f41bda85ba9a025d0e3b000a85013b63df0354f5 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationViewModel.kt @@ -32,7 +32,7 @@ import org.briarproject.briar.api.messaging.MessagingManager import org.briarproject.briar.api.messaging.PrivateMessage import org.briarproject.briar.api.messaging.PrivateMessageFactory import org.briarproject.briar.api.messaging.PrivateMessageHeader -import org.briarproject.briar.desktop.contact.ContactItem +import org.briarproject.briar.desktop.contact.RealContactItem import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.utils.KLoggerUtils.logDuration import org.briarproject.briar.desktop.utils.clearAndAddAll @@ -62,7 +62,7 @@ constructor( } private val _contactId = mutableStateOf<ContactId?>(null) - private val _contactItem = mutableStateOf<ContactItem?>(null) + private val _contactItem = mutableStateOf<RealContactItem?>(null) private val _messages = mutableStateListOf<ConversationItem>() private val _newMessage = mutableStateOf("") @@ -163,7 +163,7 @@ constructor( private fun loadContact(id: ContactId) = runOnDbThreadWithTransaction(true) { txn -> try { val start = LogUtils.now() - val contactItem = ContactItem( + val contactItem = RealContactItem( contactManager.getContact(txn, id), connectionRegistry.isConnected(id), conversationManager.getGroupCount(txn, id), diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt index 3fc3d795352aa9be3c7f80294c4a992c1ddefcad..0637a7a5b2128ee650536498cad17d9b012c303a 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/PrivateMessageScreen.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import org.briarproject.bramble.api.contact.ContactId import org.briarproject.briar.desktop.contact.ContactList import org.briarproject.briar.desktop.contact.ContactListViewModel import org.briarproject.briar.desktop.ui.UiPlaceholder @@ -27,7 +28,7 @@ fun PrivateMessageScreen( VerticalDivider() Column(modifier = Modifier.weight(1f).fillMaxHeight()) { val id = viewModel.selectedContactId.value - if (id != null) { + if (id != null && id is ContactId) { ConversationScreen(id) } else { UiPlaceholder() diff --git a/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt b/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt index e2c12e52f778a113df66011e052d9082661ea1b8..b8fe9a3350915d09831c372a3c6c23919e9c0cf6 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/introduction/ContactDrawerMakeIntro.kt @@ -27,8 +27,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.briarproject.briar.desktop.contact.ContactCard -import org.briarproject.briar.desktop.contact.ContactItem import org.briarproject.briar.desktop.contact.ProfileCircle +import org.briarproject.briar.desktop.contact.RealContactItem import org.briarproject.briar.desktop.ui.Constants.HEADER_SIZE import org.briarproject.briar.desktop.ui.HorizontalDivider import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n @@ -38,7 +38,7 @@ import java.util.Locale @Composable fun ContactDrawerMakeIntro( - contactItem: ContactItem, + contactItem: RealContactItem, setInfoDrawer: (Boolean) -> Unit, viewModel: IntroductionViewModel = viewModel(), ) { @@ -64,11 +64,12 @@ fun ContactDrawerMakeIntro( HorizontalDivider() LazyColumn { items(viewModel.contactList) { contactItem -> - ContactCard( - contactItem, - { viewModel.setSecondContact(contactItem) }, - false - ) + if (contactItem is RealContactItem) + ContactCard( + contactItem, + { viewModel.setSecondContact(contactItem) }, + false + ) } } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/introduction/IntroductionViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/introduction/IntroductionViewModel.kt index 4165c9128b11c948ee0ca9a61e6ba850f5528a89..1d7e290db1c29592944581822368f54beddfe164 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/introduction/IntroductionViewModel.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/introduction/IntroductionViewModel.kt @@ -9,6 +9,7 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager import org.briarproject.briar.api.conversation.ConversationManager import org.briarproject.briar.desktop.contact.ContactItem import org.briarproject.briar.desktop.contact.ContactsViewModel +import org.briarproject.briar.desktop.contact.RealContactItem import org.briarproject.briar.desktop.threading.BriarExecutors import org.briarproject.briar.desktop.viewmodel.asState import javax.inject.Inject @@ -27,8 +28,8 @@ constructor( contactManager, conversationManager, connectionRegistry, briarExecutors, lifecycleManager, db, eventBus ) { - private val _firstContact = mutableStateOf<ContactItem?>(null) - private val _secondContact = mutableStateOf<ContactItem?>(null) + private val _firstContact = mutableStateOf<RealContactItem?>(null) + private val _secondContact = mutableStateOf<RealContactItem?>(null) private val _secondScreen = mutableStateOf(false) private val _introductionMessage = mutableStateOf("") @@ -37,13 +38,13 @@ constructor( val secondScreen = _secondScreen.asState() val introductionMessage = _introductionMessage.asState() - fun setFirstContact(contactItem: ContactItem) { + fun setFirstContact(contactItem: RealContactItem) { _firstContact.value = contactItem loadContacts() backToFirstScreen() } - fun setSecondContact(contactItem: ContactItem) { + fun setSecondContact(contactItem: RealContactItem) { _secondContact.value = contactItem _secondScreen.value = true } @@ -58,6 +59,8 @@ constructor( } override fun filterContactItem(contactItem: ContactItem): Boolean { - return _firstContact.value?.contactId != contactItem.contactId + return if (contactItem is RealContactItem) { + _firstContact.value?.contactId != contactItem.contactId + } else false } } diff --git a/src/main/resources/strings/BriarDesktop.properties b/src/main/resources/strings/BriarDesktop.properties index 94117f65d4c199db78e838138b8e23c69be71cd7..c235a3deac97ad262f7b67d769ec7b253218a0c9 100644 --- a/src/main/resources/strings/BriarDesktop.properties +++ b/src/main/resources/strings/BriarDesktop.properties @@ -14,6 +14,7 @@ access.swap=Icon showing errors between two contacts # Contacts contacts.card.nothing=No messages. +contacts.card.pending=Pending contact contacts.dropdown.connections=Connections contacts.dropdown.connections.title=Connections contacts.dropdown.connections.bluetooth=Connect via Bluetooth