import 'package:flutter/material.dart'; import '../l10n/gen/app_localizations.dart'; import '../tema/pluriwave_theme.dart'; import 'pluri_icon.dart'; /// Shared station-art fallback (feedback-pruebas issue 6). /// /// Before this widget existed, `TarjetaEmisora` had the only good fallback — /// a deterministic pick from 4 bundled illustrations (`_fallbackArtFor`), /// with a gradient + player glyph as a last resort if the asset itself ever /// fails to decode. Every OTHER surface that can render a station without /// artwork (`FilaEmisoraPlana`'s flat rows, the Escuchar hero, the "Tus /// emisoras" grid cell, the mini player, the full player) had its own, /// separate, much poorer copy: a flat `primaryContainer`-coloured square /// with a bare `radio_rounded` icon. This widget is the ONE shared /// implementation every one of those call sites now uses instead. /// /// The selection formula is pinned EXACTLY as `TarjetaEmisora` originally /// had it (`seed.codeUnits.fold(0, (a, b) => a + b) % 4`, asset order /// aurora/cosmic/pulse/nova) — `lib/servicios/navegacion_auto.dart` (a /// protected, empty-diff file) independently mirrors this SAME formula for /// Android Auto's own drawable-resource rotation /// (`test/servicios/navegacion_auto_test.dart`'s `indiceArtePara`/ /// `artUriPara` tests assert it inline, not by importing this widget) — /// changing the order or the modulo here would silently desync the two /// without either test suite noticing until an actual device compared them /// side by side. class PluriStationArtFallback extends StatelessWidget { const PluriStationArtFallback({ super.key, required this.seed, this.iconSize = 22, }); /// Typically the station's `uuid` — the seed that deterministically picks /// one of the 4 bundled arts below. final String seed; /// Size of the centred player glyph drawn over the art. final double iconSize; static const _arts = [ 'assets/images/station_art_aurora.png', 'assets/images/station_art_cosmic.png', 'assets/images/station_art_pulse.png', 'assets/images/station_art_nova.png', ]; /// Exposed so other call sites (and tests) can assert which asset a given /// seed resolves to without needing to render the widget. static String artFor(String seed) { final index = seed.codeUnits.fold(0, (a, b) => a + b) % _arts.length; return _arts[index]; } @override Widget build(BuildContext context) { return Stack( fit: StackFit.expand, children: [ Image.asset( artFor(seed), fit: BoxFit.cover, errorBuilder: (_, __, ___) => DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ context.pluriTokens.deepViolet, context.pluriTokens.electricMagenta.withValues( alpha: 0.8, ), ], ), ), ), ), Center( child: PluriIcon( glyph: PluriIconGlyph.player, variant: PluriIconVariant.activeGlow, size: iconSize, semanticLabel: AppLocalizations.of(context).stationIconLabel, ), ), ], ); } }