Add unread count to the room unread indicator (#6887)

* Add unread indicator count

* Address review
This commit is contained in:
bxdxnn
2026-06-03 18:08:35 +03:00
committed by GitHub
parent 2ab780576a
commit 27cdc0fe7d
9 changed files with 69 additions and 13 deletions
@@ -18,6 +18,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.rememberTextMeasurer
import androidx.compose.ui.unit.dp
@@ -37,13 +38,18 @@ private const val MAX_COUNT_STRING = "+$MAX_COUNT"
* @param count The number to display. If the number is greater than [MAX_COUNT], the counter will display [MAX_COUNT_STRING].
* If the number is less than 1, the counter will not be displayed.
* @param modifier The modifier to apply to this layout.
* @param containerColor The background color of the counter. When null, uses [isCritical] to pick a default.
* @param contentColor The text color inside the counter. When null, uses [textOnSolidPrimary].
* @param textStyle The style to apply to the text inside the counter.
* @param isCritical If true, the counter will use a critical color scheme, otherwise it will use an accent color scheme.
* Only used when [containerColor] is null.
*/
@Composable
fun CounterAtom(
count: Int,
modifier: Modifier = Modifier,
containerColor: Color? = null,
contentColor: Color? = null,
textStyle: TextStyle = CounterAtomDefaults.textStyle,
isCritical: Boolean = false,
) {
@@ -65,7 +71,7 @@ fun CounterAtom(
.size(squareSize.toDp() + 1.dp)
.clip(CircleShape)
.background(
if (isCritical) {
containerColor ?: if (isCritical) {
ElementTheme.colors.iconCriticalPrimary
} else {
ElementTheme.colors.iconAccentPrimary
@@ -76,7 +82,7 @@ fun CounterAtom(
modifier = Modifier.align(Alignment.Center),
text = countAsText,
style = textStyle,
color = ElementTheme.colors.textOnSolidPrimary,
color = contentColor ?: ElementTheme.colors.textOnSolidPrimary,
)
}
}
@@ -10,6 +10,7 @@ package io.element.android.libraries.designsystem.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
@@ -29,19 +30,32 @@ import io.element.android.libraries.designsystem.theme.unreadIndicator
fun UnreadIndicatorAtom(
modifier: Modifier = Modifier,
size: Dp = 12.dp,
count: Long? = null,
color: Color = ElementTheme.colors.unreadIndicator,
isVisible: Boolean = true,
contentDescription: String? = null,
) {
Box(
modifier = modifier
.semantics {
when {
!isVisible -> Spacer(modifier = modifier.size(size))
count != null && count >= 1 -> CounterAtom(
count = count.toInt(),
modifier = modifier.semantics {
contentDescription?.let { this.contentDescription = it }
}
.size(size)
.clip(CircleShape)
.background(if (isVisible) color else Color.Transparent)
)
},
containerColor = color,
contentColor = ElementTheme.colors.bgCanvasDefault,
textStyle = ElementTheme.typography.fontBodySmMedium,
)
else -> Box(
modifier = modifier
.semantics {
contentDescription?.let { this.contentDescription = it }
}
.size(size)
.clip(CircleShape)
.background(color),
)
}
}
@PreviewsDayNight