Initial commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user