import 'dart:async'; import 'package:flutter/material.dart'; import '../../../core/infra/player_engine/player_engine.dart'; class PlayerVolumeButton extends StatefulWidget { final PlayerEngine player; final bool volumeBoost; const PlayerVolumeButton({ super.key, required this.player, this.volumeBoost = false, }); @override State createState() => _PlayerVolumeButtonState(); } class _PlayerVolumeButtonState extends State { late double _volume; StreamSubscription? _sub; @override void initState() { super.initState(); _volume = widget.player.state.volume; _sub = widget.player.stream.volume.listen((volume) { if (mounted) setState(() => _volume = volume); }); } @override void didUpdateWidget(covariant PlayerVolumeButton oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.player != widget.player) { unawaited(_sub?.cancel()); _volume = widget.player.state.volume; _sub = widget.player.stream.volume.listen((volume) { if (mounted) setState(() => _volume = volume); }); } } @override void dispose() { unawaited(_sub?.cancel()); super.dispose(); } @override Widget build(BuildContext context) { final muted = _volume <= 0; final max = widget.volumeBoost ? 150.0 : 100.0; return SizedBox( width: 122, child: Row( children: [ IconButton( tooltip: muted ? '取消静音' : '静音', onPressed: () => unawaited(widget.player.toggleMute()), icon: Icon( muted ? Icons.volume_off : (_volume < 45 ? Icons.volume_down : Icons.volume_up), color: Colors.white, size: 24, ), ), Expanded( child: SliderTheme( data: const SliderThemeData( trackHeight: 3, thumbShape: RoundSliderThumbShape(enabledThumbRadius: 6), overlayShape: RoundSliderOverlayShape(overlayRadius: 12), activeTrackColor: Colors.white, inactiveTrackColor: Colors.white24, thumbColor: Colors.white, overlayColor: Colors.white10, showValueIndicator: ShowValueIndicator.onlyForContinuous, valueIndicatorShape: PaddleSliderValueIndicatorShape(), valueIndicatorColor: Color(0xCC1E1E1E), valueIndicatorTextStyle: TextStyle( color: Colors.white, fontSize: 12, fontFeatures: [FontFeature.tabularFigures()], ), ), child: Slider( value: _volume.clamp(0.0, max), min: 0, max: max, label: '${_volume.round()}', onChanged: (value) => unawaited(widget.player.setVolume(value)), ), ), ), ], ), ); } }