From 1385f0988677127de7ec70f062a29611d16de7e9 Mon Sep 17 00:00:00 2001 From: Yamil Medina Date: Wed, 25 Oct 2023 07:04:34 -0300 Subject: [PATCH] feat: connection request warning badge and conversation started sys message warning (WPB-2266) (#2357) --- .../mapper/SystemMessageContentMapper.kt | 9 +++ .../home/conversations/SystemMessageItem.kt | 3 + .../ui/home/conversations/model/UIMessage.kt | 8 +- .../other/OtherUserConnectionStatusInfo.kt | 26 +++--- .../OtherUserConnectionUnverifiedWarning.kt | 79 +++++++++++++++++++ .../other/OtherUserProfileScreen.kt | 1 + app/src/main/res/values/strings.xml | 3 + kalium | 2 +- 8 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionUnverifiedWarning.kt diff --git a/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt b/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt index a85a042508..1ce361e681 100644 --- a/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt +++ b/app/src/main/kotlin/com/wire/android/mapper/SystemMessageContentMapper.kt @@ -70,6 +70,7 @@ class SystemMessageContentMapper @Inject constructor( is MessageContent.ConversationVerifiedProteus -> mapConversationVerified(Conversation.Protocol.PROTEUS) is MessageContent.FederationStopped -> mapFederationMessage(content) is MessageContent.ConversationProtocolChanged -> mapConversationProtocolChanged(content) + is MessageContent.ConversationStartedUnverifiedWarning -> mapConversationCreatedUnverifiedWarning() } private fun mapConversationCreated(senderUserId: UserId, date: String, userList: List): UIMessageContent.SystemMessage { @@ -85,6 +86,10 @@ class SystemMessageContentMapper @Inject constructor( ) } + private fun mapConversationCreatedUnverifiedWarning(): UIMessageContent.SystemMessage { + return UIMessageContent.SystemMessage.ConversationMessageCreatedUnverifiedWarning + } + private fun mapConversationTimerChanged( senderUserId: UserId, content: MessageContent.ConversationMessageTimerChanged, @@ -246,12 +251,16 @@ class SystemMessageContentMapper @Inject constructor( private fun mapConversationHistoryLost(): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.HistoryLost + private fun mapMLSWrongEpochWarning(): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.MLSWrongEpochWarning() + private fun mapConversationHistoryListProtocolChanged(): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.HistoryLostProtocolChanged + private fun mapConversationDegraded(protocol: Conversation.Protocol): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.ConversationDegraded(protocol) + private fun mapConversationVerified(protocol: Conversation.Protocol): UIMessageContent.SystemMessage = UIMessageContent.SystemMessage.ConversationVerified(protocol) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/SystemMessageItem.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/SystemMessageItem.kt index 9266e57dc6..72f670f15d 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/SystemMessageItem.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/SystemMessageItem.kt @@ -265,6 +265,7 @@ private fun getColorFilter(message: SystemMessage): ColorFilter? { is SystemMessage.ConversationMessageTimerDeactivated, is SystemMessage.FederationMemberRemoved, is SystemMessage.FederationStopped, + is SystemMessage.ConversationMessageCreatedUnverifiedWarning, is SystemMessage.MLSWrongEpochWarning -> ColorFilter.tint(colorsScheme().onBackground) } } @@ -495,6 +496,7 @@ private val SystemMessage.expandable is SystemMessage.ConversationDegraded -> false is SystemMessage.ConversationVerified -> false is SystemMessage.FederationStopped -> false + is SystemMessage.ConversationMessageCreatedUnverifiedWarning -> false } private fun List.toUserNamesListString(res: Resources): String = when { @@ -581,6 +583,7 @@ fun SystemMessage.annotatedString( ) is SystemMessage.FederationStopped -> domainList.toTypedArray() + is SystemMessage.ConversationMessageCreatedUnverifiedWarning -> arrayOf() } return res.annotatedText(stringResId, normalStyle, boldStyle, normalColor, boldColor, errorColor, isErrorString, *args) diff --git a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt index 721a678030..a94f18ef75 100644 --- a/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt +++ b/app/src/main/kotlin/com/wire/android/ui/home/conversations/model/UIMessage.kt @@ -423,7 +423,8 @@ sealed class UIMessageContent { object HistoryLost : SystemMessage( R.drawable.ic_info, R.string.label_system_message_conversation_history_lost, - true) + true + ) object HistoryLostProtocolChanged : SystemMessage( R.drawable.ic_info, @@ -476,6 +477,11 @@ sealed class UIMessageContent { if (protocol == Conversation.Protocol.MLS) R.string.label_system_message_conversation_verified_mls else R.string.label_system_message_conversation_verified_proteus ) + + data object ConversationMessageCreatedUnverifiedWarning : SystemMessage( + R.drawable.ic_info, + R.string.label_system_message_conversation_started_sensitive_information + ) } } diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionStatusInfo.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionStatusInfo.kt index 682b26cdba..047687aec9 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionStatusInfo.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionStatusInfo.kt @@ -58,16 +58,8 @@ fun OtherUserConnectionStatusInfo(connectionStatus: ConnectionState, membership: style = MaterialTheme.wireTypography.title02 ) } - val descriptionResource = when (connectionStatus) { - ConnectionState.PENDING, ConnectionState.IGNORED -> R.string.connection_label_accepting_request_description - ConnectionState.ACCEPTED, ConnectionState.BLOCKED -> null - else -> if (membership == Membership.None) { - R.string.connection_label_member_not_conneted - } else { - R.string.connection_label_member_not_belongs_to_team - } - } - descriptionResource?.let { + + descriptionResourceForConnectionAndMembership(connectionStatus, membership)?.let { Text( text = stringResource(it), textAlign = TextAlign.Center, @@ -80,6 +72,20 @@ fun OtherUserConnectionStatusInfo(connectionStatus: ConnectionState, membership: } } +@Composable +private fun descriptionResourceForConnectionAndMembership( + connectionStatus: ConnectionState, + membership: Membership +) = when (connectionStatus) { + ConnectionState.PENDING, ConnectionState.IGNORED -> R.string.connection_label_accepting_request_description + ConnectionState.ACCEPTED, ConnectionState.BLOCKED -> null + else -> if (membership == Membership.None) { + R.string.connection_label_member_not_conneted + } else { + R.string.connection_label_member_not_belongs_to_team + } +} + @Composable @Preview fun PreviewOtherUserConnectionStatusInfo() { diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionUnverifiedWarning.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionUnverifiedWarning.kt new file mode 100644 index 0000000000..53884ac03b --- /dev/null +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserConnectionUnverifiedWarning.kt @@ -0,0 +1,79 @@ +/* + * Wire + * Copyright (C) 2023 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + * + * + */ + +package com.wire.android.ui.userprofile.other + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import com.wire.android.R +import com.wire.android.ui.common.dimensions +import com.wire.android.ui.common.spacers.VerticalSpace +import com.wire.android.ui.theme.wireColorScheme +import com.wire.android.ui.theme.wireTypography +import com.wire.kalium.logic.data.user.ConnectionState + +@Composable +fun OtherUserConnectionUnverifiedWarning( + userName: String, + connectionStatus: ConnectionState +) { + Box( + Modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(start = dimensions().spacing32x, end = dimensions().spacing32x) + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + unverifiedDescriptionResource(connectionStatus)?.let { + Text( + text = stringResource(it, userName), + textAlign = TextAlign.Center, + color = MaterialTheme.wireColorScheme.error, + style = MaterialTheme.wireTypography.body01 + ) + VerticalSpace.x24() + } + } + } +} + +@Composable +private fun unverifiedDescriptionResource(connectionStatus: ConnectionState) = when (connectionStatus) { + ConnectionState.PENDING, ConnectionState.IGNORED -> R.string.connection_label_received_unverified_warning + ConnectionState.ACCEPTED, ConnectionState.BLOCKED -> null + else -> R.string.connection_label_send_unverified_warning +} + +@Composable +@Preview +fun PreviewOtherUserConnectionUnverifiedWarning() { + OtherUserConnectionUnverifiedWarning("Bob", ConnectionState.NOT_CONNECTED) +} diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreen.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreen.kt index 9c2433a32a..7800e6660e 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreen.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/other/OtherUserProfileScreen.kt @@ -447,6 +447,7 @@ private fun Content( Column { if (!state.isDataLoading) { OtherUserConnectionStatusInfo(state.connectionState, state.membership) + OtherUserConnectionUnverifiedWarning(state.fullName, state.connectionState) } when { state.isDataLoading || state.botService != null -> Box {} // no content visible while loading diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3e3f25b83..d96f29a87d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -607,6 +607,7 @@ This conversation is no longer verified, as some user uses at least one device without a valid end-to-end identity certificate. All devices are verified (end-to-end identity) All fingerprints are verified (Proteus) + Communication in Wire is always end-to-end encrypted. Everything you send and receive in this conversation is only accessible to you and other group participants.\n**Please still be careful with who you share sensitive information.** You added 1 person to the conversation @@ -823,6 +824,8 @@ If you accept their request, they will be added as a contact and you two can communicate directly. Accept Ignore + Get certainty about the identity of %s\'s before connecting. + Please verify the person\'s identity before accepting the connection request. Media Gallery Saved to Downloads folder diff --git a/kalium b/kalium index 2e787e61d0..85418fc071 160000 --- a/kalium +++ b/kalium @@ -1 +1 @@ -Subproject commit 2e787e61d0d1efff61f851952c92e66fb949cd12 +Subproject commit 85418fc0714c6613ba5ab372233997e3c2eb030f