fix(escuchar): show the station meta line in the hero
Audit 1.6 (t4 line 62): the Escuchar hero never rendered "genre · country · bitrate kbps" between the station name and the visualizer. Built from fields Emisora already carries (tags/pais/bitrate) — no new fields, no service calls — omitting gracefully whatever a station lacks.
This commit is contained in:
@@ -267,6 +267,22 @@ class _EscucharHero extends StatelessWidget {
|
|||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
if (_metaEscuchar(emisora) case final meta?) ...[
|
||||||
|
const SizedBox(height: 4),
|
||||||
|
Text(
|
||||||
|
meta,
|
||||||
|
key: const ValueKey('escuchar-hero-meta'),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12.5,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: theme.colorScheme.onSurface.withValues(
|
||||||
|
alpha: 0.62,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
],
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
VisualizadorAudio(
|
VisualizadorAudio(
|
||||||
estadoStream: estado.estadoStream,
|
estadoStream: estado.estadoStream,
|
||||||
@@ -536,3 +552,17 @@ class _FilaTransporteEscuchar extends StatelessWidget {
|
|||||||
: l10n.durationMinutesSeconds(d.inMinutes, s);
|
: l10n.durationMinutesSeconds(d.inMinutes, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Audit 1.6 (t4 line 62): "género · país · kbps" built ONLY from fields
|
||||||
|
/// [Emisora] already carries (`tags`/`pais`/`bitrate`) — no new fields, no
|
||||||
|
/// service calls. Whatever a station lacks is omitted gracefully; this
|
||||||
|
/// never renders a stray leading/trailing/doubled " · ".
|
||||||
|
String? _metaEscuchar(Emisora emisora) {
|
||||||
|
final partes = <String>[
|
||||||
|
if (emisora.generos.isNotEmpty) emisora.generos.first,
|
||||||
|
if (emisora.pais != null && emisora.pais!.isNotEmpty) emisora.pais!,
|
||||||
|
if (emisora.bitrate != null && emisora.bitrate! > 0)
|
||||||
|
'${emisora.bitrate} kbps',
|
||||||
|
];
|
||||||
|
return partes.isEmpty ? null : partes.join(' · ');
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:pluriwave/estado/estado_grabacion.dart';
|
|||||||
import 'package:pluriwave/estado/estado_navegacion.dart';
|
import 'package:pluriwave/estado/estado_navegacion.dart';
|
||||||
import 'package:pluriwave/estado/estado_radio.dart';
|
import 'package:pluriwave/estado/estado_radio.dart';
|
||||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||||
|
import 'package:pluriwave/modelos/emisora.dart';
|
||||||
import 'package:pluriwave/pantallas/pantalla_inicio.dart';
|
import 'package:pluriwave/pantallas/pantalla_inicio.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
@@ -164,6 +165,79 @@ void main() {
|
|||||||
reason: 'prototype t4 line 56 sizes the Escuchar hero artwork at 132',
|
reason: 'prototype t4 line 56 sizes the Escuchar hero artwork at 132',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('visual fidelity (audit 1.6): the hero shows "genre · country · '
|
||||||
|
'bitrate kbps" built from the station model, nothing invented', (
|
||||||
|
tester,
|
||||||
|
) async {
|
||||||
|
_setLargeSurfaceSize(tester);
|
||||||
|
final favoritos = FakeServicioFavoritos();
|
||||||
|
final estado = EstadoRadio(
|
||||||
|
audio: FakeServicioAudio(),
|
||||||
|
favoritos: favoritos,
|
||||||
|
radio: FakeServicioRadio(),
|
||||||
|
servicioEcualizador: FakeServicioEcualizador(),
|
||||||
|
servicioGrabacion: FakeServicioGrabacionRadio(),
|
||||||
|
resolverArchivoCustom: _archivoCustomVacio,
|
||||||
|
iniciarAutomaticamente: false,
|
||||||
|
);
|
||||||
|
addTearDown(estado.dispose);
|
||||||
|
await tester.runAsync(estado.inicializar);
|
||||||
|
const completa = Emisora(
|
||||||
|
uuid: 'meta-1',
|
||||||
|
nombre: 'Radio Horizonte',
|
||||||
|
url: 'https://stream.demo/radio',
|
||||||
|
tags: 'Noticias',
|
||||||
|
pais: 'España',
|
||||||
|
bitrate: 128,
|
||||||
|
);
|
||||||
|
await favoritos.agregar(completa);
|
||||||
|
await estado.cargarFavoritos();
|
||||||
|
// The hero only renders when a station is active.
|
||||||
|
await tester.runAsync(() => estado.reproducir(completa));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
_conProviders(estado, _testApp(const PantallaInicio())),
|
||||||
|
);
|
||||||
|
await _pumpBounded(tester);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
find.text('Noticias · España · 128 kbps'),
|
||||||
|
findsOneWidget,
|
||||||
|
reason: 'prototype t4 line 62: "Noticias · España · 128 kbps"',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'visual fidelity (audit 1.6): a station missing every meta field omits '
|
||||||
|
'the line gracefully, no stray separators',
|
||||||
|
(tester) async {
|
||||||
|
_setLargeSurfaceSize(tester);
|
||||||
|
final favoritos = FakeServicioFavoritos();
|
||||||
|
final estado = EstadoRadio(
|
||||||
|
audio: FakeServicioAudio(),
|
||||||
|
favoritos: favoritos,
|
||||||
|
radio: FakeServicioRadio(),
|
||||||
|
servicioEcualizador: FakeServicioEcualizador(),
|
||||||
|
servicioGrabacion: FakeServicioGrabacionRadio(),
|
||||||
|
resolverArchivoCustom: _archivoCustomVacio,
|
||||||
|
iniciarAutomaticamente: false,
|
||||||
|
);
|
||||||
|
addTearDown(estado.dispose);
|
||||||
|
await tester.runAsync(estado.inicializar);
|
||||||
|
final desnuda = emisoraDemo(uuid: 'meta-2', nombre: 'Radio Desnuda');
|
||||||
|
await favoritos.agregar(desnuda);
|
||||||
|
await estado.cargarFavoritos();
|
||||||
|
await tester.runAsync(() => estado.reproducir(desnuda));
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
_conProviders(estado, _testApp(const PantallaInicio())),
|
||||||
|
);
|
||||||
|
await _pumpBounded(tester);
|
||||||
|
|
||||||
|
expect(find.byKey(const ValueKey('escuchar-hero-meta')), findsNothing);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mirrors the app.dart wiring: EstadoRadio owns the domain notifiers and
|
/// Mirrors the app.dart wiring: EstadoRadio owns the domain notifiers and
|
||||||
|
|||||||
Reference in New Issue
Block a user