104 lines
3.0 KiB
Dart
104 lines
3.0 KiB
Dart
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<PlayerVolumeButton> createState() => _PlayerVolumeButtonState();
|
|
}
|
|
|
|
class _PlayerVolumeButtonState extends State<PlayerVolumeButton> {
|
|
late double _volume;
|
|
StreamSubscription<double>? _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)),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|