From 896c7fd2f7ffa3cddbbe77902f6f9cbb1c2cba9e Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Thu, 25 Apr 2024 15:05:43 -0500 Subject: [PATCH 1/2] fix(mobile): show map on mobile --- .../providers/search_page_state.provider.dart | 26 +++++++++++++++--- .../search/services/search.service.dart | 27 +++++++------------ .../search/views/curated_location_page.dart | 17 +++--------- .../lib/modules/search/views/search_page.dart | 15 +++-------- .../lib/routing/tab_navigation_observer.dart | 2 +- 5 files changed, 40 insertions(+), 47 deletions(-) diff --git a/mobile/lib/modules/search/providers/search_page_state.provider.dart b/mobile/lib/modules/search/providers/search_page_state.provider.dart index 58abe2f87ea39..817f48c777e5f 100644 --- a/mobile/lib/modules/search/providers/search_page_state.provider.dart +++ b/mobile/lib/modules/search/providers/search_page_state.provider.dart @@ -1,4 +1,5 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/modules/search/models/curated_content.dart'; import 'package:immich_mobile/modules/search/models/search_page_state.model.dart'; import 'package:immich_mobile/modules/search/services/search.service.dart'; @@ -56,10 +57,27 @@ final searchPageStateProvider = return SearchPageStateNotifier(ref.watch(searchServiceProvider)); }); -final getCuratedLocationProvider = - FutureProvider.autoDispose>((ref) async { +final getPlacesProvider = + FutureProvider.autoDispose>((ref) async { final SearchService searchService = ref.watch(searchServiceProvider); - var curatedLocation = await searchService.getCuratedLocation(); - return curatedLocation ?? []; + final exploreData = await searchService.getExploreData(); + + if (exploreData == null) { + return []; + } + + final locations = + exploreData.firstWhere((data) => data.fieldName == "exifInfo.city").items; + + final curatedContent = locations + .map( + (l) => CuratedContent( + label: l.value, + id: l.data.id, + ), + ) + .toList(); + + return curatedContent; }); diff --git a/mobile/lib/modules/search/services/search.service.dart b/mobile/lib/modules/search/services/search.service.dart index 4d19657afd417..507a94cae3df1 100644 --- a/mobile/lib/modules/search/services/search.service.dart +++ b/mobile/lib/modules/search/services/search.service.dart @@ -6,6 +6,7 @@ import 'package:immich_mobile/shared/providers/api.provider.dart'; import 'package:immich_mobile/shared/providers/db.provider.dart'; import 'package:immich_mobile/shared/services/api.service.dart'; import 'package:isar/isar.dart'; +import 'package:logging/logging.dart'; import 'package:openapi/api.dart'; final searchServiceProvider = Provider( @@ -19,6 +20,7 @@ class SearchService { final ApiService _apiService; final Isar _db; + final _log = Logger("SearchService"); SearchService(this._apiService, this._db); Future?> getUserSuggestedSearchTerms() async { @@ -112,29 +114,18 @@ class SearchService { return _db.assets .getAllByRemoteId(response.assets.items.map((e) => e.id)); - } catch (error) { - debugPrint("Error [search] $error"); + } catch (error, stackTrace) { + _log.severe("Failed to search for assets", error, stackTrace); } return null; } - Future?> getCuratedLocation() async { + Future?> getExploreData() async { try { - var locations = await _apiService.assetApi.getCuratedLocations(); - - return locations; - } catch (e) { - debugPrint("Error [getCuratedLocation] ${e.toString()}"); - return []; - } - } - - Future?> getCuratedObjects() async { - try { - return await _apiService.assetApi.getCuratedObjects(); - } catch (e) { - debugPrint("Error [getCuratedObjects] ${e.toString()}"); - return []; + return await _apiService.searchApi.getExploreData(); + } catch (error, stackTrace) { + _log.severe("Failed to getExploreData", error, stackTrace); } + return null; } } diff --git a/mobile/lib/modules/search/views/curated_location_page.dart b/mobile/lib/modules/search/views/curated_location_page.dart index b216baf3cec5a..45067dc406447 100644 --- a/mobile/lib/modules/search/views/curated_location_page.dart +++ b/mobile/lib/modules/search/views/curated_location_page.dart @@ -6,7 +6,6 @@ import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/modules/search/models/curated_content.dart'; import 'package:immich_mobile/modules/search/providers/search_page_state.provider.dart'; import 'package:immich_mobile/modules/search/ui/explore_grid.dart'; -import 'package:openapi/api.dart'; @RoutePage() class CuratedLocationPage extends HookConsumerWidget { @@ -14,8 +13,7 @@ class CuratedLocationPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - AsyncValue> curatedLocation = - ref.watch(getCuratedLocationProvider); + AsyncValue> places = ref.watch(getPlacesProvider); return Scaffold( appBar: AppBar( @@ -27,16 +25,9 @@ class CuratedLocationPage extends HookConsumerWidget { icon: const Icon(Icons.arrow_back_ios_rounded), ), ), - body: curatedLocation.widgetWhen( - onData: (curatedLocations) => ExploreGrid( - curatedContent: curatedLocations - .map( - (l) => CuratedContent( - label: l.city, - id: l.id, - ), - ) - .toList(), + body: places.widgetWhen( + onData: (data) => ExploreGrid( + curatedContent: data, ), ), ); diff --git a/mobile/lib/modules/search/views/search_page.dart b/mobile/lib/modules/search/views/search_page.dart index d0d9f2e71d879..3df614292c20b 100644 --- a/mobile/lib/modules/search/views/search_page.dart +++ b/mobile/lib/modules/search/views/search_page.dart @@ -27,7 +27,7 @@ class SearchPage extends HookConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final curatedLocation = ref.watch(getCuratedLocationProvider); + final places = ref.watch(getPlacesProvider); final curatedPeople = ref.watch(getAllPeopleProvider); final isMapEnabled = ref.watch(serverInfoProvider.select((v) => v.serverFeatures.map)); @@ -87,18 +87,11 @@ class SearchPage extends HookConsumerWidget { buildPlaces() { return SizedBox( height: imageSize, - child: curatedLocation.widgetWhen( + child: places.widgetWhen( onError: (error, stack) => const ScaffoldErrorBody(withIcon: false), - onData: (locations) => CuratedPlacesRow( + onData: (data) => CuratedPlacesRow( isMapEnabled: isMapEnabled, - content: locations - .map( - (o) => CuratedContent( - id: o.id, - label: o.city, - ), - ) - .toList(), + content: data, imageSize: imageSize, onTap: (content, index) { context.pushRoute( diff --git a/mobile/lib/routing/tab_navigation_observer.dart b/mobile/lib/routing/tab_navigation_observer.dart index afe87fb248b20..196cab1db9b6b 100644 --- a/mobile/lib/routing/tab_navigation_observer.dart +++ b/mobile/lib/routing/tab_navigation_observer.dart @@ -37,7 +37,7 @@ class TabNavigationObserver extends AutoRouterObserver { // Perform tasks on re-visit to SearchRoute if (route.name == 'SearchRoute') { // Refresh Location State - ref.invalidate(getCuratedLocationProvider); + ref.invalidate(getPlacesProvider); ref.invalidate(getAllPeopleProvider); } From 7e341d056494a8285e463a0d780897cdab8cc1f5 Mon Sep 17 00:00:00 2001 From: Alex Tran Date: Thu, 25 Apr 2024 15:11:21 -0500 Subject: [PATCH 2/2] remove ununsed code --- .../models/search_page_state.model.dart | 81 ------------------- .../providers/search_page_state.provider.dart | 54 ------------- .../search/services/search.service.dart | 9 --- 3 files changed, 144 deletions(-) delete mode 100644 mobile/lib/modules/search/models/search_page_state.model.dart diff --git a/mobile/lib/modules/search/models/search_page_state.model.dart b/mobile/lib/modules/search/models/search_page_state.model.dart deleted file mode 100644 index e949817b98a9b..0000000000000 --- a/mobile/lib/modules/search/models/search_page_state.model.dart +++ /dev/null @@ -1,81 +0,0 @@ -import 'dart:convert'; - -import 'package:collection/collection.dart'; - -class SearchPageState { - final String searchTerm; - final bool isSearchEnabled; - final List searchSuggestion; - final List userSuggestedSearchTerms; - - SearchPageState({ - required this.searchTerm, - required this.isSearchEnabled, - required this.searchSuggestion, - required this.userSuggestedSearchTerms, - }); - - SearchPageState copyWith({ - String? searchTerm, - bool? isSearchEnabled, - List? searchSuggestion, - List? userSuggestedSearchTerms, - }) { - return SearchPageState( - searchTerm: searchTerm ?? this.searchTerm, - isSearchEnabled: isSearchEnabled ?? this.isSearchEnabled, - searchSuggestion: searchSuggestion ?? this.searchSuggestion, - userSuggestedSearchTerms: - userSuggestedSearchTerms ?? this.userSuggestedSearchTerms, - ); - } - - Map toMap() { - return { - 'searchTerm': searchTerm, - 'isSearchEnabled': isSearchEnabled, - 'searchSuggestion': searchSuggestion, - 'userSuggestedSearchTerms': userSuggestedSearchTerms, - }; - } - - factory SearchPageState.fromMap(Map map) { - return SearchPageState( - searchTerm: map['searchTerm'] ?? '', - isSearchEnabled: map['isSearchEnabled'] ?? false, - searchSuggestion: List.from(map['searchSuggestion']), - userSuggestedSearchTerms: - List.from(map['userSuggestedSearchTerms']), - ); - } - - String toJson() => json.encode(toMap()); - - factory SearchPageState.fromJson(String source) => - SearchPageState.fromMap(json.decode(source)); - - @override - String toString() { - return 'SearchPageState(searchTerm: $searchTerm, isSearchEnabled: $isSearchEnabled, searchSuggestion: $searchSuggestion, userSuggestedSearchTerms: $userSuggestedSearchTerms)'; - } - - @override - bool operator ==(Object other) { - if (identical(this, other)) return true; - final listEquals = const DeepCollectionEquality().equals; - - return other is SearchPageState && - other.searchTerm == searchTerm && - other.isSearchEnabled == isSearchEnabled && - listEquals(other.searchSuggestion, searchSuggestion) && - listEquals(other.userSuggestedSearchTerms, userSuggestedSearchTerms); - } - - @override - int get hashCode { - return searchTerm.hashCode ^ - isSearchEnabled.hashCode ^ - searchSuggestion.hashCode ^ - userSuggestedSearchTerms.hashCode; - } -} diff --git a/mobile/lib/modules/search/providers/search_page_state.provider.dart b/mobile/lib/modules/search/providers/search_page_state.provider.dart index 817f48c777e5f..3bd346ab2dd0c 100644 --- a/mobile/lib/modules/search/providers/search_page_state.provider.dart +++ b/mobile/lib/modules/search/providers/search_page_state.provider.dart @@ -1,61 +1,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/modules/search/models/curated_content.dart'; -import 'package:immich_mobile/modules/search/models/search_page_state.model.dart'; import 'package:immich_mobile/modules/search/services/search.service.dart'; -import 'package:openapi/api.dart'; - -class SearchPageStateNotifier extends StateNotifier { - SearchPageStateNotifier(this._searchService) - : super( - SearchPageState( - searchTerm: "", - isSearchEnabled: false, - searchSuggestion: [], - userSuggestedSearchTerms: [], - ), - ); - - final SearchService _searchService; - - void enableSearch() { - state = state.copyWith(isSearchEnabled: true); - } - - void disableSearch() { - state = state.copyWith(isSearchEnabled: false); - } - - void setSearchTerm(String value) { - state = state.copyWith(searchTerm: value); - - _getSearchSuggestion(state.searchTerm); - } - - void _getSearchSuggestion(String searchTerm) { - var searchList = state.userSuggestedSearchTerms; - - var newList = searchList.where((e) => e.toLowerCase().contains(searchTerm)); - - state = state.copyWith(searchSuggestion: [...newList]); - - if (searchTerm.isEmpty) { - state = state.copyWith(searchSuggestion: []); - } - } - - void getSuggestedSearchTerms() async { - var userSuggestedSearchTerms = - await _searchService.getUserSuggestedSearchTerms(); - - state = state.copyWith(userSuggestedSearchTerms: userSuggestedSearchTerms); - } -} - -final searchPageStateProvider = - StateNotifierProvider((ref) { - return SearchPageStateNotifier(ref.watch(searchServiceProvider)); -}); final getPlacesProvider = FutureProvider.autoDispose>((ref) async { diff --git a/mobile/lib/modules/search/services/search.service.dart b/mobile/lib/modules/search/services/search.service.dart index 507a94cae3df1..c1c6493c02fa2 100644 --- a/mobile/lib/modules/search/services/search.service.dart +++ b/mobile/lib/modules/search/services/search.service.dart @@ -23,15 +23,6 @@ class SearchService { final _log = Logger("SearchService"); SearchService(this._apiService, this._db); - Future?> getUserSuggestedSearchTerms() async { - try { - return await _apiService.assetApi.getAssetSearchTerms(); - } catch (e) { - debugPrint("[ERROR] [getUserSuggestedSearchTerms] ${e.toString()}"); - return []; - } - } - Future?> getSearchSuggestions( SearchSuggestionType type, { String? country,