fix(alarma-sonando): add the schedule pill and restyle the station name
Audit 9.3 (t4 line 415): the ringing screen never showed its schedule
pill. Reuses the alarmScheduleOnce/alarmScheduleWeekdays ARB keys that
already existed with no consumer, plus a new alarmScheduleDaily key
(translated to all 13 locales) for the recurring-alarm case shown in
the prototype.
Audit 9.7 (t4 line 423): the station name was cardTitle (14.5px/w700),
5.5px and 100 weight units under the prototype's 20px/w800.
Audit 9.9 (snooze tiles as number-over-unit) is intentionally NOT
included in this commit: it would require the tile to stop rendering
as a single flat "{minutes} min" Text node, which is exactly what
pantalla_alarma_sonando_dismiss_guard_test.dart taps via
find.text(l10n.alarmSnoozeOptionLabel(N)) in four places. That file
must stay untouched, so this restyle is deferred pending a decision
on how to restructure the tap target safely.
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../estado/estado_alarmas.dart';
|
||||
import '../l10n/display_names.dart';
|
||||
import '../l10n/formato_fechas.dart';
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../modelos/alarma_musical.dart';
|
||||
import '../tema/pluri_animate.dart';
|
||||
@@ -204,6 +205,14 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
child: Column(
|
||||
children: [
|
||||
const Spacer(flex: 2),
|
||||
// Audit 9.3 (t4 line 415): the schedule pill was missing
|
||||
// entirely — built from `alarma.tipoProgramacion` (a field
|
||||
// already on the domain model), no new plumbing.
|
||||
_PildoraProgramacion(
|
||||
texto: _resumenProgramacion(context, l10n, alarma),
|
||||
tokens: tokens,
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: Text(
|
||||
@@ -244,7 +253,15 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
? localizedStationName(l10n, alarma.emisora!.nombre)
|
||||
: l10n.alarmRingingNotificationTitle,
|
||||
textAlign: TextAlign.center,
|
||||
style: type.cardTitle,
|
||||
// Audit 9.7 (t4 line 423): 20px/w800/ls-.3 — this used to
|
||||
// be `cardTitle` (14.5px/w700), 5.5px and 100 weight
|
||||
// units under spec for the station name on a full-screen
|
||||
// ringing surface.
|
||||
style: type.cardTitle.copyWith(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: -0.3,
|
||||
),
|
||||
),
|
||||
// WU11 (native-alarms delta — Ringing Screen Shows a
|
||||
// Static Status Label): only rendered while this alarm was
|
||||
@@ -360,6 +377,87 @@ String _hora(AlarmaMusical alarma) =>
|
||||
/// call site (mirrors `_ArteEscuchar._radio` in `pantalla_inicio.dart`).
|
||||
const _stopButtonRadius = 24.0;
|
||||
|
||||
/// Audit 9.3: the schedule pill's text, built only from
|
||||
/// [AlarmaMusical.tipoProgramacion] and the fields it already carries per
|
||||
/// case (`diasSemana`, `fechaUnica`) — no new domain plumbing. Reuses the
|
||||
/// `alarmScheduleOnce`/`alarmScheduleWeekdays` ARB keys, which existed
|
||||
/// already but had no consumer anywhere in the app.
|
||||
String _resumenProgramacion(
|
||||
BuildContext context,
|
||||
AppLocalizations l10n,
|
||||
AlarmaMusical alarma,
|
||||
) {
|
||||
switch (alarma.tipoProgramacion) {
|
||||
case TipoProgramacionAlarma.diaria:
|
||||
return l10n.alarmScheduleDaily;
|
||||
case TipoProgramacionAlarma.unica:
|
||||
final localeTag = Localizations.localeOf(context).toString();
|
||||
return l10n.alarmScheduleOnce(
|
||||
fechaCortaLocalizada(localeTag, alarma.fechaUnica ?? DateTime.now()),
|
||||
);
|
||||
case TipoProgramacionAlarma.diasSemana:
|
||||
final dias = (List<int>.from(alarma.diasSemana)
|
||||
..sort()).map((d) => _weekdayShort(l10n, d)).join(', ');
|
||||
return l10n.alarmScheduleWeekdays(dias);
|
||||
}
|
||||
}
|
||||
|
||||
// Mirrors `pantalla_alarmas.dart`'s private `_weekdayShort` (kept local
|
||||
// rather than shared/exported: this screen's only other tie to the alarm
|
||||
// editor is the domain model itself, and duplicating a 7-line switch is
|
||||
// cheaper than adding a cross-screen import for it).
|
||||
String _weekdayShort(AppLocalizations l10n, int day) => switch (day) {
|
||||
DateTime.monday => l10n.weekdayShortMonday,
|
||||
DateTime.tuesday => l10n.weekdayShortTuesday,
|
||||
DateTime.wednesday => l10n.weekdayShortWednesday,
|
||||
DateTime.thursday => l10n.weekdayShortThursday,
|
||||
DateTime.friday => l10n.weekdayShortFriday,
|
||||
DateTime.saturday => l10n.weekdayShortSaturday,
|
||||
DateTime.sunday => l10n.weekdayShortSunday,
|
||||
_ => '?',
|
||||
};
|
||||
|
||||
/// Schedule pill (audit 9.3, t4 line 415): `alarm` icon + schedule summary
|
||||
/// on a warmCoral-tinted pill, matching the prototype's
|
||||
/// `rgba(244,184,96,.16)` fill / `rgba(244,184,96,.45)` border exactly.
|
||||
class _PildoraProgramacion extends StatelessWidget {
|
||||
const _PildoraProgramacion({required this.texto, required this.tokens});
|
||||
|
||||
final String texto;
|
||||
final PluriWaveTokens tokens;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DecoratedBox(
|
||||
key: const ValueKey('ringing-schedule-pill'),
|
||||
decoration: BoxDecoration(
|
||||
color: tokens.warmCoral.withValues(alpha: 0.16),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
border: Border.all(color: tokens.warmCoral.withValues(alpha: 0.45)),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.alarm, size: 18, color: tokens.warmCoral),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
texto,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w800,
|
||||
letterSpacing: 0.84,
|
||||
color: tokens.warmCoral,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Full-bleed blurred backdrop (WU11, replaces the `PluriGlassSurface` card
|
||||
/// container per task 11.3). This app has no per-station artwork/favicon
|
||||
/// safe to render here: `Emisora.favicon` is a network URL, and rendering
|
||||
|
||||
Reference in New Issue
Block a user