fix(alarmas): show which days a weekday alarm actually fires on
The alarms list showed a generic "Días" label for a diasSemana alarm instead of its actual configured days. Render the real recurrence (e.g. "Lun, Mié, Vie") by reusing the SAME per-day abbreviation the editor's own day-picker circles already use -- no new formatting scheme, no new ARB keys for the days themselves. Also surface fade/volume/vacation-pause state on the card, each only when it is a genuinely useful deviation from the common case: a fade badge when fadeInSegundos > 0 (reusing the existing alarmFadeInLabel key), a volume percentage when it differs from the 85% default, and a vacation-paused badge when the alarm is both configured to pause and a vacation range is currently active (mirrors the exact predicate ServicioProgramacionAlarmas already uses). One compact line, not a badge per field. Fixes a text-collision regression in pantalla_alarmas_editor_test.dart: opening the editor for an alarm whose own day now renders on its card (e.g. "Lun") made a bare find.text(weekday) ambiguous against the editor's day-picker circle with the same label -- scoped that finder to the BottomSheet subtree.
This commit is contained in:
@@ -265,6 +265,26 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
? l10n.noStationUseInternalSound
|
||||
: localizedStationName(l10n, alarma.emisora!.nombre);
|
||||
|
||||
// Item 5: surfaces the genuinely useful fields that already exist on
|
||||
// the model, WITHOUT turning the row into clutter -- each is shown
|
||||
// only when it is a meaningful deviation from the common case.
|
||||
// Mirrors EXACTLY the pause predicate `impactoDeRango`/
|
||||
// `ServicioProgramacionAlarmas` already use
|
||||
// (`!sonarEnVacaciones` while `activa`), gated by whether a vacation
|
||||
// range is CURRENTLY active -- an alarm configured to pause but with
|
||||
// no active range right now is not actually paused by anything yet.
|
||||
final pausadaPorVacaciones =
|
||||
alarma.activa &&
|
||||
!alarma.sonarEnVacaciones &&
|
||||
estado.rangoVacacionesActivo() != null;
|
||||
final detalles = <String>[
|
||||
if (alarma.fadeInSegundos > 0)
|
||||
l10n.alarmFadeInLabel(alarma.fadeInSegundos),
|
||||
if ((alarma.volumen * 100).round() != 85)
|
||||
'${(alarma.volumen * 100).round()}%',
|
||||
if (pausadaPorVacaciones) l10n.alarmCardVacationPausedBadge,
|
||||
];
|
||||
|
||||
return Dismissible(
|
||||
key: ValueKey('tarjeta-alarma-${alarma.id}'),
|
||||
direction: DismissDirection.horizontal,
|
||||
@@ -309,14 +329,21 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
_recurrenciaCorta(l10n, alarma),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.5),
|
||||
// Item 5: real day list can run longer than the
|
||||
// old generic "Días" label -- Flexible+ellipsis
|
||||
// keeps a long selection from overflowing the
|
||||
// Row instead of clipping visibly.
|
||||
Flexible(
|
||||
child: Text(
|
||||
_recurrenciaCorta(l10n, alarma),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: Theme.of(context).colorScheme
|
||||
.onSurface
|
||||
.withValues(alpha: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -369,6 +396,25 @@ class _TarjetaAlarma extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
// Item 5: fade/volume/vacation-pause state, only
|
||||
// when each is a genuinely useful deviation from
|
||||
// the common case (see `detalles` above) -- a
|
||||
// single compact line, not a badge per field.
|
||||
if (detalles.isNotEmpty) ...[
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
detalles.join(' · '),
|
||||
key: ValueKey('tarjeta-alarma-detalles-${alarma.id}'),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.onSurface.withValues(alpha: 0.55),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -1668,16 +1714,39 @@ String _weekdayShort(AppLocalizations l10n, int day) => switch (day) {
|
||||
String _fechaCorta(AppLocalizations l10n, DateTime fecha) =>
|
||||
fechaCortaLocalizada(l10n.localeName, fecha);
|
||||
|
||||
/// Audit 7.4 (t4:339): a compact recurrence label next to the alarm card's
|
||||
/// giant time. Reuses the SAME generic labels the editor's own
|
||||
/// `TipoProgramacionAlarma` `SegmentedButton` already shows (`oneTimeOption`
|
||||
/// / `dailyOption` / `weekdaysOption`) rather than inventing a new, more
|
||||
/// specific ARB string -- honest given the space (12px, next to a 34px
|
||||
/// time) genuinely only fits a short word, not a full weekday list.
|
||||
/// Audit 7.4 (t4:339) / item 5: a compact recurrence label next to the
|
||||
/// alarm card's giant time. `diaria`/`unica` still show the SAME generic
|
||||
/// labels the editor's own `TipoProgramacionAlarma` `SegmentedButton`
|
||||
/// already uses (`dailyOption`/`oneTimeOption`) -- both are already fully
|
||||
/// specific (there is nothing more concrete to say than "every day"/"just
|
||||
/// once"). `diasSemana` now renders the alarm's ACTUAL configured days
|
||||
/// (e.g. "Lun, Mié, Vie") instead of the generic `weekdaysOption` ("Días"),
|
||||
/// reusing [_weekdayShort] (the SAME per-day abbreviation the editor's own
|
||||
/// day-picker circles already use) -- no new ARB keys, no second
|
||||
/// formatting scheme, and the resulting Text is wrapped in a
|
||||
/// `Flexible`+ellipsis at the call site so a long selection never
|
||||
/// overflows the row.
|
||||
String _recurrenciaCorta(AppLocalizations l10n, AlarmaMusical alarma) {
|
||||
return switch (alarma.tipoProgramacion) {
|
||||
TipoProgramacionAlarma.diaria => l10n.dailyOption,
|
||||
TipoProgramacionAlarma.diasSemana => l10n.weekdaysOption,
|
||||
TipoProgramacionAlarma.diasSemana => _diasSemanaCorto(
|
||||
l10n,
|
||||
alarma.diasSemana,
|
||||
),
|
||||
TipoProgramacionAlarma.unica => l10n.oneTimeOption,
|
||||
};
|
||||
}
|
||||
|
||||
/// The real, ordered day abbreviations for a `diasSemana` alarm (item 5),
|
||||
/// e.g. "Lun, Mié, Vie". [diasSemana] is re-sorted defensively (the editor
|
||||
/// always persists it sorted, but this does not rely on that). Falls back
|
||||
/// to the generic [AppLocalizations.weekdaysOption] label when
|
||||
/// [diasSemana] is empty -- the editor already blocks saving an empty
|
||||
/// selection in this mode, but a corrupt/legacy persisted record could
|
||||
/// still reach here, and showing nothing would be worse than the old
|
||||
/// generic label.
|
||||
String _diasSemanaCorto(AppLocalizations l10n, List<int> diasSemana) {
|
||||
if (diasSemana.isEmpty) return l10n.weekdaysOption;
|
||||
final ordenados = [...diasSemana]..sort();
|
||||
return ordenados.map((dia) => _weekdayShort(l10n, dia)).join(', ');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user