fix(dashboard): render verificado en dispositivo EMUI

- Header reestructurado: en el Huawei de prueba el Row con Alignment.Bottom
  + SpaceBetween medía ~270dp fantasma, aplastando la lista de hábitos a
  altura 0 (las tarjetas ni se componían). Ahora es columna simple con
  chips en fila propia y maxLines acotados.
- LazyColumn con weight(1f) en vez de fillMaxSize dentro de Column sin peso.
- Singular '1 día de racha' / '1 día' (antes '1 días').
This commit is contained in:
Johann
2026-07-03 23:22:56 -06:00
parent 92285bbff2
commit 0eb4133345
4 changed files with 42 additions and 36 deletions
@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
@@ -100,39 +101,41 @@ private fun CenterColumn(
onToggleHabit: (String) -> Unit, onToggleHabit: (String) -> Unit,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(12.dp)) { // Header laid out as a plain top-anchored column with height-bounded rows.
// On the EMUI test device the previous Bottom-aligned SpaceBetween header
// measured ~270 dp tall (giant invisible text box), crushing the habit list
// to zero height — see STATUS.md session 2.
val pendingText = when (uiState.pendingCount) {
0 -> stringResource(R.string.dashboard_pending_zero)
1 -> stringResource(R.string.dashboard_pending_one)
else -> stringResource(R.string.dashboard_pending_many, uiState.pendingCount)
}
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(10.dp)) {
Text(
text = stringResource(R.string.dashboard_greeting, uiState.childName),
style = MaterialTheme.typography.headlineMedium,
maxLines = 1,
)
Text(
text = "${uiState.dateLine} · $pendingText",
style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep),
maxLines = 2,
)
Row( Row(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.Bottom, verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween, horizontalArrangement = Arrangement.spacedBy(8.dp),
) { ) {
Column { BackgroundChip()
Text( Spacer(modifier = Modifier.weight(1f))
text = stringResource(R.string.dashboard_greeting, uiState.childName), uiState.battery?.let { BatteryChip(it) }
style = MaterialTheme.typography.headlineMedium, TodayCounterPill(done = uiState.doneCount, total = uiState.totalCount)
)
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
Text(
text = "${uiState.dateLine} · ${pendingLine(uiState.pendingCount)}",
style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep),
)
BackgroundChip()
}
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
uiState.battery?.let { BatteryChip(it) }
TodayCounterPill(done = uiState.doneCount, total = uiState.totalCount)
}
} }
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxSize(), modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp),
) { ) {
items(count = uiState.habits.size, key = { uiState.habits[it].id }) { index -> items(count = uiState.habits.size, key = { uiState.habits[it].id }) { index ->
@@ -143,13 +146,6 @@ private fun CenterColumn(
} }
} }
@Composable
private fun pendingLine(pending: Int): String = when (pending) {
0 -> stringResource(R.string.dashboard_pending_zero)
1 -> stringResource(R.string.dashboard_pending_one)
else -> stringResource(R.string.dashboard_pending_many, pending)
}
@Composable @Composable
private fun BackgroundChip() { private fun BackgroundChip() {
Row( Row(
@@ -96,7 +96,11 @@ private fun StreakCard(streak: Int, week: List<WeekDayUi>, securedToday: Boolean
style = MaterialTheme.typography.displaySmall.copy(color = CoralIntense), style = MaterialTheme.typography.displaySmall.copy(color = CoralIntense),
) )
Text( Text(
text = stringResource(R.string.dashboard_streak_days), text = if (streak == 1) {
stringResource(R.string.dashboard_streak_day_singular)
} else {
stringResource(R.string.dashboard_streak_days)
},
style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep), style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep),
) )
WeekRow(week = week) WeekRow(week = week)
@@ -151,7 +151,11 @@ private fun StreakRow(streak: Int) {
) { ) {
StreakFlame(modifier = Modifier.size(26.dp, 32.dp)) StreakFlame(modifier = Modifier.size(26.dp, 32.dp))
Text( Text(
text = stringResource(R.string.dashboard_streak_sidebar, streak), text = if (streak == 1) {
stringResource(R.string.dashboard_streak_sidebar_singular)
} else {
stringResource(R.string.dashboard_streak_sidebar, streak)
},
style = MaterialTheme.typography.labelLarge.copy(color = CoralIntense), style = MaterialTheme.typography.labelLarge.copy(color = CoralIntense),
) )
} }
+2
View File
@@ -33,7 +33,9 @@
<string name="dashboard_done_badge">¡Hecho!</string> <string name="dashboard_done_badge">¡Hecho!</string>
<string name="dashboard_streak_title">Tu racha</string> <string name="dashboard_streak_title">Tu racha</string>
<string name="dashboard_streak_days">días</string> <string name="dashboard_streak_days">días</string>
<string name="dashboard_streak_day_singular">día</string>
<string name="dashboard_streak_sidebar">%1$d días de racha</string> <string name="dashboard_streak_sidebar">%1$d días de racha</string>
<string name="dashboard_streak_sidebar_singular">1 día de racha</string>
<string name="dashboard_streak_secured">¡Racha asegurada hoy! 🔥</string> <string name="dashboard_streak_secured">¡Racha asegurada hoy! 🔥</string>
<string name="dashboard_level_badge">Nv. %1$d</string> <string name="dashboard_level_badge">Nv. %1$d</string>
<string name="dashboard_level_title">Nivel %1$d</string> <string name="dashboard_level_title">Nivel %1$d</string>