diff --git a/lib/components/root/bottom_player.dart b/lib/components/root/bottom_player.dart index 70d14f8a3..5a09ffa5e 100644 --- a/lib/components/root/bottom_player.dart +++ b/lib/components/root/bottom_player.dart @@ -1,6 +1,5 @@ import 'dart:ui'; -import 'package:flutter/gestures.dart'; import 'package:flutter_desktop_tools/flutter_desktop_tools.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:go_router/go_router.dart'; @@ -18,9 +17,9 @@ import 'package:spotube/extensions/context.dart'; import 'package:spotube/hooks/use_brightness_value.dart'; import 'package:spotube/models/logger.dart'; import 'package:flutter/material.dart'; +import 'package:spotube/provider/authentication_provider.dart'; import 'package:spotube/provider/proxy_playlist/proxy_playlist_provider.dart'; import 'package:spotube/provider/user_preferences_provider.dart'; -import 'package:spotube/provider/volume_provider.dart'; import 'package:spotube/utils/platform.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; @@ -30,6 +29,7 @@ class BottomPlayer extends HookConsumerWidget { final logger = getLogger(BottomPlayer); @override Widget build(BuildContext context, ref) { + final auth = ref.watch(AuthenticationNotifier.provider); final playlist = ref.watch(ProxyPlaylistNotifier.provider); final layoutMode = ref.watch(userPreferencesProvider.select((s) => s.layoutMode)); @@ -87,29 +87,30 @@ class BottomPlayer extends HookConsumerWidget { children: [ PlayerActions( extraActions: [ - IconButton( - tooltip: context.l10n.mini_player, - icon: const Icon(SpotubeIcons.miniPlayer), - onPressed: () async { - await DesktopTools.window.setMinimumSize( - const Size(300, 300), - ); - await DesktopTools.window.setAlwaysOnTop(true); - if (!kIsLinux) { - await DesktopTools.window.setHasShadow(false); - } - await DesktopTools.window - .setAlignment(Alignment.topRight); - await DesktopTools.window - .setSize(const Size(400, 500)); - await Future.delayed( - const Duration(milliseconds: 100), - () async { - GoRouter.of(context).go('/mini-player'); - }, - ); - }, - ), + if (auth != null) + IconButton( + tooltip: context.l10n.mini_player, + icon: const Icon(SpotubeIcons.miniPlayer), + onPressed: () async { + await DesktopTools.window.setMinimumSize( + const Size(300, 300), + ); + await DesktopTools.window.setAlwaysOnTop(true); + if (!kIsLinux) { + await DesktopTools.window.setHasShadow(false); + } + await DesktopTools.window + .setAlignment(Alignment.topRight); + await DesktopTools.window + .setSize(const Size(400, 500)); + await Future.delayed( + const Duration(milliseconds: 100), + () async { + GoRouter.of(context).go('/mini-player'); + }, + ); + }, + ), ], ), Container( diff --git a/lib/provider/proxy_playlist/proxy_playlist_provider.dart b/lib/provider/proxy_playlist/proxy_playlist_provider.dart index 8de5c7d2f..dee903ec2 100644 --- a/lib/provider/proxy_playlist/proxy_playlist_provider.dart +++ b/lib/provider/proxy_playlist/proxy_playlist_provider.dart @@ -19,19 +19,19 @@ import 'package:spotube/provider/piped_provider.dart'; import 'package:spotube/utils/persisted_state_notifier.dart'; import 'package:spotube/utils/type_conversion_utils.dart'; -/// Things to implement: +/// Things implemented: /// * [x] Sponsor-Block skip /// * [x] Prefetch next track as [SpotubeTrack] on 80% of current track /// * [x] Mixed Queue containing both [SpotubeTrack] and [LocalTrack] -/// * [ ] Modification of the Queue +/// * [x] Modification of the Queue /// * [x] Add track at the end /// * [x] Add track at the beginning /// * [x] Remove track -/// * [ ] Reorder track +/// * [x] Reorder track /// * [x] Caching and loading of cache of tracks /// * [x] Shuffling /// * [x] loop => playlist, track, none -/// * [ ] Alternative Track Source +/// * [x] Alternative Track Source /// * [x] Blacklisting of tracks and artist /// /// Don'ts: diff --git a/lib/services/audio_player/mk_state_player.dart b/lib/services/audio_player/mk_state_player.dart index b7732f1a8..053cd89fc 100644 --- a/lib/services/audio_player/mk_state_player.dart +++ b/lib/services/audio_player/mk_state_player.dart @@ -216,20 +216,32 @@ class MkPlayerWithState extends Player { /// This replaces the old source with a new one /// + /// If the old source is playing, the new one will play + /// from the beginning + /// /// This doesn't work when [playlist] is null - /// Or, when the current media is the one to be replaced void replace(String oldUrl, String newUrl) { - if (_playlist == null || - _playlist!.medias[_playlist!.index].uri == oldUrl) { + if (_playlist == null) { return; } + final isOldUrlPlaying = _playlist!.medias[_playlist!.index].uri == oldUrl; + for (var i = 0; i < _playlist!.medias.length - 1; i++) { final media = _playlist!.medias[i]; if (media.uri == oldUrl) { + if (isOldUrlPlaying) { + pause(); + } final newMedias = _playlist!.medias.toList(); newMedias[i] = Media(newUrl, extras: media.extras); playlist = _playlist!.copyWith(medias: newMedias); + if (isOldUrlPlaying) { + super.open( + newMedias[i], + play: true, + ); + } break; } }