feat: Integrate Google Maps functionality with place suggestions and navigation options

This commit is contained in:
Dayron
2025-10-23 12:32:34 +02:00
parent 5b8d3ec45f
commit 37f5bb1710
5 changed files with 695 additions and 222 deletions

View File

@@ -7,7 +7,8 @@ import 'dart:ui' as ui;
import 'package:flutter_dotenv/flutter_dotenv.dart';
class MapContent extends StatefulWidget {
const MapContent({super.key});
final String? initialSearchQuery;
const MapContent({super.key, this.initialSearchQuery});
@override
State<MapContent> createState() => _MapContentState();
@@ -32,6 +33,15 @@ class _MapContentState extends State<MapContent> {
void initState() {
super.initState();
_getCurrentLocation();
// Si une recherche initiale est fournie, la pré-remplir et lancer la recherche
if (widget.initialSearchQuery != null && widget.initialSearchQuery!.isNotEmpty) {
_searchController.text = widget.initialSearchQuery!;
// Lancer la recherche automatiquement après un court délai pour laisser l'interface se charger
Future.delayed(const Duration(milliseconds: 500), () {
_performInitialSearch(widget.initialSearchQuery!);
});
}
}
@override
@@ -41,6 +51,112 @@ class _MapContentState extends State<MapContent> {
super.dispose();
}
// Nouvelle méthode pour effectuer la recherche initiale
Future<void> _performInitialSearch(String query) async {
if (query.isEmpty) return;
setState(() {
_isSearching = true;
});
try {
final url = Uri.parse(
'https://maps.googleapis.com/maps/api/place/autocomplete/json'
'?input=${Uri.encodeComponent(query)}'
'&key=$_apiKey'
'&language=fr'
);
final response = await http.get(url);
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['status'] == 'OK') {
final predictions = data['predictions'] as List;
if (predictions.isNotEmpty) {
// Prendre automatiquement la première suggestion
final firstPrediction = predictions.first;
final suggestion = PlaceSuggestion(
placeId: firstPrediction['place_id'],
description: firstPrediction['description'],
);
// Effectuer la sélection automatique
await _selectPlaceForInitialSearch(suggestion);
} else {
setState(() {
_isSearching = false;
});
}
} else {
setState(() {
_isSearching = false;
});
}
}
} catch (e) {
_showError('Erreur lors de la recherche initiale: $e');
setState(() {
_isSearching = false;
});
}
}
// Version modifiée de _selectPlace pour la recherche initiale
Future<void> _selectPlaceForInitialSearch(PlaceSuggestion suggestion) async {
try {
final url = Uri.parse(
'https://maps.googleapis.com/maps/api/place/details/json'
'?place_id=${suggestion.placeId}'
'&key=$_apiKey'
'&language=fr',
);
final response = await http.get(url);
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['status'] == 'OK') {
final location = data['result']['geometry']['location'];
final lat = location['lat'];
final lng = location['lng'];
final name = data['result']['name'];
final newPosition = LatLng(lat, lng);
// Ajouter un marqueur pour le lieu recherché
setState(() {
// Garder le marqueur de position utilisateur s'il existe
_markers.removeWhere((m) => m.markerId.value != 'user_location');
// Ajouter le nouveau marqueur de lieu
_markers.add(
Marker(
markerId: MarkerId(suggestion.placeId),
position: newPosition,
infoWindow: InfoWindow(title: name),
),
);
_isSearching = false;
});
// Animer la caméra vers le lieu trouvé
_mapController?.animateCamera(
CameraUpdate.newLatLngZoom(newPosition, 15),
);
}
}
} catch (e) {
_showError('Erreur lors de la sélection du lieu initial: $e');
setState(() {
_isSearching = false;
});
}
}
Future<void> _getCurrentLocation() async {
setState(() {
_isLoadingLocation = true;
@@ -449,6 +565,10 @@ class _MapContentState extends State<MapContent> {
),
),
onChanged: (value) {
// Ne pas rechercher si c'est juste le remplissage initial
if (widget.initialSearchQuery != null && value == widget.initialSearchQuery) {
return;
}
_searchPlaces(value);
},
),