Implement a in-memory cache for user avatar colors.
This commit is contained in:
committed by
Benoit Marty
parent
06a607abf8
commit
5a85efc458
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
|
||||
@@ -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<String, AvatarColors>(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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user