import 'dart:async'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/services/search.service.dart'; import 'package:immich_mobile/models/search/search_filter.model.dart'; import 'package:immich_mobile/providers/infrastructure/search.provider.dart'; final searchPreFilterProvider = NotifierProvider(SearchFilterProvider.new); class SearchFilterProvider extends Notifier { @override SearchFilter? build() { return null; } void setFilter(SearchFilter? filter) { state = filter; } void clear() { state = null; } } class SearchState { final List assets; final int? nextPage; final bool isLoading; const SearchState({this.assets = const [], this.nextPage = 1, this.isLoading = false}); } final paginatedSearchProvider = StateNotifierProvider( (ref) => PaginatedSearchNotifier(ref.watch(searchServiceProvider)), ); class PaginatedSearchNotifier extends StateNotifier { final SearchService _searchService; final _assetCountController = StreamController.broadcast(); PaginatedSearchNotifier(this._searchService) : super(const SearchState()); Stream get assetCount => _assetCountController.stream; Future search(SearchFilter filter) async { if (state.nextPage == null || state.isLoading) return; state = SearchState(assets: state.assets, nextPage: state.nextPage, isLoading: true); final result = await _searchService.search(filter, state.nextPage!); if (result == null) { state = SearchState(assets: state.assets, nextPage: state.nextPage); return; } final assets = [...state.assets, ...result.assets]; state = SearchState(assets: assets, nextPage: result.nextPage); _assetCountController.add(assets.length); } void clear() { state = const SearchState(); _assetCountController.add(0); } @override void dispose() { _assetCountController.close(); super.dispose(); } }