Files
sm-emby-share/lib/features/player/widgets/player_volume_button.dart
T

104 lines
3.0 KiB
Dart
Raw Normal View History

2026-07-14 11:11:36 +08:00
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)),
),
),
),
],
),
);
}
}