import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:spotube/models/metadata/metadata.dart'; import 'package:spotube/provider/metadata_plugin/core/auth.dart'; import 'package:spotube/provider/metadata_plugin/utils/common.dart'; import 'package:spotube/provider/metadata_plugin/utils/paginated.dart'; class MetadataPluginSavedTracksNotifier extends AutoDisposePaginatedAsyncNotifier { MetadataPluginSavedTracksNotifier() : super(); @override fetch(offset, limit) async { final tracks = await (await metadataPlugin).user.savedTracks( offset: offset, limit: limit, ); return tracks; } @override build() async { ref.cacheFor(); await ref.watch(metadataPluginAuthenticatedProvider.future); return await fetch(0, 20); } Future addFavorite(List tracks) async { if (state.value == null) { return; } final oldState = state.value; state = AsyncData( state.value!.copyWith( items: [ ...tracks.whereType(), ...state.value!.items ], ), ); try { await (await metadataPlugin).track.save(tracks.map((e) => e.id).toList()); } catch (e) { state = AsyncData(oldState!); rethrow; } } Future removeFavorite(List tracks) async { if (state.value == null) { return; } final oldState = state.value; state = AsyncData( state.value!.copyWith( items: state.value!.items .where( (savedTrack) => !tracks.any((track) => track.id == savedTrack.id), ) .toList(), ), ); try { await (await metadataPlugin) .track .unsave(tracks.map((e) => e.id).toList()); } catch (e) { state = AsyncData(oldState!); rethrow; } } } final metadataPluginSavedTracksProvider = AutoDisposeAsyncNotifierProvider< MetadataPluginSavedTracksNotifier, SpotubePaginationResponseObject>( () => MetadataPluginSavedTracksNotifier(), ); final metadataPluginIsSavedTrackProvider = FutureProvider.autoDispose.family( (ref, trackId) async { final savedTracks = await ref.watch(metadataPluginSavedTracksProvider.future); final allSavedTracks = savedTracks.hasMore ? await ref.read(metadataPluginSavedTracksProvider.notifier).fetchAll() : savedTracks.items; return allSavedTracks.any((track) => track.id == trackId); }, );