chore: fix use SpotubeMedia to avoid duplicate sourceTrackProvider instances

This commit is contained in:
Kingkor Roy Tirtho 2024-06-25 20:36:23 +06:00
parent 1b420e661b
commit 6c5cab9899
7 changed files with 47 additions and 17 deletions

View File

@ -86,6 +86,7 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
)
.toList(),
initialIndex: playlist.index,
autoPlay: false,
);
}
}
@ -270,17 +271,18 @@ class AudioPlayerNotifier extends Notifier<AudioPlayerState> {
int initialIndex = 0,
bool autoPlay = false,
}) async {
tracks = _blacklist.filter(tracks).toList() as List<Track>;
final medias =
(_blacklist.filter(tracks).toList() as List<Track>).asMediaList();
// Giving the initial track a boost so MediaKit won't skip
// because of timeout
final intendedActiveTrack = tracks.elementAt(initialIndex);
final intendedActiveTrack = medias.elementAt(initialIndex);
if (intendedActiveTrack is! LocalTrack) {
await ref.read(sourcedTrackProvider(intendedActiveTrack).future);
}
await audioPlayer.openPlaylist(
tracks.asMediaList(),
medias,
initialIndex: initialIndex,
autoPlay: autoPlay,
);

View File

@ -128,15 +128,17 @@ class AudioPlayerStreamListeners {
audioPlayerState.tracks.length - 1) {
return;
}
final nextTrack = audioPlayerState.tracks
.elementAt(audioPlayerState.playlist.index + 1);
final nextTrack = SpotubeMedia.fromMedia(audioPlayerState.playlist.medias
.elementAt(audioPlayerState.playlist.index + 1));
if (lastTrack == nextTrack.id || nextTrack is LocalTrack) return;
if (lastTrack == nextTrack.track.id || nextTrack.track is LocalTrack) {
return;
}
try {
await ref.read(sourcedTrackProvider(nextTrack).future);
} finally {
lastTrack = nextTrack.id!;
lastTrack = nextTrack.track.id!;
}
});
}

View File

@ -4,17 +4,21 @@ import 'package:spotube/provider/server/sourced_track.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
final queryingTrackInfoProvider = Provider<bool>((ref) {
final media = audioPlayer.playlist.index == -1
final media = audioPlayer.playlist.index == -1 ||
audioPlayer.playlist.medias.isEmpty
? null
: audioPlayer.playlist.medias.elementAtOrNull(audioPlayer.playlist.index);
final audioPlayerActiveTrack =
media == null ? null : SpotubeMedia.fromMedia(media).track;
media == null ? null : SpotubeMedia.fromMedia(media);
final activeTrack =
ref.watch(audioPlayerProvider.select((s) => s.activeTrack)) ??
final activeMedia = ref.watch(audioPlayerProvider.select(
(s) => s.activeMedia == null
? null
: SpotubeMedia.fromMedia(s.activeMedia!),
)) ??
audioPlayerActiveTrack;
if (activeTrack == null) return false;
if (activeMedia == null) return false;
return ref.watch(sourcedTrackProvider(activeTrack)).isLoading;
return ref.watch(sourcedTrackProvider(activeMedia)).isLoading;
});

View File

@ -88,6 +88,11 @@ class AudioPlayerState {
return tracks.elementAtOrNull(playlist.index);
}
Media? get activeMedia {
if (playlist.index == -1 || playlist.medias.isEmpty) return null;
return playlist.medias.elementAt(playlist.index);
}
bool containsTrack(Track track) {
return tracks.any((t) => t.id == track.id);
}

View File

@ -7,6 +7,7 @@ import 'package:spotube/provider/audio_player/state.dart';
import 'package:spotube/provider/server/active_sourced_track.dart';
import 'package:spotube/provider/server/sourced_track.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/logger/logger.dart';
class ServerPlaybackRoutes {
@ -25,7 +26,7 @@ class ServerPlaybackRoutes {
final activeSourcedTrack = ref.read(activeSourcedTrackProvider);
final sourcedTrack = activeSourcedTrack?.id == track.id
? activeSourcedTrack
: await ref.read(sourcedTrackProvider(track).future);
: await ref.read(sourcedTrackProvider(SpotubeMedia(track)).future);
ref.read(activeSourcedTrackProvider.notifier).update(sourcedTrack);

View File

@ -1,12 +1,13 @@
import 'package:collection/collection.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/models/local_track.dart';
import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/services/audio_player/audio_player.dart';
import 'package:spotube/services/sourced_track/sourced_track.dart';
final sourcedTrackProvider =
FutureProvider.family<SourcedTrack?, Track?>((ref, track) async {
FutureProvider.family<SourcedTrack?, SpotubeMedia?>((ref, media) async {
final track = media?.track;
if (track == null || track is LocalTrack) {
return null;
}

View File

@ -54,6 +54,21 @@ class SpotubeMedia extends mk.Media {
httpHeaders: media.httpHeaders,
);
}
@override
operator ==(Object other) {
if (other is! SpotubeMedia) return false;
final isLocal = track is LocalTrack && other.track is LocalTrack;
return isLocal
? (other.track as LocalTrack).path == (track as LocalTrack).path
: other.track.id == track.id;
}
@override
int get hashCode => track is LocalTrack
? (track as LocalTrack).path.hashCode
: track.id.hashCode;
}
abstract class AudioPlayerInterface {