feat: Integrate Google Maps functionality with place suggestions and navigation options
This commit is contained in:
@@ -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);
|
||||
},
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user