89 lines
2.5 KiB
Dart
89 lines
2.5 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_google_places_sdk/flutter_google_places_sdk.dart';
|
|
import 'package:wheres_my_sign/common/functions.dart';
|
|
|
|
class GooglePlacesHelper {
|
|
final FlutterGooglePlacesSdk _places;
|
|
bool _isHandlingSelection = false;
|
|
|
|
GooglePlacesHelper(String apiKey) : _places = FlutterGooglePlacesSdk(apiKey);
|
|
|
|
void attachAddressListener({
|
|
required TextEditingController controller,
|
|
required FocusNode focusNode,
|
|
required void Function(List<AutocompletePrediction>) onPredictions,
|
|
required VoidCallback onOverlayHide,
|
|
required Debouncer debouncer,
|
|
}) {
|
|
controller.addListener(() {
|
|
_onAddressChanged(
|
|
controller: controller,
|
|
debouncer: debouncer,
|
|
onPredictions: onPredictions,
|
|
onOverlayHide: onOverlayHide,
|
|
);
|
|
});
|
|
|
|
focusNode.addListener(() {
|
|
if (!focusNode.hasFocus) {
|
|
Future.delayed(const Duration(milliseconds: 100), onOverlayHide);
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> _onAddressChanged({
|
|
required TextEditingController controller,
|
|
required Debouncer debouncer,
|
|
required void Function(List<AutocompletePrediction>) onPredictions,
|
|
required VoidCallback onOverlayHide,
|
|
}) async {
|
|
if (_isHandlingSelection || controller.text.length < 3) return;
|
|
|
|
debouncer.run(() async {
|
|
try {
|
|
final result = await _places.findAutocompletePredictions(
|
|
controller.text,
|
|
countries: ['us'],
|
|
);
|
|
|
|
if (result.predictions.isNotEmpty) {
|
|
onPredictions(result.predictions);
|
|
} else {
|
|
onOverlayHide();
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Prediction error: $e');
|
|
onOverlayHide();
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<void> handlePlaceSelection({
|
|
required AutocompletePrediction prediction,
|
|
required TextEditingController addressController,
|
|
required void Function(double? lat, double? lng) onLatLngRetrieved,
|
|
required VoidCallback onOverlayHide,
|
|
}) async {
|
|
try {
|
|
_isHandlingSelection = true;
|
|
onOverlayHide();
|
|
|
|
final result = await _places.fetchPlace(
|
|
prediction.placeId,
|
|
fields: [PlaceField.Address, PlaceField.Location],
|
|
);
|
|
|
|
final place = result.place;
|
|
if (place != null) {
|
|
addressController.text = place.address ?? prediction.fullText;
|
|
onLatLngRetrieved(place.latLng?.lat, place.latLng?.lng);
|
|
}
|
|
} catch (e) {
|
|
debugPrint('Place fetch error: $e');
|
|
} finally {
|
|
_isHandlingSelection = false;
|
|
}
|
|
}
|
|
}
|