feat: Add location permissions and implement current location retrieval in map component

This commit is contained in:
Van Leemput Dayron
2025-10-17 00:59:19 +02:00
parent d1cda9c3ff
commit 1ce5107b97
6 changed files with 355 additions and 131 deletions

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
class MapContent extends StatefulWidget {
const MapContent({super.key});
@@ -9,22 +10,100 @@ class MapContent extends StatefulWidget {
}
class _MapContentState extends State<MapContent> {
final LatLng _initialPosition = const LatLng(48.8566, 2.3522); // Paris
GoogleMapController? _mapController;
LatLng _initialPosition = const LatLng(48.8566, 2.3522); // Paris par défaut
final TextEditingController _searchController = TextEditingController();
bool _isLoadingLocation = false;
Position? _currentPosition;
@override
void initState() {
super.initState();
_getCurrentLocation();
}
@override
void dispose() {
_searchController.dispose();
_mapController?.dispose();
super.dispose();
}
// Obtenir la position actuelle
Future<void> _getCurrentLocation() async {
setState(() {
_isLoadingLocation = true;
});
try {
// Vérifier si la localisation est activée
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
_showError('Veuillez activer les services de localisation');
setState(() {
_isLoadingLocation = false;
});
return;
}
// Vérifier les permissions
LocationPermission permission = await Geolocator.checkPermission();
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
_showError('Permission de localisation refusée');
setState(() {
_isLoadingLocation = false;
});
return;
}
}
if (permission == LocationPermission.deniedForever) {
_showError('Permission de localisation refusée définitivement');
setState(() {
_isLoadingLocation = false;
});
return;
}
// Obtenir la position actuelle
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.high,
);
setState(() {
_currentPosition = position;
_initialPosition = LatLng(position.latitude, position.longitude);
_isLoadingLocation = false;
});
// Animer la caméra vers la position actuelle
if (_mapController != null) {
_mapController!.animateCamera(
CameraUpdate.newLatLngZoom(_initialPosition, 14),
);
}
} catch (e) {
_showError('Erreur lors de la récupération de la position: $e');
setState(() {
_isLoadingLocation = false;
});
}
}
void _showError(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message), backgroundColor: Colors.red),
);
}
void _searchLocation() {
// TODO: Implémenter la logique de recherche
final searchQuery = _searchController.text.trim();
if (searchQuery.isNotEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Recherche de: $searchQuery')),
);
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('Recherche de: $searchQuery')));
}
}
@@ -50,65 +129,62 @@ class _MapContentState extends State<MapContent> {
),
onSubmitted: (_) => _searchLocation(),
),
const SizedBox(height: 8),
// Bouton chercher
SizedBox(
width: double.infinity,
height: 48,
child: ElevatedButton(
onPressed: _searchLocation,
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
),
child: const Text(
'Chercher',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
),
),
const SizedBox(height: 8),
// Container avec la carte
const SizedBox(height: 12),
// Google Maps
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16.0),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 8,
offset: const Offset(0, 2),
child: Stack(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: GoogleMap(
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 14,
),
onMapCreated: (GoogleMapController controller) {
_mapController = controller;
},
myLocationEnabled: true,
myLocationButtonEnabled: false,
zoomControlsEnabled: false,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: CameraPosition(
target: _initialPosition,
zoom: 12,
),
onMapCreated: (GoogleMapController controller) {},
myLocationEnabled: true,
myLocationButtonEnabled: true,
zoomControlsEnabled: true,
compassEnabled: true,
),
),
// Indicateur de chargement
if (_isLoadingLocation)
Center(
child: Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(height: 8),
Text('Localisation en cours...'),
],
),
),
),
],
),
),
],
),
),
),
// Bouton flottant pour recentrer sur la position actuelle
floatingActionButton: FloatingActionButton(
onPressed: _getCurrentLocation,
tooltip: 'Ma position',
child: Icon(Icons.my_location),
),
);
}
}