diff --git a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt index 0b0676074b..cc467585cb 100644 --- a/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt +++ b/features/ftue/impl/src/main/kotlin/io/element/android/features/ftue/impl/notifications/NotificationsOptInView.kt @@ -43,7 +43,7 @@ import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMo import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.colors.AvatarColors -import io.element.android.libraries.designsystem.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize @@ -119,21 +119,21 @@ private fun NotificationsOptInContent( ) { NotificationRow( avatarLetter = "M", - avatarColors = avatarColors("5"), + avatarColors = AvatarColorsProvider.provide("5", ElementTheme.isLightTheme), firstRowPercent = 1f, secondRowPercent = 0.4f ) NotificationRow( avatarLetter = "A", - avatarColors = avatarColors("1"), + avatarColors = AvatarColorsProvider.provide("1", ElementTheme.isLightTheme), firstRowPercent = 1f, secondRowPercent = 1f ) NotificationRow( avatarLetter = "T", - avatarColors = avatarColors("4"), + avatarColors = AvatarColorsProvider.provide("4", ElementTheme.isLightTheme), firstRowPercent = 0.65f, secondRowPercent = 0f ) 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 30478c6ef0..d62513f95f 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.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider 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 avatarColors = avatarColors(senderAvatar.id) + val avatarColors = AvatarColorsProvider.provide(senderAvatar.id, ElementTheme.isLightTheme) Box( modifier = modifier ) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt index fb379c751e..c12be3b37d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/colors/AvatarColors.kt @@ -16,9 +16,8 @@ package io.element.android.libraries.designsystem.colors -import androidx.compose.runtime.Composable +import androidx.collection.LruCache import androidx.compose.ui.graphics.Color -import io.element.android.libraries.theme.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsDark import io.element.android.libraries.theme.colors.avatarColorsLight @@ -27,18 +26,37 @@ data class AvatarColors( val foreground: Color, ) -@Composable -fun avatarColors(userId: String): AvatarColors { - val hash = userId.toHash() - val colors = if (ElementTheme.isLightTheme) { - avatarColorsLight[hash] - } else { - avatarColorsDark[hash] +object AvatarColorsProvider { + private val cache = LruCache(200) + private var currentThemeIsLight = true + + fun provide(id: String, isLightTheme: Boolean): AvatarColors { + if (currentThemeIsLight != isLightTheme) { + currentThemeIsLight = isLightTheme + cache.evictAll() + } + val valueFromCache = cache.get(id) + return if (valueFromCache != null) { + valueFromCache + } else { + val colors = avatarColors(id, isLightTheme) + cache.put(id, colors) + colors + } + } + + private fun avatarColors(id: String, isLightTheme: Boolean): AvatarColors { + val hash = id.toHash() + val colors = if (isLightTheme) { + avatarColorsLight[hash] + } else { + avatarColorsDark[hash] + } + return AvatarColors( + background = colors.first, + foreground = colors.second, + ) } - return AvatarColors( - background = colors.first, - foreground = colors.second, - ) } internal fun String.toHash(): Int { 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 ce39be4df7..a0349931fe 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,7 +33,7 @@ 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.colors.avatarColors +import io.element.android.libraries.designsystem.colors.AvatarColorsProvider import io.element.android.libraries.designsystem.preview.ElementThemedPreview import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar @@ -53,7 +53,7 @@ fun Avatar( .size(avatarData.size.dp) .clip(CircleShape) if (avatarData.url.isNullOrBlank()) { - val avatarColors = initialAvatarColors ?: avatarColors(avatarData.id) + val avatarColors = initialAvatarColors ?: AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme) InitialsAvatar( avatarData = avatarData, avatarColors = avatarColors, 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 index 817650ffa7..2cfd820420 100644 --- 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 @@ -24,10 +24,11 @@ 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.colors.AvatarColorsProvider 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.ElementTheme import io.element.android.libraries.theme.colors.avatarColorsLight @DayNightPreviews @@ -43,7 +44,7 @@ internal fun UserAvatarPreview() = ElementPreview { verticalAlignment = Alignment.CenterVertically, ) { // Note: it's OK, since the hash of "0" is 0, the hash of "1" is 1, etc. - Avatar(anAvatarData(), initialAvatarColors = avatarColors("$it")) + Avatar(anAvatarData(), initialAvatarColors = AvatarColorsProvider.provide("$it", ElementTheme.isLightTheme)) Text(text = "Color index $it") } }