fix(alarm): start the fade-in when pre-started audio is already playing
The ringing screen only confirmed the native-to-Flutter handoff from its playback-state listener, but app.dart pre-starts the station before pushing the screen, so `reproduciendo` could be emitted before the listener subscribed and no further event ever arrived. That branch only cancelled the fallback timer: the gated fade-in never started and the native alarm player was never told to stop, so the alarm blared at the alarm-stream volume with no 5%-to-target ramp. Previously this was a timing race the stream usually lost; gating the ramp on the confirmation made the failure deterministic. The already-playing branch now confirms the handoff explicitly (idempotent with the listener), and the ramp re-imposes its 5% start volume immediately instead of waiting for the first periodic tick. Adds the regression test mounting in the real pre-started path.
This commit is contained in:
@@ -88,8 +88,15 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
_fallbackTimer = Timer(const Duration(seconds: 12), () {
|
||||
if (mounted) _iniciarFallback();
|
||||
});
|
||||
// Pre-started audio can reach `reproduciendo` BEFORE the listener above
|
||||
// subscribes (app.dart starts the station before pushing this screen),
|
||||
// in which case no further state event ever arrives. The handoff
|
||||
// confirmation and the fade-in must not depend on catching that
|
||||
// already-missed event, so this branch confirms explicitly too
|
||||
// (idempotent — the listener firing as well is harmless).
|
||||
if (widget.audioPrearrancado && radio.audio.estaSonando) {
|
||||
_fallbackTimer?.cancel();
|
||||
await _confirmarAudioFlutterListo();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +118,10 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
|
||||
unawaited(_aplicarVolumenGlobal(volumenObjetivo));
|
||||
return;
|
||||
}
|
||||
// Re-impose the ramp's start volume immediately: the first periodic tick
|
||||
// only lands after _fadeStep, and by now the player may have been
|
||||
// recreated or re-leveled since the pre-start set it to 5%.
|
||||
unawaited(_aplicarVolumenGlobal(inicio));
|
||||
final duracionTotalMs = segundosFade * 1000;
|
||||
final pasos = (duracionTotalMs / _fadeStep.inMilliseconds).ceil();
|
||||
var pasoActual = 0;
|
||||
|
||||
Reference in New Issue
Block a user