diff --git a/lib/components/track_tile/track_options.dart b/lib/components/track_tile/track_options.dart index 7d14493e..075010b1 100644 --- a/lib/components/track_tile/track_options.dart +++ b/lib/components/track_tile/track_options.dart @@ -89,7 +89,7 @@ class TrackOptions extends HookConsumerWidget { ], ), ), - if (!isInQueue) ...[ + if (!isInQueue) ButtonTile( style: ButtonVariance.menu, onPressed: () async { @@ -102,21 +102,8 @@ class TrackOptions extends HookConsumerWidget { }, leading: const Icon(SpotubeIcons.queueAdd), title: Text(context.l10n.add_to_queue), - ), - ButtonTile( - style: ButtonVariance.menu, - onPressed: () async { - await trackOptionActions.action( - rootNavigatorKey.currentContext!, - TrackOptionValue.playNext, - playlistId, - ); - onTapItem?.call(); - }, - leading: const Icon(SpotubeIcons.lightning), - title: Text(context.l10n.play_next), - ), - ] else + ) + else ButtonTile( style: ButtonVariance.menu, onPressed: () async { @@ -131,6 +118,19 @@ class TrackOptions extends HookConsumerWidget { leading: const Icon(SpotubeIcons.queueRemove), title: Text(context.l10n.remove_from_queue), ), + ButtonTile( + style: ButtonVariance.menu, + onPressed: () async { + await trackOptionActions.action( + rootNavigatorKey.currentContext!, + TrackOptionValue.playNext, + playlistId, + ); + onTapItem?.call(); + }, + leading: const Icon(SpotubeIcons.lightning), + title: Text(context.l10n.play_next), + ), if (isAuthenticated && !isLocalTrack) ButtonTile( style: ButtonVariance.menu, diff --git a/lib/provider/audio_player/audio_player.dart b/lib/provider/audio_player/audio_player.dart index 66878714..e590825a 100644 --- a/lib/provider/audio_player/audio_player.dart +++ b/lib/provider/audio_player/audio_player.dart @@ -228,24 +228,32 @@ class AudioPlayerNotifier extends Notifier { final addableTracks = _blacklist .filter(tracks) - .where( - (track) => - allowDuplicates || - !state.tracks.any((element) => _compareTracks(element, track)), - ) .toList(); - state = state.copyWith( - tracks: [...addableTracks, ...state.tracks], - ); - for (int i = 0; i < addableTracks.length; i++) { final track = addableTracks.elementAt(i); - await audioPlayer.addTrackAt( - SpotubeMedia(track), - max(state.currentIndex, 0) + i + 1, - ); + final (currentTrackIndex, _) = state.tracks + .indexed + .cast<(int, SpotubeTrackObject?)>() + .firstWhere( + (record) { + final (idx, element) = record; + return _compareTracks(element!, track); + }, + orElse: () => (-1, null) + ); + + final newIndex = max(state.currentIndex, 0) + i + 1; + + if (allowDuplicates || currentTrackIndex < 0) { + await audioPlayer.addTrackAt( + SpotubeMedia(track), + newIndex + ); + } else { + await audioPlayer.moveTrack(currentTrackIndex, newIndex); + } } await _updatePlayerState(