Implement a in-memory cache for user avatar colors.
This commit is contained in:
committed by
Benoit Marty
parent
06a607abf8
commit
5a85efc458
@@ -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