fix(stations): replace the ringed circle thumbnail with a plain square
The prototype's station thumbnail is a plain 44-48px square, radius 11/12, with no ring or glow (t4 lines 84, 175, 227, 302, 614). TarjetaEmisora's compact row variant instead painted a 58x58 circle wrapped in a SweepGradient ring (magenta/cyan/coral) and a 22-blur glow behind a 50x50 ClipRRect(18). Replace it with a 48x48 ClipRRect(12) square. Update the loading shimmer placeholder to match (was also a 58x58 circle block). S6, Tier 1 visual-fidelity pass (audit id 2521).
This commit is contained in:
@@ -8,7 +8,6 @@ import '../l10n/display_names.dart';
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../modelos/emisora.dart';
|
||||
import '../tema/pluriwave_theme.dart';
|
||||
import '../tema/pluriwave_tokens.dart';
|
||||
import 'pluri_glass_surface.dart';
|
||||
import 'pluri_icon.dart';
|
||||
|
||||
@@ -183,35 +182,13 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 58,
|
||||
height: 58,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
gradient: SweepGradient(
|
||||
colors: [
|
||||
t.electricMagenta,
|
||||
PluriWaveTokens.brightCyan,
|
||||
t.warmCoral,
|
||||
t.electricMagenta,
|
||||
],
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: t.glowColor.withValues(alpha: 0.24),
|
||||
blurRadius: 22,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
child: SizedBox(width: 50, height: 50, child: _logo(24)),
|
||||
),
|
||||
],
|
||||
// S6 (Tier 1 visual fidelity): the prototype's station thumbnail
|
||||
// is a plain square, radius 11/12, with NO ring or glow (t4 lines
|
||||
// 84, 175, 227, 302, 614) — was a 58x58 circle wrapped in a
|
||||
// SweepGradient ring and a 22-blur glow.
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: SizedBox(width: 48, height: 48, child: _logo(22)),
|
||||
),
|
||||
SizedBox(width: t.spacingSm),
|
||||
Expanded(
|
||||
@@ -454,7 +431,9 @@ class TarjetaEmisoraShimmer extends StatelessWidget {
|
||||
esCompacta
|
||||
? Row(
|
||||
children: [
|
||||
bloque(width: 58, height: 58, shape: BoxShape.circle),
|
||||
// S6: matches the real square thumbnail (48x48, radius 12)
|
||||
// — was a 58x58 circle block.
|
||||
bloque(width: 48, height: 48, radius: 12),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Column(
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/estado/estado_radio.dart';
|
||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||
import 'package:pluriwave/widgets/tarjeta_emisora.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../helpers/fakes.dart';
|
||||
|
||||
/// S6 (Tier 1 visual fidelity): the prototype's station thumbnail is a
|
||||
/// plain 44-48px square, radius 11/12, with NO ring or glow (t4 lines 84
|
||||
/// `44px/radius 11`, 175 `46px/radius 12`, 227 `48px/radius 12`, 302
|
||||
/// `48px/radius 12`, 614 `44px/radius 12`). The compact row variant used to
|
||||
/// paint a 58x58 circle with a `SweepGradient` ring and a 22-blur glow
|
||||
/// behind a 50x50 `ClipRRect(18)`.
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
});
|
||||
|
||||
Widget host(Widget child) {
|
||||
final estado = EstadoRadio(
|
||||
audio: FakeServicioAudio(),
|
||||
favoritos: FakeServicioFavoritos(),
|
||||
radio: FakeServicioRadio(),
|
||||
servicioEcualizador: FakeServicioEcualizador(),
|
||||
iniciarAutomaticamente: false,
|
||||
);
|
||||
addTearDown(estado.dispose);
|
||||
return ChangeNotifierProvider<EstadoRadio>.value(
|
||||
value: estado,
|
||||
child: MaterialApp(
|
||||
locale: const Locale('en'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: Scaffold(body: Center(child: child)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool isRingContainer(Widget w) =>
|
||||
w is Container &&
|
||||
w.decoration is BoxDecoration &&
|
||||
(w.decoration as BoxDecoration).shape == BoxShape.circle &&
|
||||
(w.decoration as BoxDecoration).gradient is SweepGradient;
|
||||
|
||||
testWidgets('esCompacta (row) thumbnail is a 48x48 square, radius 12, no '
|
||||
'ring/glow', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
host(
|
||||
SizedBox(
|
||||
width: 320,
|
||||
child: TarjetaEmisora(
|
||||
emisora: emisoraDemo(uuid: 'row', nombre: 'Row FM'),
|
||||
esCompacta: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byWidgetPredicate(isRingContainer), findsNothing);
|
||||
|
||||
// Not `.first` — the outer PluriGlassSurface also renders its own
|
||||
// ClipRRect (radius 14, the row surface radius from S4), so the
|
||||
// thumbnail's own clip must be found by its distinct radius instead of
|
||||
// tree order.
|
||||
final thumbnailClip = find.byWidgetPredicate(
|
||||
(w) => w is ClipRRect && w.borderRadius == BorderRadius.circular(12),
|
||||
);
|
||||
expect(thumbnailClip, findsOneWidget);
|
||||
expect(tester.getSize(thumbnailClip), const Size(48, 48));
|
||||
});
|
||||
|
||||
testWidgets('esCompacta shimmer placeholder is a square block, not a '
|
||||
'circle', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
host(const TarjetaEmisoraShimmer(esCompacta: true)),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.byWidgetPredicate(isRingContainer), findsNothing);
|
||||
final circles = tester
|
||||
.widgetList<Container>(find.byType(Container))
|
||||
.where(
|
||||
(c) =>
|
||||
c.decoration is BoxDecoration &&
|
||||
(c.decoration as BoxDecoration).shape == BoxShape.circle,
|
||||
);
|
||||
expect(
|
||||
circles,
|
||||
isEmpty,
|
||||
reason: 'the real thumbnail is square now — its shimmer must match',
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user