Skip to content

Commit

Permalink
feat: User verification status Proteus (WPB-1775) (#2299)
Browse files Browse the repository at this point in the history
  • Loading branch information
borichellow authored Oct 13, 2023
1 parent 594aa8a commit d3d6bf7
Show file tree
Hide file tree
Showing 20 changed files with 153 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ class UIParticipantMapper @Inject constructor(
unavailable = unavailable,
isDeleted = (user is OtherUser && user.deleted),
botService = (user as? OtherUser)?.botService,
isDefederated = (user is OtherUser && user.defederated)
isDefederated = (user is OtherUser && user.defederated),
isProteusVerified = (user is OtherUser && user.isProteusVerified),
)
}

Expand All @@ -69,7 +70,8 @@ class UIParticipantMapper @Inject constructor(
unavailable = !userSummary.isUserDeleted && userSummary.userName.orEmpty().isEmpty(),
isDeleted = userSummary.isUserDeleted,
isSelf = isSelfUser,
isDefederated = false
isDefederated = false,
isProteusVerified = false
)
}

Expand All @@ -84,7 +86,8 @@ class UIParticipantMapper @Inject constructor(
isDeleted = userSummary.isUserDeleted,
isSelf = false,
readReceiptDate = date,
isDefederated = false
isDefederated = false,
isProteusVerified = false
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ class MigrationMapper @Inject constructor() {
availabilityStatus = mapUserAvailabilityStatus(scalaUserData.availability),
botService = botService,
deleted = scalaUserData.deleted,
defederated = false
defederated = false,
isProteusVerified = false
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
package com.wire.android.ui.authentication.devices

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
Expand All @@ -49,14 +47,14 @@ import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.wire.android.BuildConfig
import com.wire.android.R
import com.wire.android.ui.authentication.devices.model.Device
import com.wire.android.ui.authentication.devices.model.lastActiveDescription
import com.wire.android.ui.common.ProteusVerifiedIcon
import com.wire.android.ui.common.button.WireSecondaryButton
import com.wire.android.ui.common.button.getMinTouchMargins
import com.wire.android.ui.common.button.wireSecondaryButtonColors
Expand Down Expand Up @@ -185,7 +183,7 @@ private fun DeviceItemTexts(
)
if (shouldShowVerifyLabel) {
Spacer(modifier = Modifier.width(MaterialTheme.wireDimensions.spacing8x))
VerifyLabel(device.isVerified, Modifier.wrapContentWidth())
if (device.isVerifiedProteus) ProteusVerifiedIcon(Modifier.wrapContentWidth())
}
}

Expand Down Expand Up @@ -249,35 +247,12 @@ private fun DeviceItemTexts(
)
}

@Composable
fun VerifyLabel(isVerified: Boolean, modifier: Modifier = Modifier) {
Box(
modifier = modifier.border(
width = MaterialTheme.wireDimensions.spacing1x,
shape = RoundedCornerShape(MaterialTheme.wireDimensions.spacing4x),
color = if (isVerified) MaterialTheme.wireColorScheme.primary else MaterialTheme.wireColorScheme.secondaryText,
)
) {
Text(
text = stringResource(id = if (isVerified) R.string.label_client_verified else R.string.label_client_unverified),
color = if (isVerified) MaterialTheme.wireColorScheme.primary else MaterialTheme.wireColorScheme.secondaryText,
style = MaterialTheme.wireTypography.label03,
textAlign = TextAlign.Center,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.wrapContentWidth()
.padding(horizontal = MaterialTheme.wireDimensions.spacing4x, vertical = MaterialTheme.wireDimensions.spacing2x)
)
}
}

@PreviewMultipleThemes
@Composable
fun PreviewDeviceItem() {
WireTheme {
DeviceItem(
device = Device(name = UIText.DynamicString("name")),
device = Device(name = UIText.DynamicString("name"), isVerifiedProteus = true),
placeholder = false,
shouldShowVerifyLabel = true,
background = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ data class Device(
val registrationTime: String? = null,
val lastActiveInWholeWeeks: Int? = null,
val isValid: Boolean = true,
val isVerified: Boolean = false,
val isVerifiedProteus: Boolean = false,
val mlsPublicKeys: Map<String, String>? = null
) {
constructor(client: Client) : this(
Expand All @@ -47,7 +47,7 @@ data class Device(
registrationTime = client.registrationTime?.toIsoDateTimeString(),
lastActiveInWholeWeeks = client.lastActiveInWholeWeeks(),
isValid = client.isValid,
isVerified = client.isVerified,
isVerifiedProteus = client.isVerified,
mlsPublicKeys = client.mlsPublicKeys
)
}
Expand Down
35 changes: 35 additions & 0 deletions app/src/main/kotlin/com/wire/android/ui/common/VerifiedIcons.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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.common

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import com.wire.android.R

@Composable
fun ProteusVerifiedIcon(modifier: Modifier = Modifier) {
Image(
modifier = modifier.padding(start = dimensions().spacing4x),
painter = painterResource(id = R.drawable.ic_certificate_valid_proteus),
contentDescription = stringResource(R.string.label_client_verified)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,36 @@ fun WireCenterAlignedTopAppBar(
actions: @Composable RowScope.() -> Unit = {},
modifier: Modifier = Modifier,
bottomContent: @Composable ColumnScope.() -> Unit = {}
) {
WireCenterAlignedTopAppBar(
titleContent = {
WireTopAppBarTitle(
title = title,
style = titleStyle,
maxLines = maxLines
)
},
subtitleContent = subtitleContent,
onNavigationPressed = onNavigationPressed,
navigationIconType = navigationIconType,
elevation = elevation,
actions = actions,
modifier = modifier,
bottomContent = bottomContent
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WireCenterAlignedTopAppBar(
titleContent: @Composable ColumnScope.() -> Unit,
subtitleContent: @Composable ColumnScope.() -> Unit = {},
onNavigationPressed: () -> Unit = {},
navigationIconType: NavigationIconType? = NavigationIconType.Back,
elevation: Dp = MaterialTheme.wireDimensions.topBarShadowElevation,
actions: @Composable RowScope.() -> Unit = {},
modifier: Modifier = Modifier,
bottomContent: @Composable ColumnScope.() -> Unit = {}
) {
Surface(
modifier = modifier,
Expand All @@ -62,11 +92,7 @@ fun WireCenterAlignedTopAppBar(
CenterAlignedTopAppBar(
title = {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
WireTopAppBarTitle(
title = title,
style = titleStyle,
maxLines = maxLines
)
titleContent()
subtitleContent()
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import com.wire.android.R
import com.wire.android.model.Clickable
import com.wire.android.model.UserAvatarData
import com.wire.android.ui.common.ArrowRightIcon
import com.wire.android.ui.common.ProteusVerifiedIcon
import com.wire.android.ui.common.RowItemTemplate
import com.wire.android.ui.common.UserBadge
import com.wire.android.ui.common.UserProfileAvatar
Expand Down Expand Up @@ -92,8 +93,9 @@ fun ConversationParticipantItem(
startPadding = dimensions().spacing6x,
isDeleted = uiParticipant.isDeleted
)
}

if (uiParticipant.isProteusVerified) ProteusVerifiedIcon()
}
},
subtitle = {
HighlightSubtitle(
Expand Down Expand Up @@ -125,7 +127,7 @@ fun ConversationParticipantItem(
@Composable
fun PreviewGroupConversationParticipantItem() {
ConversationParticipantItem(
UIParticipant(UserId("0", ""), "name", "handle", false, false, UserAvatarData(), Membership.Guest),
UIParticipant(UserId("0", ""), "name", "handle", false, false, UserAvatarData(), Membership.Guest, isProteusVerified = true),
clickable = Clickable(enabled = true) {}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@ data class UIParticipant(
val isDeleted: Boolean = false,
val readReceiptDate: Instant? = null,
val botService: BotService? = null,
val isDefederated: Boolean = false
val isDefederated: Boolean = false,
val isProteusVerified: Boolean = false
)
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import com.wire.android.ui.authentication.devices.remove.RemoveDeviceDialog
import com.wire.android.ui.authentication.devices.remove.RemoveDeviceDialogState
import com.wire.android.ui.authentication.devices.remove.RemoveDeviceError
import com.wire.android.ui.common.CopyButton
import com.wire.android.ui.common.ProteusVerifiedIcon
import com.wire.android.ui.common.WireDialog
import com.wire.android.ui.common.WireDialogButtonProperties
import com.wire.android.ui.common.WireDialogButtonType
Expand All @@ -52,6 +53,7 @@ import com.wire.android.ui.common.colorsScheme
import com.wire.android.ui.common.dimensions
import com.wire.android.ui.common.scaffold.WireScaffold
import com.wire.android.ui.common.topappbar.WireCenterAlignedTopAppBar
import com.wire.android.ui.common.topappbar.WireTopAppBarTitle
import com.wire.android.ui.home.conversationslist.common.FolderHeader
import com.wire.android.ui.settings.devices.model.DeviceDetailsState
import com.wire.android.ui.theme.wireColorScheme
Expand Down Expand Up @@ -102,13 +104,7 @@ fun DeviceDetailsContent(
) {
val screenState = rememberConversationScreenState()
WireScaffold(
topBar = {
WireCenterAlignedTopAppBar(
onNavigationPressed = onNavigateBack,
elevation = 0.dp,
title = state.device.name.asString()
)
},
topBar = { DeviceDetailsTopBar(onNavigateBack, state.device, state.isCurrentDevice) },
bottomBar = {
Column(
Modifier
Expand Down Expand Up @@ -195,7 +191,7 @@ fun DeviceDetailsContent(
if (!state.isCurrentDevice) {
item {
DeviceVerificationItem(
state.device.isVerified,
state.device.isVerifiedProteus,
state.fingerPrint != null,
state.isSelfClient,
state.userName,
Expand Down Expand Up @@ -231,6 +227,30 @@ fun DeviceDetailsContent(
}
}

@Composable
private fun DeviceDetailsTopBar(
onNavigateBack: () -> Unit,
device: Device,
isCurrentDevice: Boolean
) {
WireCenterAlignedTopAppBar(
onNavigationPressed = onNavigateBack,
elevation = 0.dp,
titleContent = {
Row {
WireTopAppBarTitle(
title = device.name.asString(),
style = MaterialTheme.wireTypography.title01,
maxLines = 2
)
if (!isCurrentDevice && device.isVerifiedProteus) {
ProteusVerifiedIcon()
}
}
}
)
}

@Composable
private fun DeviceIdItem(state: DeviceDetailsState, onCopy: (String) -> Unit) {
DeviceDetailSectionContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.CircleShape
Expand All @@ -56,6 +56,7 @@ import com.wire.android.model.Clickable
import com.wire.android.model.ImageAsset.UserAvatarAsset
import com.wire.android.model.UserAvatarData
import com.wire.android.ui.common.Icon
import com.wire.android.ui.common.ProteusVerifiedIcon
import com.wire.android.ui.common.UserBadge
import com.wire.android.ui.common.UserProfileAvatar
import com.wire.android.ui.common.banner.SecurityClassificationBannerForUser
Expand Down Expand Up @@ -87,6 +88,7 @@ fun UserProfileInfo(
modifier: Modifier = Modifier,
connection: ConnectionState = ConnectionState.ACCEPTED,
delayToShowPlaceholderIfNoAsset: Duration = 200.milliseconds,
isProteusVerified: Boolean = false
) {
Column(
horizontalAlignment = CenterHorizontally,
Expand Down Expand Up @@ -163,16 +165,21 @@ fun UserProfileInfo(
end.linkTo(parent.end)
}
) {
Text(
text = fullName.ifBlank {
if (isLoading) ""
else UIText.StringResource(R.string.username_unavailable_label).asString()
},
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.wireTypography.title02,
color = if (fullName.isNotBlank()) MaterialTheme.colorScheme.onBackground else MaterialTheme.wireColorScheme.labelText
)
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = fullName.ifBlank {
if (isLoading) ""
else UIText.StringResource(R.string.username_unavailable_label).asString()
},
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.wireTypography.title02,
color = if (fullName.isNotBlank()) MaterialTheme.colorScheme.onBackground
else MaterialTheme.wireColorScheme.labelText
)

if (isProteusVerified) ProteusVerifiedIcon()
}
Text(
text = if (membership == Membership.Service) userName else userName.ifNotEmpty { "@$userName" },
overflow = TextOverflow.Ellipsis,
Expand Down Expand Up @@ -261,6 +268,7 @@ fun PreviewUserProfileInfo() {
fullName = "fullName",
onUserProfileClick = {},
teamName = "Wire",
connection = ConnectionState.ACCEPTED
connection = ConnectionState.ACCEPTED,
isProteusVerified = true
)
}
Loading

0 comments on commit d3d6bf7

Please sign in to comment.