feat(ui): design token discipline, accessibility and i18n pass
- Replace all hardcoded Color literals outside lib/tema with theme tokens (new static brand palette in PluriWaveTokens); media notification uses the brand color instead of the Material default purple - Favorite button on station cards grows to a 48dp target and becomes an independent semantics node for screen readers (Semantics container fix) - All flutter_animate call sites route through the PluriAnimate reduced-motion gate (zero direct .animate() left) - Locale-aware short dates via intl DateFormat (new lib/l10n/formato_fechas.dart) replacing the hardcoded DD/MM/YYYY; proper plural messages for the favorites counter; example stream URL as a localized key - all 13 locales - Rounded shimmer placeholders matching card radii; shimmer loading state in search instead of a bare spinner; rounded icon variants unified in settings; bottom-sheet conventions on the custom station form - Fix latent debug crash: vacation editor read AppLocalizations in initState - 11 new tests (121 total green), flutter analyze clean
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
**Mode**: Strict TDD (test runner: `flutter test`)
|
||||
**Artifact store**: openspec (Engram unavailable this session)
|
||||
**Delivery**: auto-chain, local apply — no commits, no PRs (user commits at own cadence)
|
||||
**Last updated**: 2026-06-11 (Batch 6)
|
||||
**Last updated**: 2026-06-11 (Batch 7)
|
||||
|
||||
## Batch log
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
| 4 | S7 — Streaming resilience (buffer config, reconnect state machine, UI wiring) | COMPLETE (Dart-only batch; stream-drop on-device verification deferred to user) | 2026-06-11 |
|
||||
| 5 | S4a — ServicioExportImport + EstadoEcualizador extraction + compat getters | COMPLETE (Dart-only batch) | 2026-06-11 |
|
||||
| 6 | S4b — EstadoGrabacion + EstadoBusqueda + scoped rebuilds + compat-getter removal | COMPLETE (Dart-only batch) | 2026-06-11 |
|
||||
| 7 | S5 — Design system, a11y, i18n, polish | COMPLETE (Dart-only batch) | 2026-06-11 |
|
||||
|
||||
## Task status (cumulative)
|
||||
|
||||
@@ -165,9 +166,32 @@
|
||||
| T-S4b-12 | [x] | `flutter analyze` — No issues found |
|
||||
| T-S4b-13 | [x] | `dart format` on 15 touched files (10 reflowed); analyze + suite re-run after |
|
||||
|
||||
### Slice S5 — Design system, a11y, i18n — 18/18 complete
|
||||
|
||||
| Task | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| T-S5-01 | [x] | RED: `tarjeta_emisora_a11y_test.dart` — semantics label/button/toggled + ≥48dp. RED exposed a REAL bug: the card InkWell merged the favorite into ONE semantics node (screen readers could not reach the action independently) |
|
||||
| T-S5-02 | [x] | RED: `pluri_animate_test.dart` — fadeIn/scaleIn lock-in + NEW `pluriFadeSlideIn` (honest RED: method missing) |
|
||||
| T-S5-03 | [x] | RED: `pantalla_alarmas_fecha_test.dart` — en-US `6/11/2026`, NOT `11/06/2026`; es day/month |
|
||||
| T-S5-04 | [x] | RED: `pantalla_favoritos_plural_test.dart` — `stationCount` singular ≠ plural (en, es) |
|
||||
| T-S5-05 | [x] | RED: `pantalla_buscar_shimmer_test.dart` — shimmer during loading, NO spinner (cargando-true EstadoBusqueda subclass seam) |
|
||||
| T-S5-06 | [x] | RED: `notification_color_test.dart` — `configuracionAudioService.notificationColor == PluriWaveTokens.brand` |
|
||||
| T-S5-07 | [x] | GREEN: zero `Color(0x...)` outside lib/tema (rg audit). New static tokens `brand`/`brightCyan`/`auroraTeal`/`skyBlue`; scaffold gradient/orbs, alarmas glows, visualizer stop, premium orbs, tarjeta sweep mapped; Colors.grey/green/white semantic uses → colorScheme/tokens |
|
||||
| T-S5-08 | [x] | GREEN: favorite `Semantics(container: true, ...)` + 48×48 in both variants; `_AssetIcon.semanticLabel` (+`excludeFromSemantics` when decorative); alarm/vacation/ringing images labelled via NEW `alarmIconLabel`/`vacationIconLabel` |
|
||||
| T-S5-09 | [x] | GREEN: `pluriFadeSlideIn` added; ALL `flutter_animate` call sites routed through PluriAnimate (inicio chips/grid, buscar results, reproductor ×8); zero direct `.animate()` in lib/ |
|
||||
| T-S5-10 | [x] | GREEN: NEW `lib/l10n/formato_fechas.dart` (`fechaCortaLocalizada`); `_fechaCorta(l10n, fecha)` delegates via `l10n.localeName` (6 call sites) |
|
||||
| T-S5-11 | [x] | GREEN: `stationCount` ICU plural in ALL 13 locales (ru/ar full category sets); NEW `streamUrlHint` replaces hardcoded `stream.ejemplo.com`; gen-l10n run |
|
||||
| T-S5-12 | [x] | GREEN: shimmer rounded (radiusLg/6) + NEW `esCompacta` row variant; PantallaBuscar loading → 4 compact shimmer rows |
|
||||
| T-S5-13 | [x] | GREEN: 9 ajustes icons → `_rounded`; `*_outlined` family left (no rounded-outline variant exists); `_FormularioEmisora` sheet → `useSafeArea` + `showDragHandle` |
|
||||
| T-S5-14 | [x] | GREEN: `configuracionAudioService` top-level const; `notificationColor: PluriWaveTokens.brand` |
|
||||
| T-S5-15 | [x] | Targeted run 11/11 green (RED first: `+0 -6`) |
|
||||
| T-S5-16 | [x] | Full suite 121/121 (110 baseline + 11 new) |
|
||||
| T-S5-17 | [x] | `flutter analyze` — No issues found; color-literal audit ZERO |
|
||||
| T-S5-18 | [x] | `dart format` on 20 touched Dart files (7 reflowed); analyze + suite re-run after |
|
||||
|
||||
### Remaining slices (not started)
|
||||
|
||||
S5, S6, cross-cutting (T-CC-01, T-CC-02) — all pending.
|
||||
S6, cross-cutting (T-CC-01, T-CC-02) — pending. S6 is now UNBLOCKED (depends on S4b + S5, both complete).
|
||||
|
||||
## Snooze defect fixes (design audit D1–D5 / S1–S5)
|
||||
|
||||
@@ -236,6 +260,61 @@ RED run evidence (Batch 5): `00:00 +0 -2` (both files fail to load — captured
|
||||
|
||||
RED run evidence (Batch 6): `00:00 +0 -3` (all three files fail to load — captured before any lib code). GREEN: targeted 8/8; full suite `00:11 +110: All tests passed!` (103 baseline − 1 moved + 8 new); analyze + suite re-run after format.
|
||||
|
||||
### Batch 7 TDD Cycle Evidence (S5)
|
||||
|
||||
| Task | RED (test written first, failing) | GREEN (implementation passes) | REFACTOR |
|
||||
|------|-----------------------------------|-------------------------------|----------|
|
||||
| T-S5-01/T-S5-08 | `find.bySemanticsLabel` found 0 nodes — the card InkWell MERGED the favorite into one node (real a11y defect, probed with a semantics dump) | `Semantics(container: true)` + 48dp target; node found, button/toggled flags pass | `hasFlag` (deprecated) → `flagsCollection` + `Tristate`; explicit `semantics.dispose()` (addTearDown fires too late for the handle check) |
|
||||
| T-S5-02/T-S5-09 | Compile failure: `pluriFadeSlideIn` undefined | Helper added; 4/4 animate tests green | — |
|
||||
| T-S5-03/T-S5-10 | Load failure: `formato_fechas.dart` missing | `fechaCortaLocalizada` + delegation; en-US/es tests pass | — |
|
||||
| T-S5-04/T-S5-11 | Compile failure: `stationCount` missing from AppLocalizations | ARB plural ×13 + gen-l10n; both locale tests pass | — |
|
||||
| T-S5-05/T-S5-12 | `TarjetaEmisoraShimmer` found 0, spinner found 1 | Compact shimmer variant + buscar loading swap | Shimmer block builder extracted (`bloque`) shared by both variants |
|
||||
| T-S5-06/T-S5-14 | Compile failure: `configuracionAudioService`/`PluriWaveTokens.brand` undefined | Const extraction + brand token; test passes | `electricMagenta` re-pointed at `brand` (no duplicate literal) |
|
||||
|
||||
RED run evidence (Batch 7): `00:02 +0 -6` (4 compile/load failures + 2 honest assertion failures) captured before any lib code. GREEN: targeted 11/11; full suite `00:14 +121: All tests passed!`; analyze + suite re-run after `dart format`.
|
||||
|
||||
## Files changed (Batch 7)
|
||||
|
||||
| File | Action | ~Lines |
|
||||
|------|--------|--------|
|
||||
| `lib/tema/pluriwave_tokens.dart` | Modified | +12 (static `brand`/`brightCyan`/`auroraTeal`/`skyBlue` token definitions; format reflow) |
|
||||
| `lib/tema/pluri_animate.dart` | Modified | +14 (`pluriFadeSlideIn`) |
|
||||
| `lib/l10n/formato_fechas.dart` | Created | +14 (locale-aware short date) |
|
||||
| `lib/main.dart` | Modified | +13/-8 (`configuracionAudioService` const, brand notification color) |
|
||||
| `lib/widgets/pluri_wave_scaffold.dart` | Modified | +8/-8 (gradient + orbs → tokens/colorScheme) |
|
||||
| `lib/widgets/tarjeta_emisora.dart` | Modified | +60/-30 (brightCyan, favorite container semantics + 48dp, rounded shimmer + compact variant) |
|
||||
| `lib/widgets/visualizador_audio.dart` | Modified | +2/-1 (warmCoral token) |
|
||||
| `lib/widgets/pluri_premium_widgets.dart` | Modified | +3/-2 (brightCyan) |
|
||||
| `lib/pantallas/pantalla_alarmas.dart` | Modified | +55/-30 (glow tokens, `_AssetIcon` semanticLabel, locale-aware `_fechaCorta`, vacaciones initState l10n fix) |
|
||||
| `lib/pantallas/pantalla_favoritos.dart` | Modified | +2/-1 (plural counter) |
|
||||
| `lib/pantallas/pantalla_buscar.dart` | Modified | +18/-7 (shimmer loading, pluriFadeSlideIn) |
|
||||
| `lib/pantallas/pantalla_ajustes.dart` | Modified | +20/-12 (rounded icons, semantic colors, l10n hint, sheet conventions) |
|
||||
| `lib/pantallas/pantalla_reproductor.dart` | Modified | +25/-20 (PluriAnimate routing ×8, white overlays → colorScheme/tokens) |
|
||||
| `lib/pantallas/pantalla_inicio.dart` | Modified | +6/-3 (PluriAnimate routing) |
|
||||
| `lib/l10n/app_*.arb` (13 files) | Modified | +4-5 each (`stationCount` plural, `alarmIconLabel`, `vacationIconLabel`, `streamUrlHint`) |
|
||||
| `lib/l10n/gen/*` (14 files) | Regenerated | by `flutter gen-l10n` |
|
||||
| `test/widgets/tarjeta_emisora_a11y_test.dart` | Created | +72 (1 test) |
|
||||
| `test/tema/pluri_animate_test.dart` | Created | +80 (4 tests) |
|
||||
| `test/tema/notification_color_test.dart` | Created | +17 (1 test) |
|
||||
| `test/pantallas/pantalla_alarmas_fecha_test.dart` | Created | +29 (2 tests) |
|
||||
| `test/pantallas/pantalla_favoritos_plural_test.dart` | Created | +21 (2 tests) |
|
||||
| `test/pantallas/pantalla_buscar_shimmer_test.dart` | Created | +42 (1 test) |
|
||||
|
||||
Total Batch 7 lib diff: ~240 insertions / ~120 deletions (incl. ARB, excl. gen/), plus ~260 lines of new tests. Within the ~210-line slice estimate for hand-written lib changes. No Kotlin/native files touched.
|
||||
|
||||
## Deviations from design (Batch 7)
|
||||
|
||||
1. **`Semantics(container: true)` on the favorite button (not in task text).** The task only asked for `Semantics(button, label)` — which ALREADY existed. The RED test proved the real defect: the card-level InkWell merged the favorite into a single semantics node, so screen readers could not reach the action. `container: true` forces an own node; this is the actual S5-R2 fix.
|
||||
2. **`fechaCortaLocalizada` lives in NEW `lib/l10n/formato_fechas.dart`** (task said edit `_fechaCorta` in place). The private top-level function is untestable from `flutter test`; the public helper takes a locale tag (testable without widgets) and `_fechaCorta(l10n, fecha)` delegates via `l10n.localeName`. Spec scenario S5-R4-A is met verbatim.
|
||||
3. **Brand token is `PluriWaveTokens.brand`, not `brandColor`** (task text guessed the name). Defined as a `static const` so it works in the `const AudioServiceConfig` context; `electricMagenta` now references it (single source for 0xFF21D4D9). `brightCyan`/`auroraTeal`/`skyBlue` added the same way for palette colors that had no token.
|
||||
4. **`Colors.white` overlays mapped to `colorScheme.onSurface`/`onPrimary` and `tokens.glassBorder`** — the scheme's `onSurface` is 0xFFF2F7FA (near-white), so visuals are intentionally near-identical while becoming theme-driven.
|
||||
5. **`pluriScaleIn` on the hero adds a fade** the old bare `.scale()` did not have (the shared helper pairs fade+scale). Visually negligible at 420 ms; keeping one canonical scale-entry beats a third helper.
|
||||
6. **Icon variants: only base-name icons got `_rounded`** (9 sites). The `*_outlined` Material family (folder_outlined, backup_outlined, upload/download_outlined, verified_outlined, music_note_outlined) has NO rounded-outline variant; switching them to filled `_rounded` would change their visual weight, so they stay outlined.
|
||||
7. **`streamUrlHint` added as an l10n key** (the prompt's "handled per design"): the hardcoded hint leaked a Spanish-looking host (`stream.ejemplo.com`) into all 13 locales; the key ships the same neutral `stream.example.com` URL everywhere but is now localizable.
|
||||
8. **`_EditorVacacionesSheet` initState l10n crash fixed** (flagged in Batch 2 as a latent debug-mode crash, explicitly brought into this batch's scope): controller now created lazily in `didChangeDependencies`, mirroring the alarm-editor fix.
|
||||
9. **Pagination spinner in PantallaBuscar kept** — S5-R6 covers the initial loading state (explore C11, lines 241-245); the small inline load-more spinner is a different affordance and was left untouched.
|
||||
10. **`flagsCollection`/`Tristate` instead of `SemanticsFlag.hasFlag`** in the a11y test — `hasFlag` is deprecated in the current SDK and `flutter analyze` flags it; also `tester.ensureSemantics()` must be disposed in the test body (an `addTearDown` runs after the framework's handle-leak check).
|
||||
|
||||
## Files changed (Batch 2)
|
||||
|
||||
| File | Action | ~Lines |
|
||||
@@ -495,9 +574,28 @@ From tasks.md Section 11 — S1 items still pending from Batch 1, plus new S2 it
|
||||
4. **Scoped rebuilds (S4-R5):** while audio plays/buffers, home/favorites/settings should feel identical (no visual change expected — the win is fewer rebuilds); list reordering in Ajustes still re-sorts home, search results and favorites.
|
||||
5. **Stop recording on pause/stop/station switch:** unchanged orchestration in EstadoRadio — verify recording stops when playback pauses/stops or station changes.
|
||||
|
||||
## Verification summary (Batch 7)
|
||||
|
||||
- `flutter test`: 121/121 passing (110 baseline + 11 new across 6 files); re-run after `dart format`
|
||||
- `flutter analyze`: No issues found (identical to baseline); re-run after format
|
||||
- `dart format`: applied to all 20 touched Dart files (7 reflowed); gen/ untouched by hand
|
||||
- `flutter gen-l10n`: run once after the 13 .arb edits
|
||||
- Color-literal audit: `rg 'Color(0x' lib` excluding `lib/tema/` and `lib/l10n/gen/` → **0 matches** (was 14)
|
||||
- `rg '.animate()' lib` → 0 direct flutter_animate call sites (all via PluriAnimate)
|
||||
- `flutter build`: NOT run (forbidden)
|
||||
- No Kotlin/native files touched in this batch
|
||||
|
||||
### Manual verification items added by Batch 7 (user)
|
||||
|
||||
1. **Visual parity sweep (S5-R1):** home/buscar/favoritos/ajustes/alarmas/reproductor look unchanged — token mapping was value-preserving (onSurface ≈ white; electricMagenta = brand). The settings "check" icons are now mint (`colorScheme.secondary`) instead of Material green — intentional.
|
||||
2. **TalkBack (S5-R2):** on a station card, the favorite toggle is now reachable as its OWN button ("Añadir a favoritos / Quitar de favoritos") separate from the card; alarm/vacation images announce their labels.
|
||||
3. **Reduced motion (S5-R3):** with "remove animations" enabled, home grid/search results/player screens render instantly with no entry animations.
|
||||
4. **Locale dates (S5-R4):** switch app language to English → alarm editor and vacation ranges show M/D/Y order; Japanese shows Y/M/D.
|
||||
5. **Media notification (S5-R8):** the playback notification accent is teal (brand), not purple, on devices that honor `notificationColor`.
|
||||
|
||||
## Workload / boundary
|
||||
|
||||
- Mode: auto-chain local slices (no PRs)
|
||||
- Current work units: S1, S2a, S2b, S3a, S3b, S7, S4a (committed, latest 0416b30), S4b (complete, in working tree)
|
||||
- Boundary (Batch 6): starts from the clean post-0416b30 tree; ends with S4b fully checked off, suite green (110/110). Rollback = revert the 9 modified lib/test files + delete the 6 new files (Dart-only; no native edits).
|
||||
- Next batch: S5 (design system / a11y / i18n — unblocked since S2b) then S6 (quality gates — now unblocked: depends on S4b + S5).
|
||||
- Current work units: S1, S2a, S2b, S3a, S3b, S7, S4a, S4b (committed, latest 52855e7), S5 (complete, in working tree)
|
||||
- Boundary (Batch 7): starts from the clean post-52855e7 tree; ends with S5 fully checked off, suite green (121/121). Rollback = revert the 27 modified lib files (incl. 13 ARB + gen/) + delete the 7 new files (Dart-only; no native edits).
|
||||
- Next batch: S6 (quality gates — lint hardening + remaining top-5 tests) then cross-cutting T-CC-01/T-CC-02. S6 is the LAST slice.
|
||||
|
||||
@@ -363,30 +363,30 @@ Chain strategy: N/A (local apply)
|
||||
|
||||
### S5 pre-work: write failing tests
|
||||
|
||||
- [ ] **T-S5-01** [RED] Create `test/widgets/tarjeta_emisora_a11y_test.dart`: favorite `InkWell` has semantic label + `button:true`; size ≥ 48×48 dp (S5-R2-A). **~20 lines.**
|
||||
- [ ] **T-S5-02** [RED] Add test in `test/tema/pluri_animate_test.dart`: `pluriFadeIn` returns unanimated child when `disableAnimations=true` (S5-R3-A). **~15 lines.**
|
||||
- [ ] **T-S5-03** [RED] Create `test/pantallas/pantalla_alarmas_fecha_test.dart`: `_fechaCorta` with locale `en-US` returns `DateFormat.yMd('en-US')` result, NOT `11/06/2026` (S5-R4-A). **~15 lines.**
|
||||
- [ ] **T-S5-04** [RED] Add test `test/pantallas/pantalla_favoritos_plural_test.dart`: plural form changes between 1 and 5 station count strings (S5-R5). **~10 lines.**
|
||||
- [ ] **T-S5-05** [RED] Add widget test: shimmer present during loading state in `PantallaBuscar` (S5-R6). **~10 lines.**
|
||||
- [ ] **T-S5-06** [RED] Add unit test: `AudioServiceConfig.notificationColor` equals brand color token (S5-R8). **~10 lines.**
|
||||
- [x] **T-S5-01** [RED] Create `test/widgets/tarjeta_emisora_a11y_test.dart`: favorite `InkWell` has semantic label + `button:true`; size ≥ 48×48 dp (S5-R2-A). **DONE — RED exposed a REAL merge bug: the card InkWell absorbed the favorite into one semantics node; fixed with `Semantics(container: true)`. Toggled state asserted via `flagsCollection` (Tristate API; `hasFlag` is deprecated).**
|
||||
- [x] **T-S5-02** [RED] `test/tema/pluri_animate_test.dart`: `pluriFadeIn`/`pluriScaleIn` lock-in (already implemented in S2b) + NEW `pluriFadeSlideIn` (honest RED: method missing). 4 tests. **DONE.**
|
||||
- [x] **T-S5-03** [RED] `test/pantallas/pantalla_alarmas_fecha_test.dart`: en-US returns `6/11/2026` (NOT `11/06/2026`) + es day/month order. Tests the NEW public helper `fechaCortaLocalizada` (private `_fechaCorta` is untestable; see deviation). **DONE.**
|
||||
- [x] **T-S5-04** [RED] `test/pantallas/pantalla_favoritos_plural_test.dart`: `stationCount(1)` differs from `stationCount(5)` in en and es. **DONE.**
|
||||
- [x] **T-S5-05** [RED] `test/pantallas/pantalla_buscar_shimmer_test.dart`: loading shows `TarjetaEmisoraShimmer`, NO `CircularProgressIndicator` (cargando-true EstadoBusqueda subclass seam). **DONE.**
|
||||
- [x] **T-S5-06** [RED] `test/tema/notification_color_test.dart`: `configuracionAudioService.notificationColor == PluriWaveTokens.brand` (config extracted to a testable top-level const). **DONE.**
|
||||
|
||||
### S5 implementation
|
||||
|
||||
- [ ] **T-S5-07** [GREEN] Edit all 14+ remaining `Color(0x...)` literal sites identified in explore C3 (files: `lib/pantallas/`, `lib/widgets/`, excluding `pantalla_alarma_sonando.dart` done in S2b): replace with `PluriWaveTokens` or `Theme.of(context).colorScheme` references. **Reqs:** S5-R1. **~30 lines across files.**
|
||||
- [ ] **T-S5-08** [GREEN] Edit `lib/widgets/tarjeta_emisora.dart` (lines 238-289): wrap mini favorite `InkWell` in `Semantics(button: true, label: l10n.toggleFavorite)`; set `constraints: BoxConstraints(minWidth: 48, minHeight: 48)`. Add `semanticLabel` to `_AssetIcon`/alarm PNG. **Reqs:** S5-R2. **~15 lines.**
|
||||
- [ ] **T-S5-09** [GREEN] `lib/tema/pluri_animate.dart` already created in S2b (T-S2b-04). Verify tests pass (no new code needed here unless edge case found).
|
||||
- [ ] **T-S5-10** [GREEN] Edit `lib/pantallas/pantalla_alarmas.dart` `_fechaCorta` (line 1114): replace hardcoded format string with `intl.DateFormat.yMd(Localizations.localeOf(context).toLanguageTag()).format(date)`. **Reqs:** S5-R4. **~5 lines.**
|
||||
- [ ] **T-S5-11** [GREEN] Edit `lib/pantallas/pantalla_favoritos.dart` (line 138): replace bare counter string with ARB plural form using `AppLocalizations` `stationCount(n)` plural message. Add the ARB plural entry to `lib/l10n/*.arb` files for all supported locales. **Reqs:** S5-R5. **~20 lines (Dart) + ARB entries.**
|
||||
- [ ] **T-S5-12** [GREEN] Edit `lib/widgets/tarjeta_emisora.dart` shimmer placeholders (lines 389-420): apply `BorderRadius` matching card corners. Edit `lib/pantallas/pantalla_buscar.dart` (lines 241-245): replace spinner with shimmer during loading state. **Reqs:** S5-R6. **~20 lines.**
|
||||
- [ ] **T-S5-13** [GREEN] Edit `lib/pantallas/pantalla_ajustes.dart` icon sites (lines 985, 1028, 1031): replace non-`_rounded` icon variants with their `_rounded` equivalents. **Reqs:** S5-R7. **~5 lines.**
|
||||
- [ ] **T-S5-14** [GREEN] Edit `lib/main.dart` (line 23) `AudioServiceConfig`: set `notificationColor` to `PluriWaveTokens.brandColor` (or equivalent token). **Reqs:** S5-R8. **~3 lines.**
|
||||
- [x] **T-S5-07** [GREEN] ALL `Color(0x...)` literals outside `lib/tema/` removed (rg audit = 0 matches). New token DEFINITIONS in `PluriWaveTokens`: static `brand` (0xFF21D4D9, now referenced by `electricMagenta`), `brightCyan`, `auroraTeal`, `skyBlue`. Mapped: scaffold gradient → deepViolet/colorScheme.surface/auroraTeal; orbs → electricMagenta + colorScheme.secondary; alarmas glows → warmCoral/electricMagenta/skyBlue; visualizer gradient stop → warmCoral; premium orbs + tarjeta sweep → brightCyan. ALSO `Colors.grey` → onSurface(0.6), `Colors.green` → colorScheme.secondary, `Colors.white` overlays in reproductor → onSurface/onPrimary/glassBorder. **Reqs:** S5-R1. **DONE.**
|
||||
- [x] **T-S5-08** [GREEN] Favorite button: `Semantics(container: true, button, toggled, label)` (container REQUIRED — see T-S5-01) + 48×48 target in both variants. `_AssetIcon` gained `semanticLabel` (decorative images get `excludeFromSemantics: true`); labels on alarm/vacation images + ringing-screen image via NEW keys `alarmIconLabel`/`vacationIconLabel`. **Reqs:** S5-R2. **DONE.**
|
||||
- [x] **T-S5-09** [GREEN] `pluri_animate.dart` extended with `pluriFadeSlideIn`; ALL remaining `flutter_animate` call sites routed through PluriAnimate (pantalla_inicio chips + grid stagger, pantalla_buscar results, pantalla_reproductor 8 sites). Zero direct `.animate()` left in lib/. **Reqs:** S5-R3. **DONE.**
|
||||
- [x] **T-S5-10** [GREEN] NEW `lib/l10n/formato_fechas.dart` → `fechaCortaLocalizada(localeTag, fecha)`; `_fechaCorta(l10n, fecha)` delegates with `l10n.localeName` (all 6 call sites updated). **Reqs:** S5-R4. **DONE.**
|
||||
- [x] **T-S5-11** [GREEN] Group counter → `l10n.stationCount(n)` ICU plural in ALL 13 locales (ru one/few/other, ar one/two/few/other, ja/zh/id other-only). Also NEW `streamUrlHint` key replacing the hardcoded `stream.ejemplo.com` hint. `flutter gen-l10n` regenerated. **Reqs:** S5-R5. **DONE.**
|
||||
- [x] **T-S5-12** [GREEN] `TarjetaEmisoraShimmer` rounded (radiusLg image block, radius-6 text lines) + NEW `esCompacta` variant mirroring the search row layout; `PantallaBuscar` loading → 4 compact shimmer rows (pagination spinner untouched, out of S5-R6 scope). **Reqs:** S5-R6. **DONE.**
|
||||
- [x] **T-S5-13** [GREEN] 9 icon sites → `_rounded` variants (radio_button_checked, equalizer, add_circle_outline, add, radio, play_arrow, delete_outline, favorite_outline, check_circle). `*_outlined`-family icons left as-is (no rounded-outline variant exists in Material). ALSO `_FormularioEmisora` sheet gained `useSafeArea`/`showDragHandle`. **Reqs:** S5-R7. **DONE.**
|
||||
- [x] **T-S5-14** [GREEN] Config extracted to top-level `configuracionAudioService` const; `notificationColor: PluriWaveTokens.brand` (static const → usable in const context). **Reqs:** S5-R8. **DONE.**
|
||||
|
||||
### S5 verification
|
||||
|
||||
- [ ] **T-S5-15** Run `flutter test test/widgets/tarjeta_emisora_a11y_test.dart test/tema/pluri_animate_test.dart test/pantallas/pantalla_alarmas_fecha_test.dart test/pantallas/pantalla_favoritos_plural_test.dart`.
|
||||
- [ ] **T-S5-16** Run `flutter test` (full suite) — no regressions.
|
||||
- [ ] **T-S5-17** Run `flutter analyze` — zero errors (no `Color(0x...)` in modified files beyond token definitions).
|
||||
- [ ] **T-S5-18** Run `dart format` on all edited files.
|
||||
- [x] **T-S5-15** Targeted run (6 files, 11 tests) — all green (RED captured first: `+0 -6`).
|
||||
- [x] **T-S5-16** Full suite 121/121 (110 baseline + 11 new), no regressions.
|
||||
- [x] **T-S5-17** `flutter analyze` — `No issues found!`; `rg 'Color(0x' lib` outside lib/tema + l10n/gen → ZERO matches.
|
||||
- [x] **T-S5-18** `dart format` on all 20 touched Dart files (7 reflowed); analyze + suite re-run after format.
|
||||
|
||||
### S5 Definition of Done
|
||||
- `flutter test` green.
|
||||
|
||||
Reference in New Issue
Block a user