mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-29 21:02:09 +02:00
perf(player): commit seek gestures once after scrubbing
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Previews scrubbing locally and seeks once when the gesture ends.
|
||||
class PlaybackSeekSlider extends StatefulWidget {
|
||||
final Duration position;
|
||||
final Duration duration;
|
||||
final Future<void> Function(Duration) onSeek;
|
||||
|
||||
const PlaybackSeekSlider({
|
||||
super.key,
|
||||
required this.position,
|
||||
required this.duration,
|
||||
required this.onSeek,
|
||||
});
|
||||
|
||||
@override
|
||||
State<PlaybackSeekSlider> createState() => _PlaybackSeekSliderState();
|
||||
}
|
||||
|
||||
class _PlaybackSeekSliderState extends State<PlaybackSeekSlider> {
|
||||
double? _previewMs;
|
||||
int _gestureGeneration = 0;
|
||||
|
||||
Future<void> _commit(double value) async {
|
||||
final generation = _gestureGeneration;
|
||||
try {
|
||||
await widget.onSeek(Duration(milliseconds: value.round()));
|
||||
} finally {
|
||||
if (mounted && generation == _gestureGeneration) {
|
||||
setState(() => _previewMs = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final durationMs = widget.duration.inMilliseconds;
|
||||
final enabled = durationMs > 0;
|
||||
final maxMs = enabled ? durationMs.toDouble() : 1.0;
|
||||
return Slider(
|
||||
value: enabled
|
||||
? (_previewMs ?? widget.position.inMilliseconds.toDouble()).clamp(
|
||||
0,
|
||||
maxMs,
|
||||
)
|
||||
: 0,
|
||||
max: maxMs,
|
||||
onChangeStart: enabled ? (_) => _gestureGeneration++ : null,
|
||||
onChanged: enabled ? (value) => setState(() => _previewMs = value) : null,
|
||||
onChangeEnd: enabled ? _commit : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user