Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(mobile): show places in Search page on mobile #9085

Merged
merged 2 commits into from
Apr 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 0 additions & 81 deletions mobile/lib/modules/search/models/search_page_state.model.dart

This file was deleted.

72 changes: 18 additions & 54 deletions mobile/lib/modules/search/providers/search_page_state.provider.dart
Original file line number Diff line number Diff line change
@@ -1,65 +1,29 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/search/models/search_page_state.model.dart';
import 'package:immich_mobile/modules/search/models/curated_content.dart';

import 'package:immich_mobile/modules/search/services/search.service.dart';
import 'package:openapi/api.dart';

class SearchPageStateNotifier extends StateNotifier<SearchPageState> {
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: []);
}
}
final getPlacesProvider =
FutureProvider.autoDispose<List<CuratedContent>>((ref) async {
final SearchService searchService = ref.watch(searchServiceProvider);

void getSuggestedSearchTerms() async {
var userSuggestedSearchTerms =
await _searchService.getUserSuggestedSearchTerms();
final exploreData = await searchService.getExploreData();

state = state.copyWith(userSuggestedSearchTerms: userSuggestedSearchTerms);
if (exploreData == null) {
return [];
}
}

final searchPageStateProvider =
StateNotifierProvider<SearchPageStateNotifier, SearchPageState>((ref) {
return SearchPageStateNotifier(ref.watch(searchServiceProvider));
});
final locations =
exploreData.firstWhere((data) => data.fieldName == "exifInfo.city").items;

final getCuratedLocationProvider =
FutureProvider.autoDispose<List<CuratedLocationsResponseDto>>((ref) async {
final SearchService searchService = ref.watch(searchServiceProvider);
final curatedContent = locations
.map(
(l) => CuratedContent(
label: l.value,
id: l.data.id,
),
)
.toList();

var curatedLocation = await searchService.getCuratedLocation();
return curatedLocation ?? [];
return curatedContent;
});
36 changes: 9 additions & 27 deletions mobile/lib/modules/search/services/search.service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -19,17 +20,9 @@ class SearchService {
final ApiService _apiService;
final Isar _db;

final _log = Logger("SearchService");
SearchService(this._apiService, this._db);

Future<List<String>?> getUserSuggestedSearchTerms() async {
try {
return await _apiService.assetApi.getAssetSearchTerms();
} catch (e) {
debugPrint("[ERROR] [getUserSuggestedSearchTerms] ${e.toString()}");
return [];
}
}

Future<List<String>?> getSearchSuggestions(
SearchSuggestionType type, {
String? country,
Expand Down Expand Up @@ -112,29 +105,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<List<CuratedLocationsResponseDto>?> getCuratedLocation() async {
try {
var locations = await _apiService.assetApi.getCuratedLocations();

return locations;
} catch (e) {
debugPrint("Error [getCuratedLocation] ${e.toString()}");
return [];
}
}

Future<List<CuratedObjectsResponseDto>?> getCuratedObjects() async {
Future<List<SearchExploreResponseDto>?> getExploreData() 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;
}
}
17 changes: 4 additions & 13 deletions mobile/lib/modules/search/views/curated_location_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@ 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 {
const CuratedLocationPage({super.key});

@override
Widget build(BuildContext context, WidgetRef ref) {
AsyncValue<List<CuratedLocationsResponseDto>> curatedLocation =
ref.watch(getCuratedLocationProvider);
AsyncValue<List<CuratedContent>> places = ref.watch(getPlacesProvider);

return Scaffold(
appBar: AppBar(
Expand All @@ -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,
),
),
);
Expand Down
15 changes: 4 additions & 11 deletions mobile/lib/modules/search/views/search_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion mobile/lib/routing/tab_navigation_observer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
Loading