Restructures PantallaInicio's top of screen: a new _EscucharHero (square art, live/offline pill, VisualizadorAudio at barras: 30 / altura: 26 / color: liveGreen, a 5-action transport row - favorite, EQ toggle, stop, play/pause, sleep - plus a tool-tray entry chip opening the full player) replaces the old PluriScreenHeader hero, and a new "Tus emisoras" section (favorites preview, capped, "Ver todas") follows it. Per design ADR-7, EstadoRadio stays the single source of truth: the hero is a StatelessWidget with no cached fields, reading emisoraActual via context.select (uuid-based equality scopes rebuilds to real station changes) and the fast-changing playback status via StreamBuilder, the same pattern _Controles/MiniReproductor already use. The still-present discovery sections (_seccionCercanas onward, including the old grid) are deliberately left in place - WU6 relocates them to Buscar and deletes them from here; removing them now would leave that content nowhere until WU6 lands. MiniReproductor gains a `visible` parameter (default true) and a measured `static const double altura`. app.dart passes `visible: indice != RaizPluriWave.escuchar.index`, hiding it visually only (SizedBox.shrink()) while Escuchar is active, since the hero already shows the same station - the State stays mounted so its didChangeDependencies side effect (configurarLocalizaciones, S3-R3) keeps running regardless of tab. altura was measured empirically (72.0, via tester.getSize) rather than guessed, backing a new derived PluriLayout.escucharBottomChromeInset constant now wired into PantallaInicio's own bottom padding. "Ver todas" switches roots via EstadoNavegacionRaiz.irA(favoritos), verified via a NavigatorObserver asserting the push count is unchanged (switches tabs, does not push). Fixed a pre-existing test-infrastructure gap while writing the anti-cache test: no test in this codebase had ever exercised ServicioAudio.androidAudioSessionIdStream against a bare FakeServicioAudio (pantalla_reproductor.dart has always read it but has no test file at all) - the real getter needs registrarHandler() (main.dart, production only) and threw otherwise. Added an empty stream override to FakeServicioAudio, matching VisualizadorAudio's own documented no-native-session fallback. Tests: 614 -> 618 (2 skipped, unchanged). flutter analyze unchanged at 1 pre-existing info. git diff empty for visualizador_audio.dart and estado_radio.dart - this WU touches neither.
52 lines
1.4 KiB
Dart
52 lines
1.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../tema/pluriwave_theme.dart';
|
|
import 'mini_reproductor.dart';
|
|
|
|
abstract final class PluriLayout {
|
|
static const double horizontal = 16;
|
|
static const double sectionGap = 12;
|
|
static const double panelGap = 12;
|
|
static const double compactGap = 8;
|
|
static const double bottomChromeInset = 146;
|
|
|
|
/// ADR-7(b): `bottomChromeInset` assumes `MiniReproductor` is visible.
|
|
/// Escuchar hides it (design's one exception — the embedded hero already
|
|
/// shows the same station), so its content needs less bottom padding.
|
|
static const double escucharBottomChromeInset =
|
|
bottomChromeInset - MiniReproductor.altura;
|
|
|
|
static const EdgeInsets pageListPadding = EdgeInsets.fromLTRB(
|
|
0,
|
|
0,
|
|
0,
|
|
bottomChromeInset,
|
|
);
|
|
|
|
static const EdgeInsets pageContentPadding = EdgeInsets.symmetric(
|
|
horizontal: horizontal,
|
|
);
|
|
|
|
static const EdgeInsets sheetPadding = EdgeInsets.all(18);
|
|
}
|
|
|
|
class PluriPanelColumn extends StatelessWidget {
|
|
const PluriPanelColumn({super.key, required this.children, this.gap});
|
|
|
|
final List<Widget> children;
|
|
final double? gap;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final resolvedGap = gap ?? context.pluriTokens.spacingSm + 4;
|
|
return Column(
|
|
children: [
|
|
for (var i = 0; i < children.length; i++) ...[
|
|
if (i > 0) SizedBox(height: resolvedGap),
|
|
children[i],
|
|
],
|
|
],
|
|
);
|
|
}
|
|
}
|