From a79e3d41d6134eac3fb414e293e1ba9528811bee Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 5 Sep 2023 12:12:59 +0200 Subject: [PATCH] Compute avatar color of users and apply foreground color to the sender displayname. --- .../components/TimelineItemEventRow.kt | 6 +-- .../{AvatarColor.kt => AvatarColors.kt} | 14 +++---- .../designsystem/colors/AvatarColorsTest.kt | 40 +++++++++++++++++++ 3 files changed, 50 insertions(+), 10 deletions(-) rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/{AvatarColor.kt => AvatarColors.kt} (80%) create mode 100644 libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt 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 e1c6b746d2..56ad1c338e 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 @@ -75,7 +75,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemPollContent import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent -import io.element.android.libraries.designsystem.colors.AvatarColor +import io.element.android.libraries.designsystem.colors.AvatarColors import io.element.android.libraries.designsystem.components.EqualWidthColumn import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData @@ -328,7 +328,7 @@ private fun MessageSenderInformation( ) { val avatarStrokeColor = MaterialTheme.colorScheme.background val avatarSize = senderAvatar.size.dp - val avatarColor = AvatarColor(senderAvatar.id) + val avatarColors = AvatarColors(senderAvatar.id) Box( modifier = modifier ) { @@ -352,7 +352,7 @@ private fun MessageSenderInformation( text = sender, maxLines = 1, overflow = TextOverflow.Ellipsis, - color = avatarColor.foreground, + color = avatarColors.foreground, style = ElementTheme.typography.fontBodyMdMedium, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt similarity index 80% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index 0edd90132a..e73cbf3218 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColor.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -22,26 +22,26 @@ import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsDark import io.element.android.libraries.theme.colors.avatarColorsLight -data class AvatarColor( +data class AvatarColors( val background: Color, val foreground: Color, ) @Composable -fun AvatarColor(userId: String): AvatarColor { +fun AvatarColors(userId: String): AvatarColors { val hash = userId.toHash() val colors = if (ElementTheme.isLightTheme) { - avatarColorsLight[hash % avatarColorsLight.size] + avatarColorsLight[hash] } else { - avatarColorsDark[hash % avatarColorsDark.size] + avatarColorsDark[hash] } - return AvatarColor( + return AvatarColors( background = colors.first, foreground = colors.second, ) } -private fun String.toHash(): Int { - return toList().sumOf { it.code } % 8 + 1 +internal fun String.toHash(): Int { + return toList().sumOf { it.code } % 8 } 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 new file mode 100644 index 0000000000..2b91a9e490 --- /dev/null +++ b/libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt @@ -0,0 +1,40 @@ +/* + * 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.colors + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.theme.colors.avatarColorsDark +import io.element.android.libraries.theme.colors.avatarColorsLight +import org.junit.Test + +class AvatarColorsTest { + + @Test + fun `ensure list size`() { + // avatarColorsDark and avatarColorsLight size must not be modified. + // 8 is used as a hard-coded modulo in `String.toHash()` extension. + assertThat(avatarColorsDark.size).isEqualTo(8) + assertThat(avatarColorsLight.size).isEqualTo(8) + } + + @Test + fun `compute string hash`() { + assertThat("@alice:domain.org".toHash()).isEqualTo(6) + assertThat("@bob:domain.org".toHash()).isEqualTo(3) + assertThat("@charlie:domain.org".toHash()).isEqualTo(0) + } +}