mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-28 20:29:53 +00:00
android: connect with contact via address (for preset simplex contact) (#3330)
This commit is contained in:
parent
f49ded5ae5
commit
c0be36737d
10 changed files with 165 additions and 48 deletions
|
@ -147,12 +147,13 @@ object ChatModel {
|
|||
val currentCInfo = chats[i].chatInfo
|
||||
var newCInfo = cInfo
|
||||
if (currentCInfo is ChatInfo.Direct && newCInfo is ChatInfo.Direct) {
|
||||
val currentStats = currentCInfo.contact.activeConn.connectionStats
|
||||
val newStats = newCInfo.contact.activeConn.connectionStats
|
||||
if (currentStats != null && newStats == null) {
|
||||
val currentStats = currentCInfo.contact.activeConn?.connectionStats
|
||||
val newConn = newCInfo.contact.activeConn
|
||||
val newStats = newConn?.connectionStats
|
||||
if (currentStats != null && newConn != null && newStats == null) {
|
||||
newCInfo = newCInfo.copy(
|
||||
contact = newCInfo.contact.copy(
|
||||
activeConn = newCInfo.contact.activeConn.copy(
|
||||
activeConn = newConn.copy(
|
||||
connectionStats = currentStats
|
||||
)
|
||||
)
|
||||
|
@ -168,7 +169,7 @@ object ChatModel {
|
|||
fun updateContact(contact: Contact) = updateChat(ChatInfo.Direct(contact), addMissing = contact.directOrUsed)
|
||||
|
||||
fun updateContactConnectionStats(contact: Contact, connectionStats: ConnectionStats) {
|
||||
val updatedConn = contact.activeConn.copy(connectionStats = connectionStats)
|
||||
val updatedConn = contact.activeConn?.copy(connectionStats = connectionStats)
|
||||
val updatedContact = contact.copy(activeConn = updatedConn)
|
||||
updateContact(updatedContact)
|
||||
}
|
||||
|
@ -570,11 +571,19 @@ object ChatModel {
|
|||
}
|
||||
|
||||
fun setContactNetworkStatus(contact: Contact, status: NetworkStatus) {
|
||||
networkStatuses[contact.activeConn.agentConnId] = status
|
||||
val conn = contact.activeConn
|
||||
if (conn != null) {
|
||||
networkStatuses[conn.agentConnId] = status
|
||||
}
|
||||
}
|
||||
|
||||
fun contactNetworkStatus(contact: Contact): NetworkStatus =
|
||||
networkStatuses[contact.activeConn.agentConnId] ?: NetworkStatus.Unknown()
|
||||
fun contactNetworkStatus(contact: Contact): NetworkStatus {
|
||||
val conn = contact.activeConn
|
||||
return if (conn != null)
|
||||
networkStatuses[conn.agentConnId] ?: NetworkStatus.Unknown()
|
||||
else
|
||||
NetworkStatus.Unknown()
|
||||
}
|
||||
|
||||
fun addTerminalItem(item: TerminalItem) {
|
||||
if (terminalItems.size >= 500) {
|
||||
|
@ -891,7 +900,7 @@ data class Contact(
|
|||
val contactId: Long,
|
||||
override val localDisplayName: String,
|
||||
val profile: LocalProfile,
|
||||
val activeConn: Connection,
|
||||
val activeConn: Connection? = null,
|
||||
val viaGroup: Long? = null,
|
||||
val contactUsed: Boolean,
|
||||
val contactStatus: ContactStatus,
|
||||
|
@ -906,10 +915,10 @@ data class Contact(
|
|||
override val chatType get() = ChatType.Direct
|
||||
override val id get() = "@$contactId"
|
||||
override val apiId get() = contactId
|
||||
override val ready get() = activeConn.connStatus == ConnStatus.Ready
|
||||
override val ready get() = activeConn?.connStatus == ConnStatus.Ready
|
||||
val active get() = contactStatus == ContactStatus.Active
|
||||
override val sendMsgEnabled get() =
|
||||
(ready && active && !(activeConn.connectionStats?.ratchetSyncSendProhibited ?: false))
|
||||
(ready && active && !(activeConn?.connectionStats?.ratchetSyncSendProhibited ?: false))
|
||||
|| nextSendGrpInv
|
||||
val nextSendGrpInv get() = contactGroupMemberId != null && !contactGrpInvSent
|
||||
override val ntfsEnabled get() = chatSettings.enableNtfs == MsgFilter.All
|
||||
|
@ -927,13 +936,17 @@ data class Contact(
|
|||
override val image get() = profile.image
|
||||
val contactLink: String? = profile.contactLink
|
||||
override val localAlias get() = profile.localAlias
|
||||
val verified get() = activeConn.connectionCode != null
|
||||
val verified get() = activeConn?.connectionCode != null
|
||||
|
||||
val directOrUsed: Boolean get() =
|
||||
(activeConn.connLevel == 0 && !activeConn.viaGroupLink) || contactUsed
|
||||
if (activeConn != null) {
|
||||
(activeConn.connLevel == 0 && !activeConn.viaGroupLink) || contactUsed
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
||||
val contactConnIncognito =
|
||||
activeConn.customUserProfileId != null
|
||||
activeConn?.customUserProfileId != null
|
||||
|
||||
fun allowsFeature(feature: ChatFeature): Boolean = when (feature) {
|
||||
ChatFeature.TimedMessages -> mergedPreferences.timedMessages.contactPreference.allow != FeatureAllowed.NO
|
||||
|
|
|
@ -907,6 +907,23 @@ object ChatController {
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun apiConnectContactViaAddress(incognito: Boolean, contactId: Long): Contact? {
|
||||
val userId = chatModel.currentUser.value?.userId ?: run {
|
||||
Log.e(TAG, "apiConnectContactViaAddress: no current user")
|
||||
return null
|
||||
}
|
||||
val r = sendCmd(CC.ApiConnectContactViaAddress(userId, incognito, contactId))
|
||||
when {
|
||||
r is CR.SentInvitationToContact -> return r.contact
|
||||
else -> {
|
||||
if (!(networkErrorAlert(r))) {
|
||||
apiErrorAlert("apiConnectContactViaAddress", generalGetString(MR.strings.connection_error), r)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun apiDeleteChat(type: ChatType, id: Long, notify: Boolean? = null): Boolean {
|
||||
val r = sendCmd(CC.ApiDeleteChat(type, id, notify))
|
||||
when {
|
||||
|
@ -1413,8 +1430,11 @@ object ChatController {
|
|||
is CR.ContactConnected -> {
|
||||
if (active(r.user) && r.contact.directOrUsed) {
|
||||
chatModel.updateContact(r.contact)
|
||||
chatModel.dismissConnReqView(r.contact.activeConn.id)
|
||||
chatModel.removeChat(r.contact.activeConn.id)
|
||||
val conn = r.contact.activeConn
|
||||
if (conn != null) {
|
||||
chatModel.dismissConnReqView(conn.id)
|
||||
chatModel.removeChat(conn.id)
|
||||
}
|
||||
}
|
||||
if (r.contact.directOrUsed) {
|
||||
ntfManager.notifyContactConnected(r.user, r.contact)
|
||||
|
@ -1424,8 +1444,11 @@ object ChatController {
|
|||
is CR.ContactConnecting -> {
|
||||
if (active(r.user) && r.contact.directOrUsed) {
|
||||
chatModel.updateContact(r.contact)
|
||||
chatModel.dismissConnReqView(r.contact.activeConn.id)
|
||||
chatModel.removeChat(r.contact.activeConn.id)
|
||||
val conn = r.contact.activeConn
|
||||
if (conn != null) {
|
||||
chatModel.dismissConnReqView(conn.id)
|
||||
chatModel.removeChat(conn.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
is CR.ReceivedContactRequest -> {
|
||||
|
@ -1556,9 +1579,10 @@ object ChatController {
|
|||
if (!active(r.user)) return
|
||||
|
||||
chatModel.updateGroup(r.groupInfo)
|
||||
if (r.hostContact != null) {
|
||||
chatModel.dismissConnReqView(r.hostContact.activeConn.id)
|
||||
chatModel.removeChat(r.hostContact.activeConn.id)
|
||||
val conn = r.hostContact?.activeConn
|
||||
if (conn != null) {
|
||||
chatModel.dismissConnReqView(conn.id)
|
||||
chatModel.removeChat(conn.id)
|
||||
}
|
||||
}
|
||||
is CR.GroupLinkConnecting -> {
|
||||
|
@ -1946,6 +1970,7 @@ sealed class CC {
|
|||
class ApiSetConnectionIncognito(val connId: Long, val incognito: Boolean): CC()
|
||||
class APIConnectPlan(val userId: Long, val connReq: String): CC()
|
||||
class APIConnect(val userId: Long, val incognito: Boolean, val connReq: String): CC()
|
||||
class ApiConnectContactViaAddress(val userId: Long, val incognito: Boolean, val contactId: Long): CC()
|
||||
class ApiDeleteChat(val type: ChatType, val id: Long, val notify: Boolean?): CC()
|
||||
class ApiClearChat(val type: ChatType, val id: Long): CC()
|
||||
class ApiListContacts(val userId: Long): CC()
|
||||
|
@ -2057,6 +2082,7 @@ sealed class CC {
|
|||
is ApiSetConnectionIncognito -> "/_set incognito :$connId ${onOff(incognito)}"
|
||||
is APIConnectPlan -> "/_connect plan $userId $connReq"
|
||||
is APIConnect -> "/_connect $userId incognito=${onOff(incognito)} $connReq"
|
||||
is ApiConnectContactViaAddress -> "/_connect contact $userId incognito=${onOff(incognito)} $contactId"
|
||||
is ApiDeleteChat -> if (notify != null) {
|
||||
"/_delete ${chatRef(type, id)} notify=${onOff(notify)}"
|
||||
} else {
|
||||
|
@ -2164,6 +2190,7 @@ sealed class CC {
|
|||
is ApiSetConnectionIncognito -> "apiSetConnectionIncognito"
|
||||
is APIConnectPlan -> "apiConnectPlan"
|
||||
is APIConnect -> "apiConnect"
|
||||
is ApiConnectContactViaAddress -> "apiConnectContactViaAddress"
|
||||
is ApiDeleteChat -> "apiDeleteChat"
|
||||
is ApiClearChat -> "apiClearChat"
|
||||
is ApiListContacts -> "apiListContacts"
|
||||
|
@ -3379,6 +3406,7 @@ sealed class CR {
|
|||
@Serializable @SerialName("connectionPlan") class CRConnectionPlan(val user: UserRef, val connectionPlan: ConnectionPlan): CR()
|
||||
@Serializable @SerialName("sentConfirmation") class SentConfirmation(val user: UserRef): CR()
|
||||
@Serializable @SerialName("sentInvitation") class SentInvitation(val user: UserRef): CR()
|
||||
@Serializable @SerialName("sentInvitationToContact") class SentInvitationToContact(val user: UserRef, val contact: Contact, val customUserProfile: Profile?): CR()
|
||||
@Serializable @SerialName("contactAlreadyExists") class ContactAlreadyExists(val user: UserRef, val contact: Contact): CR()
|
||||
@Serializable @SerialName("contactRequestAlreadyAccepted") class ContactRequestAlreadyAccepted(val user: UserRef, val contact: Contact): CR()
|
||||
@Serializable @SerialName("contactDeleted") class ContactDeleted(val user: UserRef, val contact: Contact): CR()
|
||||
|
@ -3517,6 +3545,7 @@ sealed class CR {
|
|||
is CRConnectionPlan -> "connectionPlan"
|
||||
is SentConfirmation -> "sentConfirmation"
|
||||
is SentInvitation -> "sentInvitation"
|
||||
is SentInvitationToContact -> "sentInvitationToContact"
|
||||
is ContactAlreadyExists -> "contactAlreadyExists"
|
||||
is ContactRequestAlreadyAccepted -> "contactRequestAlreadyAccepted"
|
||||
is ContactDeleted -> "contactDeleted"
|
||||
|
@ -3650,6 +3679,7 @@ sealed class CR {
|
|||
is CRConnectionPlan -> withUser(user, json.encodeToString(connectionPlan))
|
||||
is SentConfirmation -> withUser(user, noDetails())
|
||||
is SentInvitation -> withUser(user, noDetails())
|
||||
is SentInvitationToContact -> withUser(user, json.encodeToString(contact))
|
||||
is ContactAlreadyExists -> withUser(user, json.encodeToString(contact))
|
||||
is ContactRequestAlreadyAccepted -> withUser(user, json.encodeToString(contact))
|
||||
is ContactDeleted -> withUser(user, json.encodeToString(contact))
|
||||
|
@ -3785,6 +3815,7 @@ sealed class ContactAddressPlan {
|
|||
@Serializable @SerialName("connectingConfirmReconnect") object ConnectingConfirmReconnect: ContactAddressPlan()
|
||||
@Serializable @SerialName("connectingProhibit") class ConnectingProhibit(val contact: Contact): ContactAddressPlan()
|
||||
@Serializable @SerialName("known") class Known(val contact: Contact): ContactAddressPlan()
|
||||
@Serializable @SerialName("contactViaAddress") class ContactViaAddress(val contact: Contact): ContactAddressPlan()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
|
|
@ -150,7 +150,7 @@ fun ChatInfoView(
|
|||
val (verified, existingCode) = r
|
||||
chatModel.updateContact(
|
||||
ct.copy(
|
||||
activeConn = ct.activeConn.copy(
|
||||
activeConn = ct.activeConn?.copy(
|
||||
connectionCode = if (verified) SecurityCode(existingCode, Clock.System.now()) else null
|
||||
)
|
||||
)
|
||||
|
|
|
@ -57,7 +57,7 @@ fun CIRcvDecryptionError(
|
|||
if (cInfo is ChatInfo.Direct) {
|
||||
val modelCInfo = findModelChat(cInfo.id)?.chatInfo
|
||||
if (modelCInfo is ChatInfo.Direct) {
|
||||
val modelContactStats = modelCInfo.contact.activeConn.connectionStats
|
||||
val modelContactStats = modelCInfo.contact.activeConn?.connectionStats
|
||||
if (modelContactStats != null) {
|
||||
if (modelContactStats.ratchetSyncAllowed) {
|
||||
DecryptionErrorItemFixButton(
|
||||
|
|
|
@ -30,6 +30,7 @@ import chat.simplex.common.views.newchat.*
|
|||
import chat.simplex.res.MR
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.datetime.Clock
|
||||
import java.net.URI
|
||||
|
||||
@Composable
|
||||
fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) {
|
||||
|
@ -61,8 +62,8 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) {
|
|||
val contactNetworkStatus = chatModel.contactNetworkStatus(chat.chatInfo.contact)
|
||||
ChatListNavLinkLayout(
|
||||
chatLinkPreview = { ChatPreviewView(chat, showChatPreviews, chatModel.draft.value, chatModel.draftChatId.value, chatModel.currentUser.value?.profile?.displayName, contactNetworkStatus, stopped, linkMode, inProgress = false, progressByTimeout = false) },
|
||||
click = { directChatAction(chat.chatInfo, chatModel) },
|
||||
dropdownMenuItems = { ContactMenuItems(chat, chatModel, showMenu, showMarkRead) },
|
||||
click = { directChatAction(chat.chatInfo.contact, chatModel) },
|
||||
dropdownMenuItems = { ContactMenuItems(chat, chat.chatInfo.contact, chatModel, showMenu, showMarkRead) },
|
||||
showMenu,
|
||||
stopped,
|
||||
selectedChat
|
||||
|
@ -118,8 +119,11 @@ fun ChatListNavLinkView(chat: Chat, chatModel: ChatModel) {
|
|||
}
|
||||
}
|
||||
|
||||
fun directChatAction(chatInfo: ChatInfo, chatModel: ChatModel) {
|
||||
withBGApi { openChat(chatInfo, chatModel) }
|
||||
fun directChatAction(contact: Contact, chatModel: ChatModel) {
|
||||
when {
|
||||
contact.activeConn == null && contact.profile.contactLink != null -> askCurrentOrIncognitoProfileConnectContactViaAddress(chatModel, contact, close = null, openChat = true)
|
||||
else -> withBGApi { openChat(ChatInfo.Direct(contact), chatModel) }
|
||||
}
|
||||
}
|
||||
|
||||
fun groupChatAction(groupInfo: GroupInfo, chatModel: ChatModel, inProgress: MutableState<Boolean>? = null) {
|
||||
|
@ -192,15 +196,17 @@ suspend fun setGroupMembers(groupInfo: GroupInfo, chatModel: ChatModel) {
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun ContactMenuItems(chat: Chat, chatModel: ChatModel, showMenu: MutableState<Boolean>, showMarkRead: Boolean) {
|
||||
if (showMarkRead) {
|
||||
MarkReadChatAction(chat, chatModel, showMenu)
|
||||
} else {
|
||||
MarkUnreadChatAction(chat, chatModel, showMenu)
|
||||
fun ContactMenuItems(chat: Chat, contact: Contact, chatModel: ChatModel, showMenu: MutableState<Boolean>, showMarkRead: Boolean) {
|
||||
if (contact.activeConn != null) {
|
||||
if (showMarkRead) {
|
||||
MarkReadChatAction(chat, chatModel, showMenu)
|
||||
} else {
|
||||
MarkUnreadChatAction(chat, chatModel, showMenu)
|
||||
}
|
||||
ToggleFavoritesChatAction(chat, chatModel, chat.chatInfo.chatSettings?.favorite == true, showMenu)
|
||||
ToggleNotificationsChatAction(chat, chatModel, chat.chatInfo.ntfsEnabled, showMenu)
|
||||
ClearChatAction(chat, chatModel, showMenu)
|
||||
}
|
||||
ToggleFavoritesChatAction(chat, chatModel, chat.chatInfo.chatSettings?.favorite == true, showMenu)
|
||||
ToggleNotificationsChatAction(chat, chatModel, chat.chatInfo.ntfsEnabled, showMenu)
|
||||
ClearChatAction(chat, chatModel, showMenu)
|
||||
DeleteContactAction(chat, chatModel, showMenu)
|
||||
}
|
||||
|
||||
|
@ -591,6 +597,63 @@ fun pendingContactAlertDialog(chatInfo: ChatInfo, chatModel: ChatModel) {
|
|||
)
|
||||
}
|
||||
|
||||
fun askCurrentOrIncognitoProfileConnectContactViaAddress(
|
||||
chatModel: ChatModel,
|
||||
contact: Contact,
|
||||
close: (() -> Unit)?,
|
||||
openChat: Boolean
|
||||
) {
|
||||
AlertManager.shared.showAlertDialogButtonsColumn(
|
||||
title = String.format(generalGetString(MR.strings.connect_with_contact_name_question), contact.chatViewName),
|
||||
buttons = {
|
||||
Column {
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
withApi {
|
||||
close?.invoke()
|
||||
val ok = connectContactViaAddress(chatModel, contact.contactId, incognito = false)
|
||||
if (ok && openChat) {
|
||||
openDirectChat(contact.contactId, chatModel)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text(generalGetString(MR.strings.connect_use_current_profile), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
withApi {
|
||||
close?.invoke()
|
||||
val ok = connectContactViaAddress(chatModel, contact.contactId, incognito = true)
|
||||
if (ok && openChat) {
|
||||
openDirectChat(contact.contactId, chatModel)
|
||||
}
|
||||
}
|
||||
}) {
|
||||
Text(generalGetString(MR.strings.connect_use_new_incognito_profile), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
SectionItemView({
|
||||
AlertManager.shared.hideAlert()
|
||||
}) {
|
||||
Text(stringResource(MR.strings.cancel_verb), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun connectContactViaAddress(chatModel: ChatModel, contactId: Long, incognito: Boolean): Boolean {
|
||||
val contact = chatModel.controller.apiConnectContactViaAddress(incognito, contactId)
|
||||
if (contact != null) {
|
||||
chatModel.updateContact(contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.connection_request_sent),
|
||||
text = generalGetString(MR.strings.you_will_be_connected_when_your_connection_request_is_accepted)
|
||||
)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun acceptGroupInvitationAlertDialog(groupInfo: GroupInfo, chatModel: ChatModel, inProgress: MutableState<Boolean>? = null) {
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(MR.strings.join_group_question),
|
||||
|
|
|
@ -146,11 +146,6 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
|
|||
@Composable
|
||||
private fun OnboardingButtons(openNewChatSheet: () -> Unit) {
|
||||
Column(Modifier.fillMaxSize().padding(DEFAULT_PADDING), horizontalAlignment = Alignment.End, verticalArrangement = Arrangement.Bottom) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
ConnectButton(generalGetString(MR.strings.chat_with_developers)) {
|
||||
uriHandler.openVerifiedSimplexUri(simplexTeamUri)
|
||||
}
|
||||
Spacer(Modifier.height(DEFAULT_PADDING))
|
||||
ConnectButton(generalGetString(MR.strings.tap_to_start_new_chat), openNewChatSheet)
|
||||
val color = MaterialTheme.colors.primaryVariant
|
||||
Canvas(modifier = Modifier.width(40.dp).height(10.dp), onDraw = {
|
||||
|
|
|
@ -185,10 +185,14 @@ fun ChatPreviewView(
|
|||
} else {
|
||||
when (cInfo) {
|
||||
is ChatInfo.Direct ->
|
||||
if (cInfo.contact.nextSendGrpInv) {
|
||||
Text(stringResource(MR.strings.member_contact_send_direct_message), color = MaterialTheme.colors.secondary)
|
||||
} else if (!cInfo.ready && cInfo.contact.active) {
|
||||
Text(stringResource(MR.strings.contact_connection_pending), color = MaterialTheme.colors.secondary)
|
||||
if (cInfo.contact.activeConn == null && cInfo.contact.profile.contactLink != null) {
|
||||
Text(stringResource(MR.strings.contact_tap_to_connect), color = MaterialTheme.colors.primary)
|
||||
} else if (!cInfo.ready && cInfo.contact.activeConn != null) {
|
||||
if (cInfo.contact.nextSendGrpInv) {
|
||||
Text(stringResource(MR.strings.member_contact_send_direct_message), color = MaterialTheme.colors.secondary)
|
||||
} else if (cInfo.contact.active) {
|
||||
Text(stringResource(MR.strings.contact_connection_pending), color = MaterialTheme.colors.secondary)
|
||||
}
|
||||
}
|
||||
is ChatInfo.Group ->
|
||||
when (cInfo.groupInfo.membership.memberStatus) {
|
||||
|
@ -215,7 +219,7 @@ fun ChatPreviewView(
|
|||
@Composable
|
||||
fun chatStatusImage() {
|
||||
if (cInfo is ChatInfo.Direct) {
|
||||
if (cInfo.contact.active) {
|
||||
if (cInfo.contact.active && cInfo.contact.activeConn != null) {
|
||||
val descr = contactNetworkStatus?.statusString
|
||||
when (contactNetworkStatus) {
|
||||
is NetworkStatus.Connected ->
|
||||
|
|
|
@ -20,7 +20,7 @@ fun ShareListNavLinkView(chat: Chat, chatModel: ChatModel) {
|
|||
is ChatInfo.Direct ->
|
||||
ShareListNavLinkLayout(
|
||||
chatLinkPreview = { SharePreviewView(chat) },
|
||||
click = { directChatAction(chat.chatInfo, chatModel) },
|
||||
click = { directChatAction(chat.chatInfo.contact, chatModel) },
|
||||
stopped
|
||||
)
|
||||
is ChatInfo.Group ->
|
||||
|
|
|
@ -19,8 +19,7 @@ import androidx.compose.ui.unit.dp
|
|||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.TAG
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.chatlist.openDirectChat
|
||||
import chat.simplex.common.views.chatlist.openGroupChat
|
||||
import chat.simplex.common.views.chatlist.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.views.usersettings.*
|
||||
import chat.simplex.res.MR
|
||||
|
@ -171,6 +170,16 @@ suspend fun planAndConnect(
|
|||
String.format(generalGetString(MR.strings.you_are_already_connected_to_vName_via_this_link), contact.displayName)
|
||||
)
|
||||
}
|
||||
is ContactAddressPlan.ContactViaAddress -> {
|
||||
Log.d(TAG, "planAndConnect, .ContactAddress, .ContactViaAddress, incognito=$incognito")
|
||||
val contact = connectionPlan.contactAddressPlan.contact
|
||||
if (incognito != null) {
|
||||
close?.invoke()
|
||||
connectContactViaAddress(chatModel, contact.contactId, incognito)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileConnectContactViaAddress(chatModel, contact, close, openChat = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
is ConnectionPlan.GroupLink -> when (connectionPlan.groupLinkPlan) {
|
||||
GroupLinkPlan.Ok -> {
|
||||
|
|
|
@ -289,6 +289,8 @@
|
|||
<string name="chat_with_developers">Chat with the developers</string>
|
||||
<string name="you_have_no_chats">You have no chats</string>
|
||||
<string name="no_filtered_chats">No filtered chats</string>
|
||||
<string name="contact_tap_to_connect">Tap to Connect</string>
|
||||
<string name="connect_with_contact_name_question">Connect with %1$s?</string>
|
||||
|
||||
<!-- ChatView.kt -->
|
||||
<string name="no_selected_chat">No selected chat</string>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue