mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-05-08 16:24:36 +00:00
feat: use provider in add track dialog
This commit is contained in:
parent
82802fef2c
commit
d2a9ff6652
@ -1,4 +1,3 @@
|
||||
import 'package:fl_query_hooks/fl_query_hooks.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
@ -8,8 +7,7 @@ import 'package:spotify/spotify.dart';
|
||||
import 'package:spotube/components/playlist/playlist_create_dialog.dart';
|
||||
import 'package:spotube/components/shared/image/universal_image.dart';
|
||||
import 'package:spotube/extensions/context.dart';
|
||||
import 'package:spotube/provider/spotify_provider.dart';
|
||||
import 'package:spotube/services/queries/queries.dart';
|
||||
import 'package:spotube/provider/spotify/spotify.dart';
|
||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||
|
||||
class PlaylistAddTrackDialog extends HookConsumerWidget {
|
||||
@ -25,27 +23,34 @@ class PlaylistAddTrackDialog extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, ref) {
|
||||
final ThemeData(:textTheme) = Theme.of(context);
|
||||
final spotify = ref.watch(spotifyProvider);
|
||||
final userPlaylists = useQueries.playlist.ofMineAll(ref);
|
||||
final userPlaylists = ref.watch(favoritePlaylistsProvider);
|
||||
final favoritePlaylistsNotifier =
|
||||
ref.watch(favoritePlaylistsProvider.notifier);
|
||||
|
||||
final me = useQueries.user.me(ref);
|
||||
final me = ref.watch(meProvider);
|
||||
|
||||
final filteredPlaylists = useMemoized(
|
||||
() =>
|
||||
userPlaylists.data
|
||||
?.where(
|
||||
userPlaylists.asData?.value.items
|
||||
.where(
|
||||
(playlist) =>
|
||||
playlist.owner?.id != null &&
|
||||
playlist.owner!.id == me.data?.id &&
|
||||
playlist.owner!.id == me.asData?.value.id &&
|
||||
playlist.id != openFromPlaylist,
|
||||
)
|
||||
.toList() ??
|
||||
[],
|
||||
[userPlaylists.data, me.data?.id, openFromPlaylist],
|
||||
[userPlaylists.asData?.value, me.asData?.value.id, openFromPlaylist],
|
||||
);
|
||||
|
||||
final playlistsCheck = useState(<String, bool>{});
|
||||
final queryClient = useQueryClient();
|
||||
|
||||
useEffect(() {
|
||||
if (userPlaylists.asData?.value != null) {
|
||||
favoritePlaylistsNotifier.fetchAll();
|
||||
}
|
||||
return null;
|
||||
}, [userPlaylists.asData?.value]);
|
||||
|
||||
Future<void> onAdd() async {
|
||||
final selectedPlaylists = playlistsCheck.value.entries
|
||||
@ -54,21 +59,12 @@ class PlaylistAddTrackDialog extends HookConsumerWidget {
|
||||
|
||||
await Future.wait(
|
||||
selectedPlaylists.map(
|
||||
(playlistId) => spotify.playlists.addTracks(
|
||||
tracks
|
||||
.map(
|
||||
(track) => track.uri!,
|
||||
)
|
||||
.toList(),
|
||||
playlistId),
|
||||
(playlistId) => favoritePlaylistsNotifier.addTracks(
|
||||
playlistId,
|
||||
tracks.map((e) => e.id!).toList(),
|
||||
),
|
||||
),
|
||||
).then((_) => Navigator.pop(context, true));
|
||||
|
||||
await queryClient.refreshQueries(
|
||||
selectedPlaylists
|
||||
.map((playlistId) => "playlist-tracks/$playlistId")
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
return AlertDialog(
|
||||
|
||||
@ -72,6 +72,19 @@ class FavoritePlaylistsNotifier
|
||||
|
||||
ref.invalidate(isFavoritePlaylistProvider(playlist.id!));
|
||||
}
|
||||
|
||||
Future<void> addTracks(String playlistId, 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(),
|
||||
playlistId,
|
||||
);
|
||||
|
||||
ref.invalidate(playlistTracksProvider(playlistId));
|
||||
}
|
||||
}
|
||||
|
||||
final favoritePlaylistsProvider =
|
||||
@ -79,13 +92,6 @@ final favoritePlaylistsProvider =
|
||||
() => FavoritePlaylistsNotifier(),
|
||||
);
|
||||
|
||||
final allFavoritePlaylistsProvider = FutureProvider<List<PlaylistSimple>>(
|
||||
(ref) async {
|
||||
final spotify = ref.watch(spotifyProvider);
|
||||
return (await spotify.playlists.me.all()).toList();
|
||||
},
|
||||
);
|
||||
|
||||
final isFavoritePlaylistProvider = FutureProvider.family<bool, String>(
|
||||
(ref, id) async {
|
||||
final spotify = ref.watch(spotifyProvider);
|
||||
|
||||
@ -16,7 +16,7 @@ class PlaylistNotifier extends FamilyAsyncNotifier<Playlist, String> {
|
||||
}
|
||||
|
||||
Future<void> create(PlaylistInput input, [ValueChanged? onError]) async {
|
||||
if (state is AsyncData || state is AsyncLoading) return;
|
||||
if (state is AsyncLoading) return;
|
||||
state = const AsyncLoading();
|
||||
|
||||
final spotify = ref.read(spotifyProvider);
|
||||
@ -51,19 +51,6 @@ class PlaylistNotifier extends FamilyAsyncNotifier<Playlist, String> {
|
||||
ref.invalidate(favoritePlaylistsProvider);
|
||||
}
|
||||
|
||||
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.invalidate(playlistTracksProvider(state.value!.id!));
|
||||
}
|
||||
|
||||
Future<void> modify(PlaylistInput input, [ValueChanged? onError]) async {
|
||||
if (state.value == null) return;
|
||||
|
||||
|
||||
@ -23,6 +23,30 @@ abstract class PaginatedAsyncNotifier<K, T extends BasePaginatedState<K, int>>
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<K>> fetchAll() async {
|
||||
if (state.value == null) return [];
|
||||
if (!state.value!.hasMore) return state.value!.items;
|
||||
|
||||
bool hasMore = true;
|
||||
while (hasMore) {
|
||||
await update((state) async {
|
||||
final items = await fetch(
|
||||
state.offset + state.limit,
|
||||
state.limit,
|
||||
);
|
||||
|
||||
hasMore = items.length == state.limit;
|
||||
return state.copyWith(
|
||||
items: [...state.items, ...items],
|
||||
offset: state.offset + state.limit,
|
||||
hasMore: hasMore,
|
||||
) as T;
|
||||
});
|
||||
}
|
||||
|
||||
return state.value!.items;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class CursorPaginatedAsyncNotifier<K,
|
||||
@ -49,6 +73,27 @@ abstract class CursorPaginatedAsyncNotifier<K,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<List<K>> fetchAll() async {
|
||||
if (state.value == null) return [];
|
||||
if (!state.value!.hasMore) return state.value!.items;
|
||||
|
||||
bool hasMore = true;
|
||||
while (hasMore) {
|
||||
await update((state) async {
|
||||
final items = await fetch(state.offset, state.limit);
|
||||
|
||||
hasMore = items.$1.length == state.limit;
|
||||
return state.copyWith(
|
||||
items: [...state.items, ...items.$1],
|
||||
offset: items.$2,
|
||||
hasMore: hasMore,
|
||||
) as T;
|
||||
});
|
||||
}
|
||||
|
||||
return state.value!.items;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class FamilyPaginatedAsyncNotifier<
|
||||
|
||||
Loading…
Reference in New Issue
Block a user