refactor(state): extract export/import service and equalizer state from EstadoRadio
- New ServicioExportImport owns the v2 backup envelope, pretty JSON encode and graceful decode; byte-compatible with existing exports, locked by a round-trip test - pantalla_ajustes delegates backup serialization to the service (inline jsonDecode/jsonEncode removed) - New EstadoEcualizador ChangeNotifier owns all EQ state and persistence (principal/current/per-station presets, active flag), exposed via its own provider so EQ changes no longer rebuild EstadoRadio consumers - EstadoRadio slims down ~210 lines and keeps 15 delegating compat members marked TODO(S4b) for the next slice to remove - Player EQ toggle rewired to the new provider to avoid going stale - 4 new tests (103 total green), flutter analyze clean
This commit is contained in:
@@ -294,28 +294,28 @@ Chain strategy: N/A (local apply)
|
||||
|
||||
### S4a pre-work: write failing tests
|
||||
|
||||
- [ ] **T-S4a-01** [RED] Create `test/servicios/servicio_export_import_test.dart`:
|
||||
- [x] **T-S4a-01** [RED] Create `test/servicios/servicio_export_import_test.dart`:
|
||||
- Test A: full round-trip (favorites, groups, EQ, alarms, vacations) — serialize then deserialize produces deep-equal config. (S4-R4-A, S6-R2 test #4)
|
||||
- Test B: malformed JSON input to `importar()` → graceful empty result, no throw. (S4-R4)
|
||||
**~40 lines.**
|
||||
- [ ] **T-S4a-02** [RED] Create `test/estado/estado_ecualizador_test.dart`:
|
||||
**DONE — round-trip also locks alarmas raw passthrough + "sin asignar" group never exported; malformed cases: invalid JSON, empty string, non-object JSON.**
|
||||
- [x] **T-S4a-02** [RED] Create `test/estado/estado_ecualizador_test.dart`:
|
||||
- Test A: `aplicarPreset` notifies `EstadoEcualizador` listeners. (S4-R1-A)
|
||||
- Test B: `EstadoRadio` listeners are NOT rebuilt on EQ preset change. (S4-R1-A, S4-R5)
|
||||
**~30 lines.**
|
||||
**DONE — Test A via `cambiarPreset` (the public preset-change API); Test B counts both notifiers on `estado.ecualizador.cambiarPreset` (radio = 0, eq ≥ 1).**
|
||||
|
||||
### S4a implementation
|
||||
|
||||
- [ ] **T-S4a-03** [GREEN] Create `lib/servicios/servicio_export_import.dart`: `ServicioExportImport` class with `exportar(config) → String` and `importar(json) → ConfiguracionCompleta?`. Move all `jsonEncode`/`jsonDecode` backup/restore logic from `lib/pantallas/pantalla_ajustes.dart` (~1391 lines). `PantallaAjustes` delegates to this service. **Reqs:** S4-R4. **~100 lines (service) + ~30 lines cleanup in pantalla_ajustes.**
|
||||
- [ ] **T-S4a-04** [GREEN] Create `lib/estado/estado_ecualizador.dart`: `EstadoEcualizador extends ChangeNotifier` — owns preset, bands, enabled flag. Move EQ state fields and methods from `lib/estado/estado_radio.dart`. Add `ProxyProvider` registration in `MultiProvider` (wherever providers are registered, likely `lib/main.dart` or `lib/app.dart`). **Reqs:** S4-R1. **~90 lines.**
|
||||
- [ ] **T-S4a-05** [GREEN] Edit `lib/estado/estado_radio.dart`: add backward-compatible getters delegating EQ state to `EstadoEcualizador` (transition bridge). These are removed in S4b. Add `// TODO(S4b): remove getter` comments. **~20 lines.**
|
||||
- [ ] **T-S4a-06** [GREEN] Edit `lib/widgets/ecualizador_widget.dart` and `lib/pantallas/pantalla_ajustes.dart` EQ sections: consume `context.watch<EstadoEcualizador>()` (scoped). Screens still compile via compat getters if missed. **Reqs:** S4-R5. **~20 lines.**
|
||||
- [x] **T-S4a-03** [GREEN] Create `lib/servicios/servicio_export_import.dart`: `ServicioExportImport` class with `exportar(config) → String` and `importar(json) → ConfiguracionCompleta?`. Move all `jsonEncode`/`jsonDecode` backup/restore logic from `lib/pantallas/pantalla_ajustes.dart` (~1391 lines). `PantallaAjustes` delegates to this service. **Reqs:** S4-R4. **DONE — service owns the v2 envelope (`construirExportacion`), pretty-print (`exportar`) and graceful parse (`importar` → `Map?`, null on malformed). `dart:convert` removed from pantalla_ajustes; EstadoRadio exposes `exportarConfigJson`/`parsearConfigJson`. DEVIATION: `Map<String,dynamic>` instead of a `ConfiguracionCompleta` model (see apply-progress).**
|
||||
- [x] **T-S4a-04** [GREEN] Create `lib/estado/estado_ecualizador.dart`: `EstadoEcualizador extends ChangeNotifier` — owns preset, bands, enabled flag. Move EQ state fields and methods from `lib/estado/estado_radio.dart`. Add `ProxyProvider` registration in `MultiProvider` (wherever providers are registered, likely `lib/main.dart` or `lib/app.dart`). **Reqs:** S4-R1. **DONE — owns principal/actual/per-station presets + activo, persistence via ServicioEcualizador, application via ServicioAudio; `emisoraActualUuid` callback decouples it from station lists. Registered via `ListenableProvider` (not ProxyProvider — see deviation) in `app.dart`; instance owned/disposed by EstadoRadio during the S4 transition.**
|
||||
- [x] **T-S4a-05** [GREEN] Edit `lib/estado/estado_radio.dart`: add backward-compatible getters delegating EQ state to `EstadoEcualizador` (transition bridge). These are removed in S4b. Add `// TODO(S4b): remove getter` comments. **DONE — 15 delegating getters/methods, every one tagged `// TODO(S4b): remove getter`. EQ fields, `_cargarEcualizadorPersistido`, `_aplicarPresetActivo`, `_presetParaEmisora` removed from EstadoRadio.**
|
||||
- [x] **T-S4a-06** [GREEN] Edit `lib/widgets/ecualizador_widget.dart` and `lib/pantallas/pantalla_ajustes.dart` EQ sections: consume `context.watch<EstadoEcualizador>()` (scoped). Screens still compile via compat getters if missed. **Reqs:** S4-R5. **DONE — `_SeccionEcualizador` now `Consumer2<EstadoRadio, EstadoEcualizador>` (radio only for station/favorite info); `ecualizador_widget.dart` is purely presentational (props + callbacks), no change needed. ALSO rewired `pantalla_reproductor.dart` EQ toggle (required for correctness — see deviation).**
|
||||
|
||||
### S4a verification
|
||||
|
||||
- [ ] **T-S4a-07** Run `flutter test test/servicios/servicio_export_import_test.dart test/estado/estado_ecualizador_test.dart`.
|
||||
- [ ] **T-S4a-08** Run `flutter test` (full suite) — no regressions.
|
||||
- [ ] **T-S4a-09** Run `flutter analyze` — zero errors.
|
||||
- [ ] **T-S4a-10** Run `dart format lib/servicios/servicio_export_import.dart lib/estado/estado_ecualizador.dart lib/estado/estado_radio.dart lib/pantallas/pantalla_ajustes.dart`.
|
||||
- [x] **T-S4a-07** Run `flutter test test/servicios/servicio_export_import_test.dart test/estado/estado_ecualizador_test.dart` — 4/4 green (RED captured first: `+0 -2` load failures).
|
||||
- [x] **T-S4a-08** Run `flutter test` (full suite) — 103/103 passing (99 baseline + 4 new), no regressions.
|
||||
- [x] **T-S4a-09** Run `flutter analyze` — `No issues found!`.
|
||||
- [x] **T-S4a-10** Run `dart format` on all 8 touched Dart files (4 reflowed); analyze + full suite re-run after format.
|
||||
|
||||
### S4a Definition of Done
|
||||
- `flutter test` green.
|
||||
|
||||
Reference in New Issue
Block a user