android, desktop: showing only actionable contacts

This commit is contained in:
Diogo Cunha
2024-07-17 22:27:17 +01:00
parent cea3aad0d4
commit 060d3dd4d4
4 changed files with 36 additions and 123 deletions
@@ -76,27 +76,6 @@ fun ContactListNavLinkView(chat: Chat, nextChatSelected: State<Boolean>, oneHand
oneHandUI
)
}
is ChatInfo.ContactConnection -> {
ChatListNavLinkLayout(
chatLinkPreview = {
tryOrShowError("${chat.id}ContactListNavLink", error = { ErrorChatListItem() }) {
ContactPreviewView(chat, disabled)
}
},
click = {
contactRequestAlertDialog(
rhId = chat.remoteHostId,
connection = chat.chatInfo.contactConnection
)
},
dropdownMenuItems = {},
showMenu,
disabled,
selectedChat,
nextChatSelected,
oneHandUI
)
}
else -> {}
}
}
@@ -132,12 +111,4 @@ fun DeleteContactAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState
},
color = Color.Red
)
}
fun contactRequestAlertDialog(rhId: Long?, connection: PendingContactConnection) {
AlertManager.shared.showAlertMsg(
title = "Connection not yet accepted",
text = "${connection.displayName} didn't accept your connection request yet.",
hostDevice = hostDevice(rhId),
)
}
@@ -3,15 +3,12 @@ package chat.simplex.common.views.contacts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.*
import chat.simplex.common.views.helpers.*
@@ -27,44 +24,6 @@ fun ContactPreviewView(
) {
val cInfo = chat.chatInfo
@Composable
fun OverlayIcon(painter: Painter, description: String) {
Icon(
painter,
description,
Modifier.size(18.dp).background(MaterialTheme.colors.background, CircleShape),
tint = MaterialTheme.colors.secondary
)
}
@Composable
fun pendingIcon() {
OverlayIcon(
painterResource(MR.images.ic_timer),
stringResource(MR.strings.icon_descr_pending_contact_connection)
)
}
@Composable
fun inactiveIcon() {
OverlayIcon(
painterResource(MR.images.ic_cancel_filled),
stringResource(MR.strings.icon_descr_group_inactive)
)
}
@Composable
fun chatPreviewImageOverlayIcon() {
when (cInfo) {
is ChatInfo.Direct ->
if (!cInfo.contact.active) {
inactiveIcon()
}
is ChatInfo.ContactConnection -> pendingIcon()
else -> {}
}
}
@Composable
fun VerifiedIcon() {
Icon(painterResource(MR.images.ic_verified_user), null, Modifier.size(19.dp).padding(end = 3.dp, top = 1.dp), tint = MaterialTheme.colors.secondary)
@@ -95,15 +54,6 @@ fun ContactPreviewView(
color = Color.Unspecified
)
}
is ChatInfo.ContactConnection ->
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
cInfo.chatViewName,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = MaterialTheme.colors.secondary
)
}
else -> {}
}
}
@@ -113,9 +63,6 @@ fun ContactPreviewView(
) {
Box(contentAlignment = Alignment.BottomEnd) {
ChatInfoImage(cInfo, size = 42.dp)
Box(Modifier.padding(end = 2.dp, bottom = 2.dp)) {
chatPreviewImageOverlayIcon()
}
}
Spacer(Modifier.width(DEFAULT_SPACE_AFTER_ICON))
@@ -126,7 +73,7 @@ fun ContactPreviewView(
Spacer(Modifier.fillMaxWidth().weight(1f))
if (chat.chatInfo is ChatInfo.ContactRequest || chat.chatInfo is ChatInfo.ContactConnection) {
if (chat.chatInfo is ChatInfo.ContactRequest) {
Text(
text = generalGetString(MR.strings.contact_type_new).uppercase(),
color = MaterialTheme.colors.onPrimary,
@@ -1,12 +1,10 @@
package chat.simplex.common.views.contacts
import SectionDividerSpaced
import SectionItemView
import SectionView
import TextIconSpaced
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -15,7 +13,6 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -23,63 +20,62 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.common.model.Chat
import chat.simplex.common.model.ChatController
import chat.simplex.common.model.ChatInfo
import chat.simplex.common.model.ChatModel
import chat.simplex.common.model.ChatType
import chat.simplex.common.model.ContactStatus
import chat.simplex.common.model.Format
import chat.simplex.common.model.RemoteHostInfo
import chat.simplex.common.model.SharedPreference
import chat.simplex.common.platform.BackHandler
import chat.simplex.common.platform.ColumnWithScrollBar
import chat.simplex.common.platform.LazyColumnWithScrollBar
import chat.simplex.common.platform.LocalMultiplatformView
import chat.simplex.common.platform.Log
import chat.simplex.common.platform.TAG
import chat.simplex.common.platform.appPlatform
import chat.simplex.common.platform.chatModel
import chat.simplex.common.platform.getKeyboardState
import chat.simplex.common.platform.hideKeyboard
import chat.simplex.common.ui.theme.*
import chat.simplex.common.views.chatlist.DetailedSMPStatsView
import chat.simplex.common.views.helpers.*
import chat.simplex.common.views.newchat.AddGroupView
import chat.simplex.common.views.newchat.NewChatOption
import chat.simplex.common.views.newchat.NewChatOptions
import chat.simplex.common.views.newchat.NewChatView
import chat.simplex.common.views.newchat.strHasSingleSimplexLink
import chat.simplex.common.ui.theme.DEFAULT_PADDING
import chat.simplex.common.ui.theme.DEFAULT_PADDING_HALF
import chat.simplex.common.views.helpers.AppBarTitle
import chat.simplex.common.views.helpers.KeyChangeEffect
import chat.simplex.common.views.helpers.KeyboardState
import chat.simplex.common.views.helpers.ModalData
import chat.simplex.common.views.helpers.ModalManager
import chat.simplex.common.views.helpers.ModalView
import chat.simplex.common.views.helpers.SearchTextField
import chat.simplex.common.views.helpers.generalGetString
import chat.simplex.common.views.helpers.hostDevice
import chat.simplex.res.MR
import dev.icerock.moko.resources.compose.painterResource
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import java.util.HashSet
enum class ContactType {
CARD, REQUEST_RECEIVED, REQUEST_SENT, RECENT, REMOVED, UNKNOWN
CARD, REQUEST, RECENT, REMOVED, UNKNOWN
}
private fun contactChats(c: List<Chat>, contactTypes: List<ContactType>): List<Chat> {
@@ -88,19 +84,17 @@ private fun contactChats(c: List<Chat>, contactTypes: List<ContactType>): List<C
private fun getContactType(chat: Chat): ContactType {
return when (val cInfo = chat.chatInfo) {
is ChatInfo.ContactRequest -> ContactType.REQUEST_RECEIVED
is ChatInfo.ContactRequest -> ContactType.REQUEST
is ChatInfo.Direct -> {
val contact = cInfo.contact;
when {
contact.activeConn == null && contact.profile.contactLink != null -> ContactType.CARD
contact.contactStatus == ContactStatus.DeletedByUser || contact.contactStatus == ContactStatus.Deleted -> ContactType.REMOVED
contact.chatDeleted -> ContactType.REMOVED
else -> ContactType.RECENT
contact.contactStatus != ContactStatus.DeletedByUser && contact.contactStatus != ContactStatus.Deleted -> ContactType.RECENT
else -> ContactType.UNKNOWN
}
}
// TODO: Redo this.
is ChatInfo.ContactConnection -> ContactType.REQUEST_SENT
else -> ContactType.UNKNOWN
}
}
@@ -128,7 +122,7 @@ fun ModalData.DeletedContactsView(rh: RemoteHostInfo?, close: () -> Unit) {
Box(contentAlignment = Alignment.Center) {
val bottomPadding = DEFAULT_PADDING
AppBarTitle(
stringResource(MR.strings.contact_type_deleted),
stringResource(MR.strings.chat_deleted),
hostDevice(rh?.remoteHostId),
bottomPadding = bottomPadding
)
@@ -161,11 +155,11 @@ private fun ContactActionsSection(contactActions: @Composable () -> Unit, rh: Re
) {
Icon(
painterResource(MR.images.ic_folder_open),
contentDescription = stringResource(MR.strings.contact_type_deleted),
contentDescription = stringResource(MR.strings.chat_deleted),
tint = MaterialTheme.colors.secondary,
)
TextIconSpaced(extraPadding = true)
Text(text = stringResource(MR.strings.contact_type_deleted), color = MaterialTheme.colors.onBackground)
Text(text = stringResource(MR.strings.chat_deleted), color = MaterialTheme.colors.onBackground)
}
}
}
@@ -214,7 +208,7 @@ fun ContactsView(
) {
ContactsLayout(
contactActions = { ContactActionsSection(contactActions, rh) },
contactTypes = listOf(ContactType.CARD, ContactType.RECENT, ContactType.REQUEST_RECEIVED, ContactType.REQUEST_SENT),
contactTypes = listOf(ContactType.CARD, ContactType.RECENT, ContactType.REQUEST),
contactListTitle = stringResource(MR.strings.contact_list_header_title).uppercase()
)
}
@@ -2218,6 +2218,7 @@
<!-- ContactsView.kt -->
<string name="contact_type_new">New</string>
<string name="contact_type_deleted">Deleted contacts</string>
<string name="chat_deleted">Deleted chats</string>
<string name="contact_type_recent">Recent</string>
<string name="no_filtered_contacts">No filtered contacts</string>
<string name="contact_list_header_title">Your contacts</string>