mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	fix(mobile): search page (#13833)
* fix(mobile): search page minor problems * fix: flashing between search * restore search size * remove print statement * linting
This commit is contained in:
		
							parent
							
								
									9d75c5b999
								
							
						
					
					
						commit
						318ab756cb
					
				
							
								
								
									
										37
									
								
								mobile/lib/models/search/search_result.model.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								mobile/lib/models/search/search_result.model.dart
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					import 'package:collection/collection.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:immich_mobile/entities/asset.entity.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SearchResult {
 | 
				
			||||||
 | 
					  final List<Asset> assets;
 | 
				
			||||||
 | 
					  final int? nextPage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SearchResult({
 | 
				
			||||||
 | 
					    required this.assets,
 | 
				
			||||||
 | 
					    this.nextPage,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  SearchResult copyWith({
 | 
				
			||||||
 | 
					    List<Asset>? assets,
 | 
				
			||||||
 | 
					    int? nextPage,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    return SearchResult(
 | 
				
			||||||
 | 
					      assets: assets ?? this.assets,
 | 
				
			||||||
 | 
					      nextPage: nextPage ?? this.nextPage,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String toString() => 'SearchResult(assets: $assets, nextPage: $nextPage)';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  bool operator ==(covariant SearchResult other) {
 | 
				
			||||||
 | 
					    if (identical(this, other)) return true;
 | 
				
			||||||
 | 
					    final listEquals = const DeepCollectionEquality().equals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return listEquals(other.assets, assets) && other.nextPage == nextPage;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  int get hashCode => assets.hashCode ^ nextPage.hashCode;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -58,23 +58,22 @@ class SearchPage extends HookConsumerWidget {
 | 
				
			|||||||
    final mediaTypeCurrentFilterWidget = useState<Widget?>(null);
 | 
					    final mediaTypeCurrentFilterWidget = useState<Widget?>(null);
 | 
				
			||||||
    final displayOptionCurrentFilterWidget = useState<Widget?>(null);
 | 
					    final displayOptionCurrentFilterWidget = useState<Widget?>(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final currentPage = useState(1);
 | 
					    final isSearching = useState(false);
 | 
				
			||||||
    final searchProvider = ref.watch(paginatedSearchProvider);
 | 
					 | 
				
			||||||
    final searchResultCount = useState(0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    search() async {
 | 
					    search() async {
 | 
				
			||||||
      if (prefilter == null && filter.value == previousFilter.value) return;
 | 
					      if (prefilter == null && filter.value == previousFilter.value) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      isSearching.value = true;
 | 
				
			||||||
      ref.watch(paginatedSearchProvider.notifier).clear();
 | 
					      ref.watch(paginatedSearchProvider.notifier).clear();
 | 
				
			||||||
 | 
					      await ref.watch(paginatedSearchProvider.notifier).search(filter.value);
 | 
				
			||||||
      currentPage.value = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      final searchResult = await ref
 | 
					 | 
				
			||||||
          .watch(paginatedSearchProvider.notifier)
 | 
					 | 
				
			||||||
          .getNextPage(filter.value, currentPage.value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      previousFilter.value = filter.value;
 | 
					      previousFilter.value = filter.value;
 | 
				
			||||||
      searchResultCount.value = searchResult.length;
 | 
					      isSearching.value = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadMoreSearchResult() async {
 | 
				
			||||||
 | 
					      isSearching.value = true;
 | 
				
			||||||
 | 
					      await ref.watch(paginatedSearchProvider.notifier).search(filter.value);
 | 
				
			||||||
 | 
					      isSearching.value = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    searchPrefilter() {
 | 
					    searchPrefilter() {
 | 
				
			||||||
@ -97,20 +96,16 @@ class SearchPage extends HookConsumerWidget {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    useEffect(
 | 
					    useEffect(
 | 
				
			||||||
      () {
 | 
					      () {
 | 
				
			||||||
 | 
					        Future.microtask(
 | 
				
			||||||
 | 
					          () => ref.invalidate(paginatedSearchProvider),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        searchPrefilter();
 | 
					        searchPrefilter();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      [],
 | 
					      [],
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loadMoreSearchResult() async {
 | 
					 | 
				
			||||||
      currentPage.value += 1;
 | 
					 | 
				
			||||||
      final searchResult = await ref
 | 
					 | 
				
			||||||
          .watch(paginatedSearchProvider.notifier)
 | 
					 | 
				
			||||||
          .getNextPage(filter.value, currentPage.value);
 | 
					 | 
				
			||||||
      searchResultCount.value = searchResult.length;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    showPeoplePicker() {
 | 
					    showPeoplePicker() {
 | 
				
			||||||
      handleOnSelect(Set<Person> value) {
 | 
					      handleOnSelect(Set<Person> value) {
 | 
				
			||||||
        filter.value = filter.value.copyWith(
 | 
					        filter.value = filter.value.copyWith(
 | 
				
			||||||
@ -465,41 +460,6 @@ class SearchPage extends HookConsumerWidget {
 | 
				
			|||||||
      search();
 | 
					      search();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    buildSearchResult() {
 | 
					 | 
				
			||||||
      return switch (searchProvider) {
 | 
					 | 
				
			||||||
        AsyncData() => Expanded(
 | 
					 | 
				
			||||||
            child: Padding(
 | 
					 | 
				
			||||||
              padding: const EdgeInsets.only(top: 8.0),
 | 
					 | 
				
			||||||
              child: NotificationListener<ScrollEndNotification>(
 | 
					 | 
				
			||||||
                onNotification: (notification) {
 | 
					 | 
				
			||||||
                  final metrics = notification.metrics;
 | 
					 | 
				
			||||||
                  final shouldLoadMore = searchResultCount.value > 75;
 | 
					 | 
				
			||||||
                  if (metrics.pixels >= metrics.maxScrollExtent &&
 | 
					 | 
				
			||||||
                      shouldLoadMore) {
 | 
					 | 
				
			||||||
                    loadMoreSearchResult();
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                  return true;
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                child: MultiselectGrid(
 | 
					 | 
				
			||||||
                  renderListProvider: paginatedSearchRenderListProvider,
 | 
					 | 
				
			||||||
                  archiveEnabled: true,
 | 
					 | 
				
			||||||
                  deleteEnabled: true,
 | 
					 | 
				
			||||||
                  editEnabled: true,
 | 
					 | 
				
			||||||
                  favoriteEnabled: true,
 | 
					 | 
				
			||||||
                  stackEnabled: false,
 | 
					 | 
				
			||||||
                  emptyIndicator: Padding(
 | 
					 | 
				
			||||||
                    padding: const EdgeInsets.symmetric(horizontal: 16.0),
 | 
					 | 
				
			||||||
                    child: SearchEmptyContent(),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
          ),
 | 
					 | 
				
			||||||
        AsyncError(:final error) => Text('Error: $error'),
 | 
					 | 
				
			||||||
        _ => const Expanded(child: Center(child: CircularProgressIndicator())),
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      resizeToAvoidBottomInset: true,
 | 
					      resizeToAvoidBottomInset: true,
 | 
				
			||||||
      appBar: AppBar(
 | 
					      appBar: AppBar(
 | 
				
			||||||
@ -635,13 +595,67 @@ class SearchPage extends HookConsumerWidget {
 | 
				
			|||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
          buildSearchResult(),
 | 
					          SearchResultGrid(
 | 
				
			||||||
 | 
					            onScrollEnd: loadMoreSearchResult,
 | 
				
			||||||
 | 
					            isSearching: isSearching.value,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SearchResultGrid extends StatelessWidget {
 | 
				
			||||||
 | 
					  final VoidCallback onScrollEnd;
 | 
				
			||||||
 | 
					  final bool isSearching;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const SearchResultGrid({
 | 
				
			||||||
 | 
					    super.key,
 | 
				
			||||||
 | 
					    required this.onScrollEnd,
 | 
				
			||||||
 | 
					    this.isSearching = false,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return Expanded(
 | 
				
			||||||
 | 
					      child: Padding(
 | 
				
			||||||
 | 
					        padding: const EdgeInsets.only(top: 8.0),
 | 
				
			||||||
 | 
					        child: NotificationListener<ScrollEndNotification>(
 | 
				
			||||||
 | 
					          onNotification: (notification) {
 | 
				
			||||||
 | 
					            final isBottomSheetNotification = notification.context
 | 
				
			||||||
 | 
					                    ?.findAncestorWidgetOfExactType<
 | 
				
			||||||
 | 
					                        DraggableScrollableSheet>() !=
 | 
				
			||||||
 | 
					                null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final metrics = notification.metrics;
 | 
				
			||||||
 | 
					            final isVerticalScroll = metrics.axis == Axis.vertical;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (metrics.pixels >= metrics.maxScrollExtent &&
 | 
				
			||||||
 | 
					                isVerticalScroll &&
 | 
				
			||||||
 | 
					                !isBottomSheetNotification) {
 | 
				
			||||||
 | 
					              onScrollEnd();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          child: MultiselectGrid(
 | 
				
			||||||
 | 
					            renderListProvider: paginatedSearchRenderListProvider,
 | 
				
			||||||
 | 
					            archiveEnabled: true,
 | 
				
			||||||
 | 
					            deleteEnabled: true,
 | 
				
			||||||
 | 
					            editEnabled: true,
 | 
				
			||||||
 | 
					            favoriteEnabled: true,
 | 
				
			||||||
 | 
					            stackEnabled: false,
 | 
				
			||||||
 | 
					            emptyIndicator: Padding(
 | 
				
			||||||
 | 
					              padding: const EdgeInsets.symmetric(horizontal: 16.0),
 | 
				
			||||||
 | 
					              child: !isSearching ? SearchEmptyContent() : SizedBox.shrink(),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SearchEmptyContent extends StatelessWidget {
 | 
					class SearchEmptyContent extends StatelessWidget {
 | 
				
			||||||
  const SearchEmptyContent({super.key});
 | 
					  const SearchEmptyContent({super.key});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,46 +1,39 @@
 | 
				
			|||||||
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/models/search/search_result.model.dart';
 | 
				
			||||||
import 'package:immich_mobile/providers/asset_viewer/render_list.provider.dart';
 | 
					import 'package:immich_mobile/providers/asset_viewer/render_list.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
 | 
					import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
 | 
				
			||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
 | 
					import 'package:immich_mobile/models/search/search_filter.model.dart';
 | 
				
			||||||
import 'package:immich_mobile/services/search.service.dart';
 | 
					import 'package:immich_mobile/services/search.service.dart';
 | 
				
			||||||
import 'package:immich_mobile/entities/asset.entity.dart';
 | 
					 | 
				
			||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
 | 
					import 'package:riverpod_annotation/riverpod_annotation.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
part 'paginated_search.provider.g.dart';
 | 
					part 'paginated_search.provider.g.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@riverpod
 | 
					final paginatedSearchProvider =
 | 
				
			||||||
class PaginatedSearch extends _$PaginatedSearch {
 | 
					    StateNotifierProvider<PaginatedSearchNotifier, SearchResult>(
 | 
				
			||||||
  Future<List<Asset>?> _search(SearchFilter filter, int page) async {
 | 
					  (ref) => PaginatedSearchNotifier(ref.watch(searchServiceProvider)),
 | 
				
			||||||
    final service = ref.read(searchServiceProvider);
 | 
					);
 | 
				
			||||||
    final result = await service.search(filter, page);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return result;
 | 
					class PaginatedSearchNotifier extends StateNotifier<SearchResult> {
 | 
				
			||||||
  }
 | 
					  final SearchService _searchService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  PaginatedSearchNotifier(this._searchService)
 | 
				
			||||||
  Future<List<Asset>> build() async {
 | 
					      : super(SearchResult(assets: [], nextPage: 1));
 | 
				
			||||||
    return [];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<List<Asset>> getNextPage(SearchFilter filter, int nextPage) async {
 | 
					  search(SearchFilter filter) async {
 | 
				
			||||||
    state = const AsyncValue.loading();
 | 
					    if (state.nextPage == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final newState = await AsyncValue.guard(() async {
 | 
					    final result = await _searchService.search(filter, state.nextPage!);
 | 
				
			||||||
      final assets = await _search(filter, nextPage);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (assets != null) {
 | 
					    if (result == null) return;
 | 
				
			||||||
        return [...?state.value, ...assets];
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state = newState.valueOrNull == null
 | 
					    state = SearchResult(
 | 
				
			||||||
        ? const AsyncValue.data([])
 | 
					      assets: [...state.assets, ...result.assets],
 | 
				
			||||||
        : AsyncValue.data(newState.value!);
 | 
					      nextPage: result.nextPage,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
    return newState.valueOrNull ?? [];
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  clear() {
 | 
					  clear() {
 | 
				
			||||||
    state = const AsyncValue.data([]);
 | 
					    state = SearchResult(assets: [], nextPage: 1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -48,15 +41,11 @@ class PaginatedSearch extends _$PaginatedSearch {
 | 
				
			|||||||
AsyncValue<RenderList> paginatedSearchRenderList(
 | 
					AsyncValue<RenderList> paginatedSearchRenderList(
 | 
				
			||||||
  PaginatedSearchRenderListRef ref,
 | 
					  PaginatedSearchRenderListRef ref,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
  final assets = ref.watch(paginatedSearchProvider).value;
 | 
					  final result = ref.watch(paginatedSearchProvider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (assets != null) {
 | 
					 | 
				
			||||||
  return ref.watch(
 | 
					  return ref.watch(
 | 
				
			||||||
    renderListProviderWithGrouping(
 | 
					    renderListProviderWithGrouping(
 | 
				
			||||||
        (assets, GroupAssetsBy.none),
 | 
					      (result.assets, GroupAssetsBy.none),
 | 
				
			||||||
    ),
 | 
					    ),
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    return const AsyncValue.loading();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,7 @@ part of 'paginated_search.provider.dart';
 | 
				
			|||||||
// **************************************************************************
 | 
					// **************************************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String _$paginatedSearchRenderListHash() =>
 | 
					String _$paginatedSearchRenderListHash() =>
 | 
				
			||||||
    r'c2cc2381ee6ea8f8e08d6d4c1289bbf0c6b9647e';
 | 
					    r'4585c832106b16b6d294055f47bbbe83e0802846';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// See also [paginatedSearchRenderList].
 | 
					/// See also [paginatedSearchRenderList].
 | 
				
			||||||
@ProviderFor(paginatedSearchRenderList)
 | 
					@ProviderFor(paginatedSearchRenderList)
 | 
				
			||||||
@ -24,21 +24,5 @@ final paginatedSearchRenderListProvider =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef PaginatedSearchRenderListRef
 | 
					typedef PaginatedSearchRenderListRef
 | 
				
			||||||
    = AutoDisposeProviderRef<AsyncValue<RenderList>>;
 | 
					    = AutoDisposeProviderRef<AsyncValue<RenderList>>;
 | 
				
			||||||
String _$paginatedSearchHash() => r'8312f358261368cf2b5572b839fdd8f8fbe9a62e';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// See also [PaginatedSearch].
 | 
					 | 
				
			||||||
@ProviderFor(PaginatedSearch)
 | 
					 | 
				
			||||||
final paginatedSearchProvider =
 | 
					 | 
				
			||||||
    AutoDisposeAsyncNotifierProvider<PaginatedSearch, List<Asset>>.internal(
 | 
					 | 
				
			||||||
  PaginatedSearch.new,
 | 
					 | 
				
			||||||
  name: r'paginatedSearchProvider',
 | 
					 | 
				
			||||||
  debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
 | 
					 | 
				
			||||||
      ? null
 | 
					 | 
				
			||||||
      : _$paginatedSearchHash,
 | 
					 | 
				
			||||||
  dependencies: null,
 | 
					 | 
				
			||||||
  allTransitiveDependencies: null,
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef _$PaginatedSearch = AutoDisposeAsyncNotifier<List<Asset>>;
 | 
					 | 
				
			||||||
// ignore_for_file: type=lint
 | 
					// ignore_for_file: type=lint
 | 
				
			||||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
 | 
					// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,10 @@
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
					import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/extensions/string_extensions.dart';
 | 
				
			||||||
import 'package:immich_mobile/interfaces/asset.interface.dart';
 | 
					import 'package:immich_mobile/interfaces/asset.interface.dart';
 | 
				
			||||||
import 'package:immich_mobile/models/search/search_filter.model.dart';
 | 
					import 'package:immich_mobile/models/search/search_filter.model.dart';
 | 
				
			||||||
import 'package:immich_mobile/entities/asset.entity.dart';
 | 
					import 'package:immich_mobile/entities/asset.entity.dart';
 | 
				
			||||||
 | 
					import 'package:immich_mobile/models/search/search_result.model.dart';
 | 
				
			||||||
import 'package:immich_mobile/providers/api.provider.dart';
 | 
					import 'package:immich_mobile/providers/api.provider.dart';
 | 
				
			||||||
import 'package:immich_mobile/repositories/asset.repository.dart';
 | 
					import 'package:immich_mobile/repositories/asset.repository.dart';
 | 
				
			||||||
import 'package:immich_mobile/services/api.service.dart';
 | 
					import 'package:immich_mobile/services/api.service.dart';
 | 
				
			||||||
@ -44,7 +46,7 @@ class SearchService {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<List<Asset>?> search(SearchFilter filter, int page) async {
 | 
					  Future<SearchResult?> search(SearchFilter filter, int page) async {
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      SearchResponseDto? response;
 | 
					      SearchResponseDto? response;
 | 
				
			||||||
      AssetTypeEnum? type;
 | 
					      AssetTypeEnum? type;
 | 
				
			||||||
@ -103,8 +105,12 @@ class SearchService {
 | 
				
			|||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return _assetRepository
 | 
					      return SearchResult(
 | 
				
			||||||
          .getAllByRemoteId(response.assets.items.map((e) => e.id));
 | 
					        assets: await _assetRepository.getAllByRemoteId(
 | 
				
			||||||
 | 
					          response.assets.items.map((e) => e.id),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        nextPage: response.assets.nextPage?.toInt(),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
    } catch (error, stackTrace) {
 | 
					    } catch (error, stackTrace) {
 | 
				
			||||||
      _log.severe("Failed to search for assets", error, stackTrace);
 | 
					      _log.severe("Failed to search for assets", error, stackTrace);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user