mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
feat(playback): add repeat track support #166
This commit is contained in:
parent
daa62c73f7
commit
cae9993429
@ -103,20 +103,17 @@ class PlayerControls extends HookConsumerWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: [
|
children: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.shuffle_rounded),
|
icon: Icon(
|
||||||
color: playback.isShuffled
|
playback.isLoop
|
||||||
? Theme.of(context).primaryColor
|
? Icons.repeat_one_rounded
|
||||||
: iconColor,
|
: playback.isShuffled
|
||||||
onPressed: () {
|
? Icons.shuffle_rounded
|
||||||
if (playback.track == null || playback.playlist == null) {
|
: Icons.repeat_rounded,
|
||||||
return;
|
),
|
||||||
}
|
onPressed: playback.track == null || playback.playlist == null
|
||||||
try {
|
? null
|
||||||
playback.toggleShuffle();
|
: playback.cyclePlaybackMode,
|
||||||
} catch (e, stack) {
|
),
|
||||||
logger.e("onShuffle", e, stack);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.skip_previous_rounded),
|
icon: const Icon(Icons.skip_previous_rounded),
|
||||||
color: iconColor,
|
color: iconColor,
|
||||||
|
@ -37,9 +37,15 @@ enum AudioQuality {
|
|||||||
low,
|
low,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum PlaybackMode {
|
||||||
|
repeat,
|
||||||
|
shuffle,
|
||||||
|
normal,
|
||||||
|
}
|
||||||
|
|
||||||
class Playback extends PersistedChangeNotifier {
|
class Playback extends PersistedChangeNotifier {
|
||||||
// player properties
|
// player properties
|
||||||
bool isShuffled;
|
PlaybackMode playbackMode;
|
||||||
bool isPlaying;
|
bool isPlaying;
|
||||||
Duration currentDuration;
|
Duration currentDuration;
|
||||||
double volume;
|
double volume;
|
||||||
@ -72,9 +78,9 @@ class Playback extends PersistedChangeNotifier {
|
|||||||
required this.youtube,
|
required this.youtube,
|
||||||
required this.ref,
|
required this.ref,
|
||||||
this.mobileAudioService,
|
this.mobileAudioService,
|
||||||
}) : volume = 0,
|
}) : volume = 1,
|
||||||
isShuffled = false,
|
|
||||||
isPlaying = false,
|
isPlaying = false,
|
||||||
|
playbackMode = PlaybackMode.normal,
|
||||||
currentDuration = Duration.zero,
|
currentDuration = Duration.zero,
|
||||||
_subscriptions = [],
|
_subscriptions = [],
|
||||||
status = PlaybackStatus.idle,
|
status = PlaybackStatus.idle,
|
||||||
@ -102,7 +108,13 @@ class Playback extends PersistedChangeNotifier {
|
|||||||
),
|
),
|
||||||
player.onPlayerComplete.listen((_) {
|
player.onPlayerComplete.listen((_) {
|
||||||
if (track?.id != null) {
|
if (track?.id != null) {
|
||||||
seekForward();
|
if (isLoop) {
|
||||||
|
final prevTrack = track;
|
||||||
|
track = null;
|
||||||
|
play(prevTrack!);
|
||||||
|
} else if (playlist != null) {
|
||||||
|
seekForward();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
status = PlaybackStatus.idle;
|
status = PlaybackStatus.idle;
|
||||||
@ -250,12 +262,26 @@ class Playback extends PersistedChangeNotifier {
|
|||||||
isPlaying ? await pause() : await resume();
|
isPlaying ? await pause() : await resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleShuffle() {
|
void cyclePlaybackMode() {
|
||||||
final result = isShuffled ? playlist?.unshuffle() : playlist?.shuffle();
|
switch (playbackMode) {
|
||||||
if (result == true) {
|
case PlaybackMode.normal:
|
||||||
isShuffled = !isShuffled;
|
playbackMode = PlaybackMode.shuffle;
|
||||||
notifyListeners();
|
playlist?.shuffle();
|
||||||
|
break;
|
||||||
|
case PlaybackMode.shuffle:
|
||||||
|
playbackMode = PlaybackMode.repeat;
|
||||||
|
playlist?.unshuffle();
|
||||||
|
break;
|
||||||
|
case PlaybackMode.repeat:
|
||||||
|
playbackMode = PlaybackMode.normal;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
notifyListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlaybackMode(PlaybackMode mode) {
|
||||||
|
playbackMode = mode;
|
||||||
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> seekPosition(Duration position) {
|
Future<void> seekPosition(Duration position) {
|
||||||
@ -273,7 +299,7 @@ class Playback extends PersistedChangeNotifier {
|
|||||||
await player.stop();
|
await player.stop();
|
||||||
await player.release();
|
await player.release();
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
isShuffled = false;
|
playbackMode = PlaybackMode.normal;
|
||||||
playlist = null;
|
playlist = null;
|
||||||
track = null;
|
track = null;
|
||||||
status = PlaybackStatus.idle;
|
status = PlaybackStatus.idle;
|
||||||
@ -553,6 +579,10 @@ class Playback extends PersistedChangeNotifier {
|
|||||||
"volume": volume,
|
"volume": volume,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get isLoop => playbackMode == PlaybackMode.repeat;
|
||||||
|
bool get isShuffled => playbackMode == PlaybackMode.shuffle;
|
||||||
|
bool get isNormal => playbackMode == PlaybackMode.normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
final playbackProvider = ChangeNotifierProvider<Playback>((ref) {
|
final playbackProvider = ChangeNotifierProvider<Playback>((ref) {
|
||||||
|
@ -275,7 +275,9 @@ class _MprisMediaPlayer2Player extends DBusObject {
|
|||||||
|
|
||||||
/// Sets property org.mpris.MediaPlayer2.Player.Shuffle
|
/// Sets property org.mpris.MediaPlayer2.Player.Shuffle
|
||||||
Future<DBusMethodResponse> setShuffle(bool value) async {
|
Future<DBusMethodResponse> setShuffle(bool value) async {
|
||||||
playback.toggleShuffle();
|
playback.setPlaybackMode(
|
||||||
|
value ? PlaybackMode.shuffle : PlaybackMode.normal,
|
||||||
|
);
|
||||||
return DBusMethodSuccessResponse();
|
return DBusMethodSuccessResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user