import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/entities/user.entity.dart'; import 'package:immich_mobile/models/albums/album_search.model.dart'; import 'package:immich_mobile/services/album.service.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/entities/album.entity.dart'; final isRefreshingRemoteAlbumProvider = StateProvider((ref) => false); class AlbumNotifier extends StateNotifier> { AlbumNotifier(this.albumService, this.ref) : super([]) { albumService.getAllRemoteAlbums().then((value) { if (mounted) { state = value; } }); _streamSub = albumService.watchRemoteAlbums().listen((data) => state = data); } final AlbumService albumService; final Ref ref; late final StreamSubscription> _streamSub; Future refreshRemoteAlbums() async { ref.read(isRefreshingRemoteAlbumProvider.notifier).state = true; await albumService.refreshRemoteAlbums(); ref.read(isRefreshingRemoteAlbumProvider.notifier).state = false; } Future refreshDeviceAlbums() => albumService.refreshDeviceAlbums(); Future deleteAlbum(Album album) => albumService.deleteAlbum(album); Future createAlbum( String albumTitle, Set assets, ) => albumService.createAlbum(albumTitle, assets, []); Future getAlbumByName( String albumName, { bool? remote, bool? shared, bool? owner, }) => albumService.getAlbumByName( albumName, remote: remote, shared: shared, owner: owner, ); /// Create an album on the server with the same name as the selected album for backup /// First this will check if the album already exists on the server with name /// If it does not exist, it will create the album on the server Future createSyncAlbum( String albumName, ) async { final album = await getAlbumByName(albumName, remote: true, owner: true); if (album != null) { return; } await createAlbum(albumName, {}); } Future leaveAlbum(Album album) async { var res = await albumService.leaveAlbum(album); if (res) { await deleteAlbum(album); return true; } else { return false; } } void searchAlbums(String searchTerm, QuickFilterMode filterMode) async { state = await albumService.search(searchTerm, filterMode); } Future addUsers(Album album, List userIds) async { await albumService.addUsers(album, userIds); } Future removeUser(Album album, User user) async { final isRemoved = await albumService.removeUser(album, user); if (isRemoved && album.sharedUsers.isEmpty) { state = state.where((element) => element.id != album.id).toList(); } return isRemoved; } Future addAssets(Album album, Iterable assets) async { await albumService.addAssets(album, assets); } Future removeAsset(Album album, Iterable assets) async { return await albumService.removeAsset(album, assets); } Future setActivitystatus( Album album, bool enabled, ) { return albumService.setActivityStatus(album, enabled); } Future toggleSortOrder(Album album) { final order = album.sortOrder == SortOrder.asc ? SortOrder.desc : SortOrder.asc; return albumService.updateSortOrder(album, order); } @override void dispose() { _streamSub.cancel(); super.dispose(); } } final albumProvider = StateNotifierProvider.autoDispose>((ref) { return AlbumNotifier( ref.watch(albumServiceProvider), ref, ); }); final albumWatcher = StreamProvider.autoDispose.family((ref, id) async* { final albumService = ref.watch(albumServiceProvider); final album = await albumService.getAlbumById(id); if (album != null) { yield album; } await for (final album in albumService.watchAlbum(id)) { if (album != null) { yield album; } } }); class LocalAlbumsNotifier extends StateNotifier> { LocalAlbumsNotifier(this.albumService) : super([]) { albumService.getAllLocalAlbums().then((value) { if (mounted) { state = value; } }); _streamSub = albumService.watchLocalAlbums().listen((data) => state = data); } final AlbumService albumService; late final StreamSubscription> _streamSub; @override void dispose() { _streamSub.cancel(); super.dispose(); } } final localAlbumsProvider = StateNotifierProvider.autoDispose>((ref) { return LocalAlbumsNotifier(ref.watch(albumServiceProvider)); });