diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 56ad1c338e..b5229c2656 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -346,7 +346,7 @@ private fun MessageSenderInformation( } // Content Row { - Avatar(senderAvatar) + Avatar(senderAvatar, avatarColors = avatarColors) Spacer(modifier = Modifier.width(4.dp)) Text( text = sender, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt index 2e2d98ddbb..cfc2efd6ae 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt @@ -33,6 +33,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage +import io.element.android.libraries.designsystem.colors.AvatarColors import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar @@ -45,6 +46,7 @@ import timber.log.Timber fun Avatar( avatarData: AvatarData, modifier: Modifier = Modifier, + avatarColors: AvatarColors? = null, contentDescription: String? = null, ) { val commonModifier = modifier @@ -53,6 +55,7 @@ fun Avatar( if (avatarData.url.isNullOrBlank()) { InitialsAvatar( avatarData = avatarData, + avatarColors = avatarColors, modifier = commonModifier, ) } else { @@ -85,12 +88,13 @@ private fun ImageAvatar( @Composable private fun InitialsAvatar( avatarData: AvatarData, + avatarColors: AvatarColors?, modifier: Modifier = Modifier, ) { // Use temporary color for default avatar background val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled Box( - modifier.background(color = avatarColor), + modifier.background(color = avatarColors?.background ?: avatarColor) ) { val fontSize = avatarData.size.dp.toSp() / 2 val originalFont = ElementTheme.typography.fontBodyMdRegular @@ -100,7 +104,7 @@ private fun InitialsAvatar( modifier = Modifier.align(Alignment.Center), text = avatarData.initial, style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), - color = Color.White, + color = avatarColors?.foreground ?: Color.White, ) } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt new file mode 100644 index 0000000000..f47ee9bb7a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.components.avatar + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.colors.AvatarColors +import io.element.android.libraries.designsystem.preview.DayNightPreviews +import io.element.android.libraries.designsystem.preview.ElementPreview +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.theme.colors.avatarColorsLight + +@DayNightPreviews +@Composable +internal fun UserAvatarPreview() = ElementPreview { + Column( + modifier = Modifier.padding(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + repeat(avatarColorsLight.size) { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. + Avatar(anAvatarData(), avatarColors = AvatarColors("$it")) + Text(text = "Color index $it") + } + } + } +} diff --git a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt index 2b91a9e490..8e92e8186c 100644 --- a/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt @@ -37,4 +37,16 @@ class AvatarColorsTest { assertThat("@bob:domain.org".toHash()).isEqualTo(3) assertThat("@charlie:domain.org".toHash()).isEqualTo(0) } + + @Test + fun `compute string hash reverse`() { + assertThat("0".toHash()).isEqualTo(0) + assertThat("1".toHash()).isEqualTo(1) + assertThat("2".toHash()).isEqualTo(2) + assertThat("3".toHash()).isEqualTo(3) + assertThat("4".toHash()).isEqualTo(4) + assertThat("5".toHash()).isEqualTo(5) + assertThat("6".toHash()).isEqualTo(6) + assertThat("7".toHash()).isEqualTo(7) + } }