feat(ui): add premium PluriWave redesign
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../servicios/servicio_audio.dart';
|
||||
@@ -49,6 +50,7 @@ class _VisualizadorAudioState extends State<VisualizadorAudio>
|
||||
late List<_BarraState> _barras;
|
||||
final _random = Random();
|
||||
bool _activo = false;
|
||||
StreamSubscription<EstadoReproduccion>? _estadoSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -68,13 +70,14 @@ class _VisualizadorAudioState extends State<VisualizadorAudio>
|
||||
duration: const Duration(seconds: 1),
|
||||
)..addListener(_actualizar);
|
||||
|
||||
widget.estadoStream.listen(_onEstado);
|
||||
_estadoSubscription = widget.estadoStream.listen(_onEstado);
|
||||
}
|
||||
|
||||
void _onEstado(EstadoReproduccion estado) {
|
||||
final nuevoActivo = estado == EstadoReproduccion.reproduciendo ||
|
||||
estado == EstadoReproduccion.cargando;
|
||||
if (nuevoActivo == _activo) return;
|
||||
if (!mounted) return;
|
||||
setState(() => _activo = nuevoActivo);
|
||||
if (nuevoActivo) {
|
||||
_controller.repeat();
|
||||
@@ -91,6 +94,7 @@ class _VisualizadorAudioState extends State<VisualizadorAudio>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_estadoSubscription?.cancel();
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
@@ -110,10 +114,11 @@ class _VisualizadorAudioState extends State<VisualizadorAudio>
|
||||
final espaciado = totalAncho / widget.barras;
|
||||
final anchoBar = (espaciado * 0.55).clamp(2.0, 8.0);
|
||||
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: List.generate(widget.barras, (i) {
|
||||
return RepaintBoundary(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: List.generate(widget.barras, (i) {
|
||||
final b = _barras[i];
|
||||
final double altura;
|
||||
|
||||
@@ -131,21 +136,22 @@ class _VisualizadorAudioState extends State<VisualizadorAudio>
|
||||
altura = b.alturaActual.clamp(2.0, widget.altura * 0.05);
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: (espaciado - anchoBar) / 2),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 80),
|
||||
width: anchoBar,
|
||||
height: altura.clamp(2.0, widget.altura),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withValues(
|
||||
alpha: _activo ? 0.7 + (altura / widget.altura) * 0.3 : 0.3,
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: (espaciado - anchoBar) / 2),
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 80),
|
||||
width: anchoBar,
|
||||
height: altura.clamp(2.0, widget.altura),
|
||||
decoration: BoxDecoration(
|
||||
color: color.withValues(
|
||||
alpha: _activo ? 0.7 + (altura / widget.altura) * 0.3 : 0.3,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(anchoBar / 2),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(anchoBar / 2),
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -190,15 +196,17 @@ class _IndicadorReproduccionState extends State<IndicadorReproduccion>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late AnimationController _ctrl;
|
||||
bool _reproduciendo = false;
|
||||
StreamSubscription<EstadoReproduccion>? _estadoSubscription;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_ctrl = AnimationController(vsync: this, duration: const Duration(milliseconds: 600))
|
||||
..addListener(() => setState(() {}));
|
||||
widget.estadoStream.listen((s) {
|
||||
_estadoSubscription = widget.estadoStream.listen((s) {
|
||||
final rep = s == EstadoReproduccion.reproduciendo;
|
||||
if (rep == _reproduciendo) return;
|
||||
if (!mounted) return;
|
||||
setState(() => _reproduciendo = rep);
|
||||
rep ? _ctrl.repeat(reverse: true) : _ctrl.stop();
|
||||
});
|
||||
@@ -206,6 +214,7 @@ class _IndicadorReproduccionState extends State<IndicadorReproduccion>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_estadoSubscription?.cancel();
|
||||
_ctrl.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user