- 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.
4.9 KiB
Exploration: Startup retry, custom stations, and equalizer persistence
Current State
lib/main.dartonly initializesAudioServiceand launchesPluriWaveApp; app data initialization starts later whenEstadoRadiois created byChangeNotifierProviderinlib/app.dart.EstadoRadioconstructor calls_init()without awaiting it._init()runsFuture.wait([cargarPopulares(), cargarFavoritos(), _cargarEmisoresCustom()]).cargarPopulares()fetchesradio.obtenerPopulares()andradio.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_servidorActualon 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_SeccionEmisorasinpantalla_ajustes.dart.PantallaIniciolists API stations only, so custom stations never enter the main grid.TarjetaEmisoraalready supports favorites for anyEmisora. - Equalizer state is in memory only:
_presetActualplus_presetsEmisoraMapinEstadoRadio. 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 byemisoraActual, whilePluriWaveAudioHandler.emisoraActualis declared but never assigned when playback starts. - Existing tests are only
test/widget_test.dart, a placeholder assertingtrue. 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
-
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.
- Pros: small change; directly targets startup; easy to preserve
-
Retry inside
ServicioRadio._get()with host rotation- Pros: centralizes network resilience; startup and search benefit; keeps
EstadoRadiosimpler. - Cons: needs injectable HTTP client/delay for tests; must avoid long blocking startup.
- Effort: Medium.
- Pros: centralizes network resilience; startup and search benefit; keeps
-
Merge custom stations into main grid via
EstadoRadiogetter- Pros: minimal UI disruption;
TarjetaEmisoraalready handles favorite toggles. - Cons: custom and API stations share one grid; no separate "My stations" visual grouping.
- Effort: Low.
- Pros: minimal UI disruption;
-
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.
-
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.
- Pros: dependency already exists; JSON values fit
-
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.