Display user status next to display names across rooms and profiles

This commit is contained in:
ganfra
2026-06-24 17:59:08 +02:00
parent 18034e02a2
commit 06a903718b
46 changed files with 386 additions and 89 deletions
@@ -42,6 +42,8 @@ import io.element.android.libraries.designsystem.theme.components.ButtonSize
import io.element.android.libraries.designsystem.theme.components.OutlinedButton
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.DisplayedStatus
import io.element.android.libraries.matrix.ui.model.toText
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag
import io.element.android.libraries.ui.strings.CommonStrings
@@ -56,6 +58,7 @@ fun UserProfileHeaderSection(
openAvatarPreview: (url: String) -> Unit,
onUserIdClick: () -> Unit,
withdrawVerificationClick: () -> Unit,
displayedStatus: DisplayedStatus?,
modifier: Modifier = Modifier
) {
Column(
@@ -90,7 +93,16 @@ fun UserProfileHeaderSection(
style = ElementTheme.typography.fontHeadingLgBold,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(6.dp))
Spacer(modifier = Modifier.height(12.dp))
}
displayedStatus?.let { status ->
Text(
text = status.toText(),
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textSecondary,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(12.dp))
}
Text(
modifier = Modifier.niceClickable { onUserIdClick() },
@@ -99,6 +111,7 @@ fun UserProfileHeaderSection(
color = ElementTheme.colors.textSecondary,
textAlign = TextAlign.Center,
)
Spacer(modifier = Modifier.height(12.dp))
when (verificationState) {
UserProfileVerificationState.UNKNOWN, UserProfileVerificationState.UNVERIFIED -> Unit
UserProfileVerificationState.VERIFIED -> {
@@ -143,6 +156,7 @@ internal fun UserProfileHeaderSectionPreview() = ElementPreview {
userId = UserId("@alice:example.com"),
userName = USER_NAME_ALICE,
verificationState = UserProfileVerificationState.VERIFIED,
displayedStatus = DisplayedStatus.InCall(0L),
openAvatarPreview = {},
onUserIdClick = {},
withdrawVerificationClick = {},
@@ -157,6 +171,7 @@ internal fun UserProfileHeaderSectionWithVerificationViolationPreview() = Elemen
userId = UserId("@alice:example.com"),
userName = USER_NAME_ALICE,
verificationState = UserProfileVerificationState.VERIFICATION_VIOLATION,
displayedStatus = DisplayedStatus.InCall(0L),
openAvatarPreview = {},
onUserIdClick = {},
withdrawVerificationClick = {},
@@ -18,6 +18,7 @@ import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarMessage
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.user.DisplayedStatus
import io.element.android.libraries.matrix.ui.components.aMatrixUser
open class UserProfileStateProvider : PreviewParameterProvider<UserProfileState> {
@@ -48,6 +49,7 @@ fun aUserProfileState(
dmRoomId: RoomId? = null,
canCall: Boolean = false,
snackbarMessage: SnackbarMessage? = null,
displayedStatus: DisplayedStatus? = null,
eventSink: (UserProfileEvents) -> Unit = {},
) = UserProfileState(
userId = userId,
@@ -61,5 +63,6 @@ fun aUserProfileState(
dmRoomId = dmRoomId,
canCall = canCall,
snackbarMessage = snackbarMessage,
displayedStatus = displayedStatus,
eventSink = eventSink,
)
@@ -78,6 +78,7 @@ fun UserProfileView(
userId = state.userId,
userName = state.userName,
verificationState = state.verificationState,
displayedStatus = state.displayedStatus,
openAvatarPreview = { avatarUrl ->
openAvatarPreview(state.userName ?: state.userId.value, avatarUrl)
},