feat: Add geocoding functionality for trips and enhance activity search with coordinates

This commit is contained in:
Dayron
2025-11-04 20:47:26 +01:00
parent f6c8432335
commit 9cb21c3470
9 changed files with 421 additions and 56 deletions

View File

@@ -23,6 +23,7 @@ class ActivityBloc extends Bloc<ActivityEvent, ActivityState> {
on<LoadActivities>(_onLoadActivities);
on<SearchActivities>(_onSearchActivities);
on<SearchActivitiesWithCoordinates>(_onSearchActivitiesWithCoordinates);
on<SearchActivitiesByText>(_onSearchActivitiesByText);
on<AddActivity>(_onAddActivity);
on<AddActivitiesBatch>(_onAddActivitiesBatch);
@@ -98,6 +99,50 @@ class ActivityBloc extends Bloc<ActivityEvent, ActivityState> {
}
}
/// Handles searching activities using coordinates directly (bypasses geocoding)
Future<void> _onSearchActivitiesWithCoordinates(
SearchActivitiesWithCoordinates event,
Emitter<ActivityState> emit,
) async {
try {
// Si c'est un append (charger plus), on garde l'état actuel et on met isLoading à true
if (event.appendToExisting && state is ActivitySearchResults) {
final currentState = state as ActivitySearchResults;
emit(currentState.copyWith(isLoading: true));
} else {
emit(const ActivitySearching());
}
final searchResults = await _placesService.searchActivitiesPaginated(
latitude: event.latitude,
longitude: event.longitude,
tripId: event.tripId,
category: event.category,
pageSize: event.maxResults ?? 20,
);
final activities = searchResults['activities'] as List<Activity>;
List<Activity> finalResults;
// Si on doit ajouter aux résultats existants
if (event.appendToExisting && state is ActivitySearchResults) {
final currentState = state as ActivitySearchResults;
finalResults = [...currentState.searchResults, ...activities];
} else {
finalResults = activities;
}
emit(ActivitySearchResults(
searchResults: finalResults,
query: event.category?.displayName ?? 'Toutes les activités',
isLoading: false,
));
} catch (e) {
_errorService.logError('activity_bloc', 'Erreur recherche activités avec coordonnées: $e');
emit(const ActivityError('Impossible de rechercher les activités'));
}
}
/// Handles text-based activity search
Future<void> _onSearchActivitiesByText(
SearchActivitiesByText event,

View File

@@ -43,6 +43,32 @@ class SearchActivities extends ActivityEvent {
List<Object?> get props => [tripId, destination, category, maxResults, offset, reset, appendToExisting];
}
/// Event to search activities using coordinates directly (bypasses geocoding)
class SearchActivitiesWithCoordinates extends ActivityEvent {
final String tripId;
final double latitude;
final double longitude;
final ActivityCategory? category;
final int? maxResults;
final int? offset;
final bool reset;
final bool appendToExisting;
const SearchActivitiesWithCoordinates({
required this.tripId,
required this.latitude,
required this.longitude,
this.category,
this.maxResults,
this.offset,
this.reset = false,
this.appendToExisting = false,
});
@override
List<Object?> get props => [tripId, latitude, longitude, category, maxResults, offset, reset, appendToExisting];
}
/// Event to search activities by text query
class SearchActivitiesByText extends ActivityEvent {
final String tripId;

View File

@@ -39,6 +39,8 @@ class GoogleActivityBloc extends Bloc<GoogleActivityEvent, GoogleActivityState>
final result = await _placesService.searchActivitiesPaginated(
destination: event.destination,
latitude: event.latitude,
longitude: event.longitude,
tripId: event.tripId,
category: event.category,
pageSize: 6,
@@ -74,6 +76,8 @@ class GoogleActivityBloc extends Bloc<GoogleActivityEvent, GoogleActivityState>
final result = await _placesService.searchActivitiesPaginated(
destination: event.destination,
latitude: event.latitude,
longitude: event.longitude,
tripId: event.tripId,
category: event.category,
pageSize: 6,
@@ -143,6 +147,8 @@ class GoogleActivityBloc extends Bloc<GoogleActivityEvent, GoogleActivityState>
add(LoadGoogleActivities(
tripId: event.tripId,
destination: event.destination,
latitude: event.latitude,
longitude: event.longitude,
category: event.category,
));
}

View File

@@ -12,35 +12,43 @@ abstract class GoogleActivityEvent extends Equatable {
/// Charger les activités Google Places
class LoadGoogleActivities extends GoogleActivityEvent {
final String tripId;
final String destination;
final String? destination;
final double? latitude;
final double? longitude;
final ActivityCategory? category;
const LoadGoogleActivities({
required this.tripId,
required this.destination,
this.destination,
this.latitude,
this.longitude,
this.category,
});
@override
List<Object?> get props => [tripId, destination, category];
List<Object?> get props => [tripId, destination, latitude, longitude, category];
}
/// Charger plus d'activités Google (pagination)
class LoadMoreGoogleActivities extends GoogleActivityEvent {
final String tripId;
final String destination;
final String? destination;
final double? latitude;
final double? longitude;
final ActivityCategory? category;
final String? nextPageToken;
const LoadMoreGoogleActivities({
required this.tripId,
required this.destination,
this.destination,
this.latitude,
this.longitude,
this.category,
this.nextPageToken,
});
@override
List<Object?> get props => [tripId, destination, category, nextPageToken];
List<Object?> get props => [tripId, destination, latitude, longitude, category, nextPageToken];
}
/// Mettre à jour les activités Google
@@ -74,17 +82,21 @@ class AddGoogleActivityToDb extends GoogleActivityEvent {
/// Rechercher des activités Google par catégorie
class SearchGoogleActivitiesByCategory extends GoogleActivityEvent {
final String tripId;
final String destination;
final String? destination;
final double? latitude;
final double? longitude;
final ActivityCategory category;
const SearchGoogleActivitiesByCategory({
required this.tripId,
required this.destination,
this.destination,
this.latitude,
this.longitude,
required this.category,
});
@override
List<Object?> get props => [tripId, destination, category];
List<Object?> get props => [tripId, destination, latitude, longitude, category];
}
/// Effacer les résultats Google