summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrangerot <purple@orangerot.dev>2024-12-23 04:18:04 +0100
committerOrangerot <purple@orangerot.dev>2024-12-23 04:18:04 +0100
commit97598c741de84b48630293928690d8be2be7e6c6 (patch)
treeeb2f50d6495fd3b0993cb6b7e063c5946374171b
parent1415f91fa5f32b53f69332c7f1ef1129a3d9f454 (diff)
feat: ProgressBar shows position in songHEADmain
-rw-r--r--lib/level.dart95
1 files changed, 76 insertions, 19 deletions
diff --git a/lib/level.dart b/lib/level.dart
index e35325a..1391f8a 100644
--- a/lib/level.dart
+++ b/lib/level.dart
@@ -1,3 +1,4 @@
+import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
@@ -12,44 +13,98 @@ class Level extends StatefulWidget {
}
class _LevelState extends State<Level> {
- final _player = AudioPlayer();
+ final player = AudioPlayer();
bool _isPlaying = true;
+ Duration? _duration;
+ Duration? _position;
+
+ StreamSubscription? _durationSubscription;
+ StreamSubscription? _positionSubscription;
+
+ @override
+ void setState(VoidCallback fn) {
+ // Subscriptions only can be closed asynchronously,
+ // therefore events can occur after widget has been disposed.
+ if (mounted) {
+ super.setState(fn);
+ }
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ // Use initial values from player
+ player.getDuration().then(
+ (value) => setState(() {
+ _duration = value;
+ }),
+ );
+ player.getCurrentPosition().then(
+ (value) => setState(() {
+ _position = value;
+ }),
+ );
+ _durationSubscription = player.onDurationChanged.listen((duration) {
+ setState(() => _duration = duration);
+ });
+
+ _positionSubscription = player.onPositionChanged.listen(
+ (p) => setState(() => _position = p),
+ );
+ }
@override
Widget build(BuildContext context) {
+ player.onDurationChanged.listen((Duration d) {
+ // print('Max duration: $d');
+ setState(() => _duration = d);
+ });
+
+ player.onPositionChanged.listen((Duration p) {
+ // print('Current position: $p');
+ setState(() => _position = p);
+ });
+
String audioPath = Directory(widget.stepmaniaFolderPath)
.listSync()
.firstWhere((entity) => entity.path.endsWith('.ogg'),
orElse: () => File(''))
.path;
- _player.play(DeviceFileSource(audioPath));
+ player.play(DeviceFileSource(audioPath));
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
- onPressed: () => {
- if (_isPlaying)
- {
- _player.pause(),
- setState(() {
- _isPlaying = false;
- })
- }
- else
- {
- _player.resume(),
- setState(() {
- _isPlaying = true;
- })
- },
+ onPressed: () {
+ if (_isPlaying) {
+ player.pause();
+ setState(() {
+ _isPlaying = false;
+ });
+ } else {
+ player.resume();
+ setState(() {
+ _isPlaying = true;
+ });
+ }
},
),
- title: Text('Level 1'),
+ title: Text(widget.stepmaniaFolderPath.split('/').last),
actions: [
IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.pop(context))
],
+ bottom: PreferredSize(
+ preferredSize: Size(double.infinity, 1.0),
+ child: LinearProgressIndicator(
+ value: (_duration != null &&
+ _position != null &&
+ _position!.inMilliseconds > 0 &&
+ _position!.inMilliseconds < _duration!.inMilliseconds)
+ ? _position!.inMilliseconds / _duration!.inMilliseconds
+ : 0.0,
+ )),
),
body: Stack(children: [
Arrow(
@@ -91,7 +146,9 @@ class _LevelState extends State<Level> {
@override
void dispose() {
- _player.dispose();
+ _durationSubscription?.cancel();
+ _positionSubscription?.cancel();
+ player.dispose();
super.dispose();
}
}