feat: Implement startup retry mechanism for custom stations and equalizer persistence
- Added state management for startup retry and custom station handling in `EstadoRadio`. - Created tasks for implementing strict TDD with RED tests for HTTP failure retries and EQ persistence. - Developed verification report to ensure compliance with TDD practices. - Introduced fake services for testing, including `FakeServicioAudio`, `FakeServicioFavoritos`, and `FakeServicioRadio`. - Implemented widget tests for `PantallaInicio` and `PantallaFavoritos` to validate UI behavior with custom stations. - Enhanced `ServicioRadio` to support host rotation and retry logic for API calls. - Established a new configuration file to enforce project constraints and testing rules.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
# Exploration: Startup retry, custom stations, and equalizer persistence
|
||||
|
||||
## Current State
|
||||
|
||||
- `lib/main.dart` only initializes `AudioService` and launches `PluriWaveApp`; app data initialization starts later when `EstadoRadio` is created by `ChangeNotifierProvider` in `lib/app.dart`.
|
||||
- `EstadoRadio` constructor calls `_init()` without awaiting it. `_init()` runs `Future.wait([cargarPopulares(), cargarFavoritos(), _cargarEmisoresCustom()])`.
|
||||
- `cargarPopulares()` fetches `radio.obtenerPopulares()` and `radio.obtenerTendencias()` once. On any failure it sets `_errorCarga = 'Sin conexion a la API de radio'`; the UI exposes a manual "Reintentar" button but there is no automatic startup retry.
|
||||
- `ServicioRadio._get()` picks one fallback Radio Browser host, applies a 10s timeout, and clears `_servidorActual` on error so a later call can rotate. It does not retry within the same request.
|
||||
- Custom stations are stored as JSON from inside `EstadoRadio` (`emisoras_custom.json`) and are only rendered in `_SeccionEmisoras` in `pantalla_ajustes.dart`. `PantallaInicio` lists API stations only, so custom stations never enter the main grid. `TarjetaEmisora` already supports favorites for any `Emisora`.
|
||||
- Equalizer state is in memory only: `_presetActual` plus `_presetsEmisoraMap` in `EstadoRadio`. Export/import includes station preset maps, but startup never loads EQ state from app storage.
|
||||
- Per-station EQ is currently unreliable because `EstadoRadio.cambiarPresetEcualizador()` stores by `emisoraActual`, while `PluriWaveAudioHandler.emisoraActual` is declared but never assigned when playback starts.
|
||||
- Existing tests are only `test/widget_test.dart`, a placeholder asserting `true`. Strict TDD is active, so the implementation needs test seams before behavior changes.
|
||||
|
||||
## Affected Areas
|
||||
|
||||
- `lib/servicios/servicio_radio.dart` - startup/API fetch resilience and host retry behavior.
|
||||
- `lib/estado/estado_radio.dart` - startup orchestration, custom station listing, EQ load/save, station EQ selection.
|
||||
- `lib/servicios/servicio_audio.dart` - current station tracking needed for mini player and per-station EQ.
|
||||
- `lib/pantallas/pantalla_inicio.dart` - main listing must include custom stations.
|
||||
- `lib/pantallas/pantalla_ajustes.dart` / `lib/widgets/ecualizador_widget.dart` - EQ scope controls and persisted graph display.
|
||||
- `lib/modelos/preset_ecualizador.dart` - equality/copy helpers may be needed for persistence tests.
|
||||
- `test/` - new unit/widget tests for startup retry, custom station listing/favorites, and EQ persistence.
|
||||
|
||||
## Approaches
|
||||
|
||||
1. **Retry in `EstadoRadio.cargarPopulares()`**
|
||||
- Pros: small change; directly targets startup; easy to preserve `ServicioRadio`.
|
||||
- Cons: search calls still lack retry; duplicated retry policy if other API calls need it.
|
||||
- Effort: Low.
|
||||
|
||||
2. **Retry inside `ServicioRadio._get()` with host rotation**
|
||||
- Pros: centralizes network resilience; startup and search benefit; keeps `EstadoRadio` simpler.
|
||||
- Cons: needs injectable HTTP client/delay for tests; must avoid long blocking startup.
|
||||
- Effort: Medium.
|
||||
|
||||
3. **Merge custom stations into main grid via `EstadoRadio` getter**
|
||||
- Pros: minimal UI disruption; `TarjetaEmisora` already handles favorite toggles.
|
||||
- Cons: custom and API stations share one grid; no separate "My stations" visual grouping.
|
||||
- Effort: Low.
|
||||
|
||||
4. **Separate "Mis emisoras" section on `PantallaInicio`**
|
||||
- Pros: clearer UX; no confusion with API popularity ranking.
|
||||
- Cons: more UI work and widget tests; still must define empty/genre-filter behavior.
|
||||
- Effort: Medium.
|
||||
|
||||
5. **Persist EQ in SharedPreferences through a dedicated service**
|
||||
- Pros: dependency already exists; JSON values fit `PresetEcualizador`; avoids SQLite migration.
|
||||
- Cons: less relational than SQLite; needs careful key/version handling.
|
||||
- Effort: Medium.
|
||||
|
||||
6. **Persist EQ in SQLite favorites table**
|
||||
- Pros: station-specific EQ close to favorite rows.
|
||||
- Cons: requires DB migration and does not naturally store global/main EQ.
|
||||
- Effort: High.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Use service-level radio retry with host rotation, expose a combined main-station getter for custom stations, and introduce a small `ServicioEcualizador` backed by SharedPreferences. Represent station EQ as "entry exists = own EQ; no entry = use main EQ". Also fix current-station tracking in the audio layer before wiring station EQ; otherwise the UI and per-station persistence sit on arena sand, not concrete.
|
||||
|
||||
## Risks
|
||||
|
||||
- Retrying both popular and trending in parallel can lengthen startup; cap attempts and use short backoff.
|
||||
- SharedPreferences persistence must be loaded before the first playback applies EQ.
|
||||
- Android equalizer availability is runtime-dependent; persisted EQ must still load even when native EQ is not available yet.
|
||||
- Adding test seams can touch constructors; keep backward-compatible defaults.
|
||||
|
||||
## Ready for Proposal
|
||||
|
||||
Yes. The code paths are clear enough to plan without production changes.
|
||||
Reference in New Issue
Block a user