diff --git a/app/src/main/kotlin/com/wire/android/ui/userprofile/common/UserProfileInfo.kt b/app/src/main/kotlin/com/wire/android/ui/userprofile/common/UserProfileInfo.kt index 391682b3e34..4cf987b6985 100644 --- a/app/src/main/kotlin/com/wire/android/ui/userprofile/common/UserProfileInfo.kt +++ b/app/src/main/kotlin/com/wire/android/ui/userprofile/common/UserProfileInfo.kt @@ -19,21 +19,15 @@ package com.wire.android.ui.userprofile.common import android.annotation.SuppressLint -import androidx.annotation.StringRes import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.Crossfade -import androidx.compose.animation.animateContentSize import androidx.compose.foundation.background -import androidx.compose.foundation.clickable 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.Spacer +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.InlineTextContent @@ -54,13 +48,17 @@ import androidx.compose.ui.Alignment.Companion.CenterHorizontally import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.Placeholder import androidx.compose.ui.text.PlaceholderVerticalAlign import androidx.compose.ui.text.buildAnnotatedString 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.sp +import androidx.constraintlayout.compose.ConstraintLayout import com.wire.android.R import com.wire.android.model.ClickBlockParams import com.wire.android.model.Clickable @@ -74,12 +72,13 @@ import com.wire.android.ui.common.UserBadge import com.wire.android.ui.common.UserProfileAvatar import com.wire.android.ui.common.UserProfileAvatarType import com.wire.android.ui.common.banner.SecurityClassificationBannerForUser -import com.wire.android.ui.common.colorsScheme +import com.wire.android.ui.common.button.WireSecondaryButton import com.wire.android.ui.common.dimensions import com.wire.android.ui.common.progress.WireCircularProgressIndicator import com.wire.android.ui.home.conversationslist.model.Membership import com.wire.android.ui.theme.WireTheme import com.wire.android.ui.theme.wireColorScheme +import com.wire.android.ui.theme.wireDimensions import com.wire.android.ui.theme.wireTypography import com.wire.android.util.debug.LocalFeatureVisibilityFlags import com.wire.android.util.ifNotEmpty @@ -179,37 +178,47 @@ fun UserProfileInfo( } } - Row(Modifier.animateContentSize()) { - if (onQrCodeClick != null && isLoading.not()) { - Spacer( - modifier = Modifier - .padding(start = dimensions().spacing16x) - .width(dimensions().spacing24x) + ConstraintLayout( + modifier = Modifier + .padding(horizontal = dimensions().spacing32x) + .then(modifier) + ) { + val (displayName, username, qrIcon) = createRefs() + + val (text, inlineContent: MutableMap) = + processFullName( + fullName = fullName, + isLoading = isLoading, + isProteusVerified = isProteusVerified, + isMLSVerified = isMLSVerified ) - } - Column(horizontalAlignment = CenterHorizontally, modifier = Modifier.weight(1f)) { - Row(modifier = Modifier.padding(horizontal = dimensions().spacing16x)) { - val (text, inlineContent: MutableMap) = - processFullName( - fullName = fullName, - isLoading = isLoading, - isProteusVerified = isProteusVerified, - isMLSVerified = isMLSVerified - ) + Text( + modifier = Modifier + .padding(horizontal = dimensions().spacing16x) + .constrainAs(displayName) { + start.linkTo(parent.start) + end.linkTo(parent.end) + }, + text = text, + // TODO. replace with MIDDLE_ELLIPSIS when available see https://issuetracker.google.com/issues/185418980 + overflow = TextOverflow.Visible, + maxLines = 2, + textAlign = TextAlign.Center, + style = MaterialTheme.wireTypography.title02, + color = if (fullName.isNotBlank()) MaterialTheme.colorScheme.onBackground + else MaterialTheme.wireColorScheme.labelText, + inlineContent = inlineContent + ) - Text( - text = text, - // TODO. replace with MIDDLE_ELLIPSIS when available see https://issuetracker.google.com/issues/185418980 - overflow = TextOverflow.Visible, - maxLines = 2, - textAlign = TextAlign.Center, - style = MaterialTheme.wireTypography.title02, - color = if (fullName.isNotBlank()) MaterialTheme.colorScheme.onBackground - else MaterialTheme.wireColorScheme.labelText, - inlineContent = inlineContent - ) + Column( + horizontalAlignment = CenterHorizontally, + modifier = Modifier.constrainAs(username) { + start.linkTo(parent.start) + end.linkTo(parent.end) + top.linkTo(displayName.bottom) } + ) { Text( text = processUsername(userName, membership, expiresAt), overflow = TextOverflow.Ellipsis, @@ -221,9 +230,18 @@ fun UserProfileInfo( UserBadge(membership, connection, topPadding = dimensions().spacing8x) } - if (onQrCodeClick != null && isLoading.not()) { - Column(Modifier.padding(end = dimensions().spacing16x)) { - QRCodeIcon(onQrCodeClick) + Column( + Modifier + .padding(top = dimensions().spacing0x, start = dimensions().spacing4x) + .constrainAs(qrIcon) { + start.linkTo(if (fullName.length > userName.length) displayName.end else username.end) + end.linkTo(parent.end) + top.linkTo(displayName.top) + bottom.linkTo(displayName.bottom) + } + ) { + if (isLoading.not()) { + onQrCodeClick?.let { QRCodeIcon(it) } } } } @@ -319,15 +337,16 @@ private fun createMiddleEllipsizeIfNeeded( fun QRCodeIcon( onQrCodeClick: () -> Unit, modifier: Modifier = Modifier, - @StringRes contentDescriptionId: Int = R.string.user_profile_qr_code_share_link ) { - androidx.compose.material3.Icon( - imageVector = Icons.Filled.QrCode, - contentDescription = stringResource(contentDescriptionId), - modifier = modifier - .size(dimensions().spacing24x) - .clickable { onQrCodeClick() }, - tint = colorsScheme().onBackground + val contentDescription = stringResource(id = R.string.user_profile_qr_code_share_link) + WireSecondaryButton( + modifier = modifier.semantics { this.contentDescription = contentDescription }, + leadingIcon = Icons.Filled.QrCode.Icon(), + contentPadding = PaddingValues(0.dp), + onClick = onQrCodeClick, + fillMaxWidth = false, + minSize = MaterialTheme.wireDimensions.buttonSmallMinSize, + minClickableSize = MaterialTheme.wireDimensions.buttonMinClickableSize, ) }