Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Few more badge fixes #81

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 64 additions & 42 deletions android/ui/src/main/java/com/trafi/ui/Badge.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ import com.trafi.ui.theme.MaasTheme
import com.trafi.ui.theme.currentTheme
import com.trafi.ui.theme.darkColors

/**
*
* Badge does not work with LazyColumn and LazyColumnFor, because parent ConstraintLayout of badge
* has parameter preferredWidth(IntrinsicSize.Min). Without this parameter it is not possible to
* to set custom width to badge.
*
* One of the options is to use same modifier for ConstraintLayout and child layout
* (Surface or other) but then subbadgeIcon flies away from badge.
Comment on lines +29 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed with @stonevyt , this is a blocker, will need to investigate.

*/

@Composable
private val constants
get() = BadgeConstants(currentTheme)
Expand Down Expand Up @@ -52,15 +62,16 @@ fun Badge(
modifier = modifier,
icon = icon,
subbadgeIcon = subbadgeIcon,
isEnabled = isEnabled
isEnabled = isEnabled,
)
} else {
StackedBadge(
modifier = modifier,
badge = badge,
alternativeBadges = alternativeBadges,
icon = icon,
badgeType = badgeType
badgeType = badgeType,
subbadgeIcon = subbadgeIcon,
)
}
}
Expand All @@ -75,15 +86,15 @@ private fun SingleBadge(
subbadgeIcon: ImageVector? = null,
isEnabled: Boolean = true,
) {
ConstraintLayout {
ConstraintLayout(
modifier = modifier.preferredWidth(IntrinsicSize.Min)
) {
Surface(
color = if (isEnabled) badge.backgroundColor else constants.disabledColor,
contentColor = badge.contentColor ?: constants.defaultContentColor,
shape = RoundedCornerShape(badgeType.badgeRounding),
modifier = modifier.sizeIn(minHeight = badgeType.badgeHeight)
.constrainAs(createRef()) {
bottom.linkTo(parent.bottom)
}
modifier = Modifier.sizeIn(minHeight = badgeType.badgeHeight)
.fillMaxWidth()
) {
BadgeFiller(
badgeType = badgeType,
Expand All @@ -109,7 +120,6 @@ private fun SingleBadge(
}
}


@OptIn(ExperimentalLayout::class)
@Composable
private fun StackedBadge(
Expand All @@ -120,15 +130,18 @@ private fun StackedBadge(
subbadgeIcon: ImageVector? = null,
alternativeBadges: List<BadgeInfo> = listOf(),
) {
ConstraintLayout {
ConstraintLayout(
modifier = modifier.preferredWidth(IntrinsicSize.Min)
) {
val altBadgesSublist = alternativeBadges.take(constants.maxStackedBadgesNumber)
altBadgesSublist.forEachIndexed { index, smallScheduleBadge ->
Surface(
color = smallScheduleBadge.backgroundColor,
contentColor = smallScheduleBadge.contentColor ?: constants.defaultContentColor,
border = BorderStroke(constants.borderWidth, color = constants.borderColor),
shape = RoundedCornerShape(badgeType.badgeRounding),
modifier = modifier.height(badgeType.badgeHeight + (index * 4).dp)
modifier = Modifier.height(badgeType.badgeHeight + (index * 4).dp)
.fillMaxWidth()
.padding(top = (index * 4).dp)
) {
BadgeFiller(
Expand All @@ -146,9 +159,10 @@ private fun StackedBadge(
contentColor = badge.contentColor ?: constants.defaultContentColor,
border = BorderStroke(constants.borderWidth, color = constants.borderColor),
shape = RoundedCornerShape(badgeType.badgeRounding),
modifier = modifier
modifier = Modifier
.sizeIn(minHeight = badgeType.badgeHeight + (altBadgesSublist.size * 4).dp + (constants.borderWidth * 2))
.padding(top = (altBadgesSublist.size * 4).dp)
.fillMaxWidth()
) {
BadgeFiller(
badgeType = badgeType,
Expand Down Expand Up @@ -176,6 +190,7 @@ private fun StackedBadge(
}
}

@ExperimentalLayout
@Composable
private fun BadgeFiller(
badgeType: BadgeType,
Expand All @@ -184,37 +199,44 @@ private fun BadgeFiller(
icon: ImageVector?,
isHiddenLayoutFiller: Boolean = false,
) {
Row(
modifier = Modifier.padding(
horizontal = badgeType.getHorizontalPadding(isStackedBadge),
vertical = badgeType.verticalPadding
),
horizontalArrangement = Arrangement.spacedBy(constants.spacer)
Box(
contentAlignment = Alignment.Center,
) {
if (isHiddenLayoutFiller) {
Box(modifier = Modifier.align(Alignment.CenterVertically).width(constants.iconWidth)) {}
} else {
icon?.let {
Image(
icon,
colorFilter = ColorFilter.tint(badge.contentColor
?: constants.defaultContentColor),
Row(
modifier = Modifier
.padding(
horizontal = badgeType.getHorizontalPadding(isStackedBadge),
vertical = badgeType.verticalPadding
),
) {
if (isHiddenLayoutFiller) {
Box(modifier = Modifier.align(Alignment.CenterVertically)
.width(constants.iconWidth)) {}
} else {
icon?.let {
Image(
icon,
colorFilter = ColorFilter.tint(badge.contentColor
?: constants.defaultContentColor),
modifier = Modifier.align(Alignment.CenterVertically)
.width(constants.iconWidth)
.padding(bottom = 1.dp)
.height(constants.iconHeight)
)
}
}
badge.text?.let {
Text(
text = badge.text,
color = badge.contentColor ?: constants.defaultContentColor,
style = badgeType.textStyle,
modifier = Modifier.align(Alignment.CenterVertically)
.width(constants.iconWidth)
.height(constants.iconHeight)
.padding(bottom = 1.dp,
start = if (icon != null) constants.spacer else 0.dp)
.wrapContentHeight(unbounded = true)
)
}
}
badge.text?.let {
Text(
text = badge.text,
color = badge.contentColor ?: constants.defaultContentColor,
style = badgeType.textStyle,
modifier = Modifier.align(Alignment.CenterVertically)
.padding(bottom = 1.dp)
.wrapContentHeight(unbounded = true)
)
}
}
}

Expand All @@ -225,15 +247,13 @@ private val BadgeType.badgeHeight: Dp
Medium -> constants.minHeightMedium
}


@Composable
private val BadgeType.badgeRounding: Dp
get() = when (this) {
Small -> constants.cornerRadiusSmall
Medium -> constants.cornerRadiusMedium
}


@Composable
private fun BadgeType.getHorizontalPadding(isStackedBadge: Boolean): Dp {
return when (this) {
Expand All @@ -251,7 +271,6 @@ private val BadgeType.verticalPadding: Dp
Medium -> constants.verticalPaddingMedium
}


@Composable
private val BadgeType.textStyle: TextStyle
get() = when (this) {
Expand Down Expand Up @@ -283,7 +302,8 @@ fun BadgePreviewWithSubbadge() {
badge = BadgeInfo("5G", Color.Magenta),
icon = vectorResource(R.drawable.providers_ubahn_xs),
subbadgeIcon = vectorResource(id = R.drawable.warning_warning_s),
badgeType = Medium
modifier = Modifier.width(120.dp).padding(12.dp),
badgeType = Medium,
)
}

Expand Down Expand Up @@ -366,6 +386,8 @@ fun StackedBadgePreviewWithSubbadge() {
BadgeInfo("135", Color.Magenta),
BadgeInfo("135", Color.Magenta)),
icon = vectorResource(R.drawable.providers_ubahn_xs),
badgeType = Medium
subbadgeIcon = vectorResource(id = R.drawable.warning_warning_s),
modifier = Modifier.width(150.dp).padding(12.dp),
badgeType = Medium,
)
}