import 'package:collection/collection.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/extensions/track.dart'; import 'package:spotube/models/local_track.dart'; import 'package:spotube/models/spotube_track.dart'; class ProxyPlaylist { final Set tracks; final Set collections; final int? active; ProxyPlaylist(this.tracks, [this.active, this.collections = const {}]); factory ProxyPlaylist.fromJson(Map json) { return ProxyPlaylist( List.castFrom>( json['tracks'] ?? >[], ).map(_makeAppropriateTrack).toSet(), json['active'] as int?, json['collections'] == null ? {} : (json['collections'] as List).toSet().cast(), ); } Track? get activeTrack => active == null || active == -1 ? null : tracks.elementAtOrNull(active!); bool get isFetching => activeTrack != null && activeTrack is! SpotubeTrack && activeTrack is! LocalTrack; bool containsCollection(String collection) { return collections.contains(collection); } bool containsTrack(TrackSimple track) { return tracks.firstWhereOrNull((element) => element.id == track.id) != null; } bool containsTracks(Iterable tracks) { if (tracks.isEmpty) return false; return tracks.every(containsTrack); } static Track _makeAppropriateTrack(Map track) { if (track.containsKey("ytUri")) { return SpotubeTrack.fromJson(track); } else if (track.containsKey("path")) { return LocalTrack.fromJson(track); } else { return Track.fromJson(track); } } static Map _makeAppropriateTrackJson(Track track) { if (track is LocalTrack) { return track.toJson(); } else { return track.toJson(); } } Map toJson() { return { 'tracks': tracks.map(_makeAppropriateTrackJson).toList(), 'active': active, 'collections': collections.toList(), }; } ProxyPlaylist copyWith({ Set? tracks, int? active, Set? collections, }) { return ProxyPlaylist( tracks ?? this.tracks, active ?? this.active, collections ?? this.collections, ); } }