Browse Source

Apply colors to default user avatar in the timeline.

pull/1224/head
Benoit Marty 1 year ago
parent
commit
1cffbbdca7
  1. 2
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt
  2. 8
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/Avatar.kt
  3. 51
      libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/UserAvatarPreview.kt
  4. 12
      libraries/designsystem/src/test/kotlin/io/element/android/libraries/designsystem/colors/AvatarColorsTest.kt

2
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt

@ -346,7 +346,7 @@ private fun MessageSenderInformation(
} }
// Content // Content
Row { Row {
Avatar(senderAvatar) Avatar(senderAvatar, avatarColors = avatarColors)
Spacer(modifier = Modifier.width(4.dp)) Spacer(modifier = Modifier.width(4.dp))
Text( Text(
text = sender, text = sender,

8
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.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage 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.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar
@ -45,6 +46,7 @@ import timber.log.Timber
fun Avatar( fun Avatar(
avatarData: AvatarData, avatarData: AvatarData,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
avatarColors: AvatarColors? = null,
contentDescription: String? = null, contentDescription: String? = null,
) { ) {
val commonModifier = modifier val commonModifier = modifier
@ -53,6 +55,7 @@ fun Avatar(
if (avatarData.url.isNullOrBlank()) { if (avatarData.url.isNullOrBlank()) {
InitialsAvatar( InitialsAvatar(
avatarData = avatarData, avatarData = avatarData,
avatarColors = avatarColors,
modifier = commonModifier, modifier = commonModifier,
) )
} else { } else {
@ -85,12 +88,13 @@ private fun ImageAvatar(
@Composable @Composable
private fun InitialsAvatar( private fun InitialsAvatar(
avatarData: AvatarData, avatarData: AvatarData,
avatarColors: AvatarColors?,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
// Use temporary color for default avatar background // Use temporary color for default avatar background
val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled val avatarColor = ElementTheme.colors.bgActionPrimaryDisabled
Box( Box(
modifier.background(color = avatarColor), modifier.background(color = avatarColors?.background ?: avatarColor)
) { ) {
val fontSize = avatarData.size.dp.toSp() / 2 val fontSize = avatarData.size.dp.toSp() / 2
val originalFont = ElementTheme.typography.fontBodyMdRegular val originalFont = ElementTheme.typography.fontBodyMdRegular
@ -100,7 +104,7 @@ private fun InitialsAvatar(
modifier = Modifier.align(Alignment.Center), modifier = Modifier.align(Alignment.Center),
text = avatarData.initial, text = avatarData.initial,
style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp), style = originalFont.copy(fontSize = fontSize, lineHeight = lineHeight, letterSpacing = 0.sp),
color = Color.White, color = avatarColors?.foreground ?: Color.White,
) )
} }
} }

51
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")
}
}
}
}

12
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("@bob:domain.org".toHash()).isEqualTo(3)
assertThat("@charlie:domain.org".toHash()).isEqualTo(0) 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)
}
} }

Loading…
Cancel
Save