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:
@@ -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.
|
||||||
Row(
|
// On the EMUI test device the previous Bottom-aligned SpaceBetween header
|
||||||
modifier = Modifier.fillMaxWidth(),
|
// measured ~270 dp tall (giant invisible text box), crushing the habit list
|
||||||
verticalAlignment = Alignment.Bottom,
|
// to zero height — see STATUS.md session 2.
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
val pendingText = when (uiState.pendingCount) {
|
||||||
) {
|
0 -> stringResource(R.string.dashboard_pending_zero)
|
||||||
Column {
|
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(
|
||||||
text = stringResource(R.string.dashboard_greeting, uiState.childName),
|
text = stringResource(R.string.dashboard_greeting, uiState.childName),
|
||||||
style = MaterialTheme.typography.headlineMedium,
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
|
maxLines = 1,
|
||||||
)
|
)
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
|
||||||
) {
|
|
||||||
Text(
|
Text(
|
||||||
text = "${uiState.dateLine} · ${pendingLine(uiState.pendingCount)}",
|
text = "${uiState.dateLine} · $pendingText",
|
||||||
style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep),
|
style = MaterialTheme.typography.bodyMedium.copy(color = WarmGreyDeep),
|
||||||
|
maxLines = 2,
|
||||||
)
|
)
|
||||||
BackgroundChip()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Row(
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
) {
|
) {
|
||||||
|
BackgroundChip()
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
uiState.battery?.let { BatteryChip(it) }
|
uiState.battery?.let { BatteryChip(it) }
|
||||||
TodayCounterPill(done = uiState.doneCount, total = uiState.totalCount)
|
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),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user