mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-05-08 16:24:36 +00:00
feat: add playlist create and update and favorite handlers
This commit is contained in:
parent
f8550ae3d6
commit
f83d6e08e1
@ -41,12 +41,11 @@ class FavoriteAlbumNotifier
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> saveAlbums(List<String> ids) async {
|
Future<void> addFavorites(List<String> ids) async {
|
||||||
if (state.value == null) return;
|
if (state.value == null) return;
|
||||||
|
|
||||||
await spotify.me.saveAlbums(ids);
|
|
||||||
|
|
||||||
state = await AsyncValue.guard(() async {
|
state = await AsyncValue.guard(() async {
|
||||||
|
await spotify.me.saveAlbums(ids);
|
||||||
final albums = await spotify.albums.list(ids);
|
final albums = await spotify.albums.list(ids);
|
||||||
|
|
||||||
return state.value!.copyWith(
|
return state.value!.copyWith(
|
||||||
@ -57,6 +56,20 @@ class FavoriteAlbumNotifier
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> removeFavorites(List<String> ids) async {
|
||||||
|
if (state.value == null) return;
|
||||||
|
|
||||||
|
state = await AsyncValue.guard(() async {
|
||||||
|
await spotify.me.removeAlbums(ids);
|
||||||
|
|
||||||
|
return state.value!.copyWith(
|
||||||
|
items: state.value!.items
|
||||||
|
.where((element) => !ids.contains(element.id))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final favoriteAlbumsProvider =
|
final favoriteAlbumsProvider =
|
||||||
|
|||||||
@ -50,6 +50,24 @@ class FavoritePlaylistsNotifier
|
|||||||
hasMore: playlists.length == 20,
|
hasMore: playlists.length == 20,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> addFavorite(PlaylistSimple playlist) async {
|
||||||
|
update((state) async {
|
||||||
|
await spotify.playlists.followPlaylist(playlist.id!);
|
||||||
|
return state.copyWith(
|
||||||
|
items: [...state.items, playlist],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> removeFavorite(PlaylistSimple playlist) async {
|
||||||
|
update((state) async {
|
||||||
|
await spotify.playlists.unfollowPlaylist(playlist.id!);
|
||||||
|
return state.copyWith(
|
||||||
|
items: state.items.where((e) => e.id != playlist.id).toList(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final favoritePlaylistsProvider =
|
final favoritePlaylistsProvider =
|
||||||
|
|||||||
@ -1,8 +1,49 @@
|
|||||||
part of '../spotify.dart';
|
part of '../spotify.dart';
|
||||||
|
|
||||||
final likedTracksProvider = FutureProvider<List<Track>>((ref) async {
|
class LikedTracksNotifier extends AsyncNotifier<List<Track>> with Persistence {
|
||||||
|
LikedTracksNotifier() {
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<List<Track>> build() async {
|
||||||
final spotify = ref.watch(spotifyProvider);
|
final spotify = ref.watch(spotifyProvider);
|
||||||
final savedTracked = await spotify.tracks.me.saved.all();
|
final savedTracked = await spotify.tracks.me.saved.all();
|
||||||
|
|
||||||
return savedTracked.map((e) => e.track!).toList();
|
return savedTracked.map((e) => e.track!).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> toggleFavorite(Track track) async {
|
||||||
|
if (state.value == null) return;
|
||||||
|
final spotify = ref.read(spotifyProvider);
|
||||||
|
|
||||||
|
await update((tracks) async {
|
||||||
|
final isLiked = tracks.map((e) => e.id).contains(track.id);
|
||||||
|
|
||||||
|
if (isLiked) {
|
||||||
|
await spotify.tracks.me.removeOne(track.id!);
|
||||||
|
return tracks.where((e) => e.id != track.id).toList();
|
||||||
|
} else {
|
||||||
|
await spotify.tracks.me.saveOne(track.id!);
|
||||||
|
return [...tracks, track];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<List<Track>> fromJson(Map<String, dynamic> json) {
|
||||||
|
return (json['tracks'] as List).map((e) => Track.fromJson(e)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson(List<Track> data) {
|
||||||
|
return {
|
||||||
|
'tracks': data.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final likedTracksProvider =
|
||||||
|
AsyncNotifierProvider<LikedTracksNotifier, List<Track>>(
|
||||||
|
() => LikedTracksNotifier(),
|
||||||
|
);
|
||||||
|
|||||||
@ -1,8 +1,89 @@
|
|||||||
part of '../spotify.dart';
|
part of '../spotify.dart';
|
||||||
|
|
||||||
final playlistProvider = FutureProvider.family<Playlist, String>(
|
typedef PlaylistInput = ({
|
||||||
(ref, playlistId) async {
|
String playlistName,
|
||||||
|
bool? public,
|
||||||
|
bool? collaborative,
|
||||||
|
String? description,
|
||||||
|
String? base64Image,
|
||||||
|
});
|
||||||
|
|
||||||
|
class PlaylistNotifier extends FamilyAsyncNotifier<Playlist, String> {
|
||||||
|
@override
|
||||||
|
FutureOr<Playlist> build(String arg) {
|
||||||
final spotify = ref.watch(spotifyProvider);
|
final spotify = ref.watch(spotifyProvider);
|
||||||
return spotify.playlists.get(playlistId);
|
return spotify.playlists.get(arg);
|
||||||
},
|
}
|
||||||
|
|
||||||
|
Future<void> create(PlaylistInput input) async {
|
||||||
|
if (state is AsyncData || state is AsyncLoading) return;
|
||||||
|
state = const AsyncLoading();
|
||||||
|
|
||||||
|
final spotify = ref.read(spotifyProvider);
|
||||||
|
final me = ref.read(meProvider);
|
||||||
|
|
||||||
|
if (me.value == null) return;
|
||||||
|
|
||||||
|
state = await AsyncValue.guard(() async {
|
||||||
|
final playlist = await spotify.playlists.createPlaylist(
|
||||||
|
me.value!.id!,
|
||||||
|
input.playlistName,
|
||||||
|
collaborative: input.collaborative,
|
||||||
|
description: input.description,
|
||||||
|
public: input.public,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (input.base64Image != null) {
|
||||||
|
await spotify.playlists.updatePlaylistImage(
|
||||||
|
playlist.id!,
|
||||||
|
input.base64Image!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return playlist;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> addTracks(List<String> trackIds) async {
|
||||||
|
if (state.value == null) return;
|
||||||
|
|
||||||
|
final spotify = ref.read(spotifyProvider);
|
||||||
|
|
||||||
|
await spotify.playlists.addTracks(
|
||||||
|
trackIds.map((id) => 'spotify:track:$id').toList(),
|
||||||
|
state.value!.id!,
|
||||||
|
);
|
||||||
|
|
||||||
|
ref.refresh(playlistTracksProvider(state.value!.id!));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> modify(PlaylistInput input) async {
|
||||||
|
if (state.value == null) return;
|
||||||
|
|
||||||
|
final spotify = ref.read(spotifyProvider);
|
||||||
|
|
||||||
|
await update((state) async {
|
||||||
|
await spotify.playlists.updatePlaylist(
|
||||||
|
state.id!,
|
||||||
|
input.playlistName,
|
||||||
|
collaborative: input.collaborative,
|
||||||
|
description: input.description,
|
||||||
|
public: input.public,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (input.base64Image != null) {
|
||||||
|
await spotify.playlists.updatePlaylistImage(
|
||||||
|
state.id!,
|
||||||
|
input.base64Image!,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return spotify.playlists.get(state.id!);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final playlistProvider =
|
||||||
|
AsyncNotifierProvider.family<PlaylistNotifier, String, PlaylistNotifier>(
|
||||||
|
() => PlaylistNotifier(),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
// ignore: depend_on_referenced_packages, implementation_imports
|
// ignore: depend_on_referenced_packages, implementation_imports
|
||||||
import 'package:riverpod/src/async_notifier.dart';
|
import 'package:riverpod/src/async_notifier.dart';
|
||||||
import 'package:spotube/extensions/map.dart';
|
import 'package:spotube/extensions/map.dart';
|
||||||
|
import 'package:spotube/extensions/track.dart';
|
||||||
import 'package:spotube/models/lyrics.dart';
|
import 'package:spotube/models/lyrics.dart';
|
||||||
import 'package:spotube/models/spotify/recommendation_seeds.dart';
|
import 'package:spotube/models/spotify/recommendation_seeds.dart';
|
||||||
import 'package:spotube/models/spotify_friends.dart';
|
import 'package:spotube/models/spotify_friends.dart';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user