Created
April 26, 2023 21:43
-
-
Save Daniel-Sogbey/77541760cda3b9a7ee0e292ea0158488 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import '../constants/store.dart'; | |
import '../model/directions.dart'; | |
class AppInfo extends ChangeNotifier { | |
Directions? userPickupLocation, userDropOffLocation; | |
updatePickupLocationAddress(Directions userPickupAddress) { | |
userPickupLocation = userPickupAddress; | |
notifyListeners(); | |
return userPickupAddress; | |
} | |
void updateDropOffLocationAddress(Directions userDropOffAddress) { | |
userDropOffLocation = userDropOffAddress; | |
Store.setUserLocation(userDropOffLocation!.locationName!); | |
notifyListeners(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Directions { | |
String? formattedAddress; | |
String? locationName; | |
String? locationId; | |
double? locationLatitude; | |
double? locationLongitude; | |
Directions({ | |
this.formattedAddress, | |
this.locationName, | |
this.locationId, | |
this.locationLatitude, | |
this.locationLongitude, | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:click_so/widgets/progress_dialog.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:provider/provider.dart'; | |
import '../constants/global.dart'; | |
import '../constants/request_method.dart'; | |
import '../constants/store.dart'; | |
import '../constants/variable_constants.dart'; | |
import '../model/directions.dart'; | |
import '../model/predicted_places.dart'; | |
import '../providers/app_info.dart'; | |
class PlacePredictionTile extends StatefulWidget { | |
final PredictedPlaces? predictedPlaces; | |
const PlacePredictionTile({Key? key, required this.predictedPlaces}) | |
: super(key: key); | |
@override | |
State<PlacePredictionTile> createState() => _PlacePredictionTileState(); | |
} | |
class _PlacePredictionTileState extends State<PlacePredictionTile> { | |
getPlaceDirectionDetails(String? placeId, context) async { | |
showDialog( | |
context: context, | |
builder: (BuildContext context) { | |
return ProgressDialog( | |
message: "Processing new location..", | |
); | |
}); | |
String placeDirectionsDetailsUrl = | |
"https://maps.googleapis.com/maps/api/place/details/json?place_id=$placeId&key=$mapKey"; | |
var responseApi = | |
await RequestMethod.receiveRequest(placeDirectionsDetailsUrl); | |
Navigator.pop(context); | |
if (responseApi == "Something went wrong") { | |
return; | |
} | |
if (responseApi['status'] == 'OK') { | |
Directions directions = Directions(); | |
directions.locationId = placeId; | |
directions.locationName = responseApi['result']['name']; | |
directions.locationLatitude = | |
responseApi['result']['geometry']['location']['lat']; | |
directions.locationLongitude = | |
responseApi['result']['geometry']['location']['lng']; | |
print("LOCATION NAME HERE : ${directions.locationName}"); | |
print("LOCATION LATITUDE HERE : ${directions.locationLatitude}"); | |
print("LOCATION LONGITUDE HERE : ${directions.locationLongitude}"); | |
Provider.of<AppInfo>(context, listen: false) | |
.updateDropOffLocationAddress(directions); | |
setState(() { | |
userNewAddress = directions.locationName!; | |
}); | |
Store.setUserLocation(userNewAddress); | |
Navigator.pop(context, userNewAddress); | |
userDropOffAddress = directions.locationName!; | |
Navigator.pop(context, 'obtainedDropOff'); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
margin: const EdgeInsets.symmetric(horizontal: 10), | |
child: ElevatedButton( | |
onPressed: () { | |
getPlaceDirectionDetails(widget.predictedPlaces!.place_id, context); | |
}, | |
style: ElevatedButton.styleFrom( | |
primary: const Color(0xffffffff), | |
elevation: 1, | |
), | |
child: Row( | |
children: [ | |
Icon(Icons.location_on_outlined, color: Theme.of(context).primaryColor), | |
const SizedBox(width: 10), | |
Expanded( | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.start, | |
children: [ | |
const SizedBox(height: 10), | |
Text( | |
widget.predictedPlaces!.main_text!, | |
style: const TextStyle(color: Color(0xff3e3e3e)), | |
overflow: TextOverflow.ellipsis, | |
), | |
const SizedBox(height: 2), | |
Text( | |
widget.predictedPlaces!.secondary_text!, | |
style: const TextStyle(color: Color(0xff3e3e3e)), | |
overflow: TextOverflow.ellipsis, | |
), | |
const SizedBox(height: 8), | |
], | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class PredictedPlaces { | |
String? place_id; | |
String? main_text; | |
String? secondary_text; | |
String? city; | |
PredictedPlaces( | |
{this.place_id, this.main_text, this.secondary_text, this.city}); | |
PredictedPlaces.fromJson(Map<String, dynamic> jsonData) { | |
place_id = jsonData['place_id']; | |
main_text = jsonData["structured_formatting"]['main_text']; | |
secondary_text = jsonData["structured_formatting"]['secondary_text']; | |
city = (jsonData["structured_formatting"]['secondary_text'] as String) | |
.split(",") | |
.length > | |
1 | |
? (jsonData["structured_formatting"]['secondary_text'] as String) | |
.split(",")[1] | |
: (jsonData["structured_formatting"]['secondary_text'] as String) | |
.split(",")[0]; | |
debugPrint("USER SELECTED CITY $city"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ignore_for_file: unnecessary_const | |
import 'package:flutter/material.dart'; | |
import '../../constants/request_method.dart'; | |
import '../../constants/variable_constants.dart'; | |
import '../../model/predicted_places.dart'; | |
import '../../widgets/place_prediction_tile.dart'; | |
class SearchPlacesScreen extends StatefulWidget { | |
const SearchPlacesScreen({Key? key}) : super(key: key); | |
static const String routeName = '/search-places'; | |
@override | |
State<SearchPlacesScreen> createState() => _SearchPlacesScreenState(); | |
} | |
class _SearchPlacesScreenState extends State<SearchPlacesScreen> { | |
var _formController = TextEditingController(); | |
var _toController = TextEditingController(); | |
List<PredictedPlaces> placesPredictedList = []; | |
void findPlaceAutoCompleteSearch(String inputText) async { | |
if (inputText.isNotEmpty) { | |
String urlAutoCompleteSearch = | |
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$inputText&key=$mapKey&components=country:FRA"; | |
var responseAutoCompleteSearch = | |
await RequestMethod.receiveRequest(urlAutoCompleteSearch); | |
print(responseAutoCompleteSearch); | |
if (responseAutoCompleteSearch == "Something went wrong") { | |
return; | |
} | |
print("Result from auto complete search: $responseAutoCompleteSearch"); | |
if (responseAutoCompleteSearch["status"] == "OK") { | |
var placePredictions = responseAutoCompleteSearch["predictions"]; | |
var placePredictionsList = (placePredictions as List).map((jsonData) { | |
// print("PREDICTION HERE IS: $jsonData"); | |
return PredictedPlaces.fromJson(jsonData); | |
}).toList(); | |
setState(() { | |
placesPredictedList = placePredictionsList; | |
}); | |
} | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
backgroundColor: const Color(0xffffffff), | |
elevation: 0, | |
leading: Builder( | |
builder: (BuildContext context) { | |
return GestureDetector( | |
onTap: () { | |
Navigator.pop(context); | |
}, | |
child: Container( | |
child: const Icon( | |
Icons.arrow_back, | |
color: Color(0xff3e3e3e), | |
size: 25.0, | |
), | |
), | |
); | |
}, | |
), | |
title: const Text( | |
'Enter New Address', | |
style: TextStyle( | |
color: Color(0xff3e3e3e), | |
fontSize: 15, | |
fontWeight: FontWeight.w500, | |
), | |
), | |
actions: <Widget>[ | |
PopupMenuButton( | |
onSelected: (result) async { | |
if (result == 0) { | |
Navigator.of(context).pop(); | |
} | |
}, | |
offset: const Offset(0, kToolbarHeight), | |
itemBuilder: (BuildContext context) => <PopupMenuEntry>[], | |
), | |
], | |
), | |
backgroundColor: const Color(0xffffffff), | |
body: Column( | |
children: [ | |
Container( | |
decoration: const BoxDecoration( | |
color: Colors.white, | |
), | |
child: Padding( | |
padding: const EdgeInsets.only(top: 10.0, bottom: 10.0), | |
child: Column( | |
mainAxisSize: MainAxisSize.min, | |
children: <Widget>[ | |
Container( | |
margin: const EdgeInsets.symmetric(horizontal: 20), | |
color: const Color(0xffededed), | |
height: 50, | |
child: TextFormField( | |
controller: _formController, | |
decoration: const InputDecoration( | |
fillColor: Color(0xff000000), | |
enabledBorder: OutlineInputBorder( | |
borderSide: BorderSide(color: Color(0xffededed)), | |
), | |
focusedBorder: OutlineInputBorder( | |
borderSide: BorderSide(color: Color(0xffededed)), | |
), | |
border: OutlineInputBorder( | |
borderSide: BorderSide( | |
color: Color(0xffededed), | |
), | |
), | |
focusColor: Color(0xff3e3e3e), | |
hintStyle: TextStyle( | |
color: Color(0xff3e3e3e), | |
fontSize: 15, | |
fontWeight: FontWeight.w300, | |
), | |
hintText: ('Search address'), | |
prefixIcon: const Icon( | |
Icons.search_rounded, | |
color: Color(0xff3e3e3e), | |
), | |
), | |
onChanged: (value) { | |
findPlaceAutoCompleteSearch(value); | |
print(value); | |
}, | |
), | |
), | |
const SizedBox(height: 10), | |
const Divider( | |
color: Color(0xffededed), | |
thickness: 2, | |
), | |
Container( | |
margin: | |
const EdgeInsets.symmetric(vertical: 5, horizontal: 20), | |
child: Row( | |
children: [ | |
// Container( | |
// width: 35, | |
// height: 35, | |
// child: const Icon( | |
// Icons.pin_drop_outlined, | |
// size: 20, | |
// color: Color(0xffffffff), | |
// ), | |
// decoration: const BoxDecoration( | |
// shape: BoxShape.circle, | |
// color: const Color(0xbf3e3e3e), | |
// ), | |
// ), | |
// const Padding( | |
// padding: EdgeInsets.all(8.0), | |
// child: Text( | |
// 'Previous Drop-off', | |
// style: TextStyle( | |
// color: Color(0xff3e3e3e), | |
// fontSize: 16, | |
// fontWeight: FontWeight.w600, | |
// ), | |
// ), | |
// ), | |
], | |
), | |
), | |
], | |
), | |
), | |
), | |
// const Divider( | |
// color: Color(0xffededed), | |
// thickness: 2, | |
// ), | |
// Container( | |
// margin: EdgeInsets.symmetric(vertical: 5, horizontal: 20), | |
// child: Row( | |
// children: [ | |
// Container( | |
// width: 35, | |
// height: 35, | |
// child: Icon(Icons.pin_drop_outlined, | |
// size: 20, color: Color(0xffffffff)), | |
// decoration: BoxDecoration( | |
// shape: BoxShape.circle, color: Color(0xbf3e3e3e)), | |
// ), | |
// Padding( | |
// padding: const EdgeInsets.all(8.0), | |
// child: const Text( | |
// 'Previous Drop-off', | |
// style: TextStyle( | |
// color: Color(0xff3e3e3e), | |
// fontSize: 16, | |
// fontWeight: FontWeight.w600, | |
// ), | |
// ), | |
// ), | |
// ], | |
// ), | |
// ), | |
//list view for predictions | |
(placesPredictedList.isNotEmpty) | |
? Expanded( | |
child: ListView.separated( | |
itemCount: placesPredictedList.length, | |
itemBuilder: (context, int index) { | |
return Container( | |
padding: const EdgeInsets.symmetric( | |
horizontal: 10, | |
vertical: 5, | |
), | |
child: PlacePredictionTile( | |
predictedPlaces: placesPredictedList[index], | |
), | |
); | |
}, | |
separatorBuilder: (BuildContext context, int index) { | |
return const Divider( | |
height: 2, | |
thickness: 1, | |
color: Colors.white, | |
); | |
}, | |
), | |
) | |
: Container(), | |
], | |
), | |
); | |
} | |
Widget _textField({ | |
required TextEditingController controller, | |
FocusNode? focusNode, | |
required String label, | |
required String hint, | |
required double width, | |
required Icon prefixIcon, | |
required Function(String) locationCallback, | |
}) { | |
return Container( | |
width: width * 0.8, | |
child: TextField( | |
onChanged: (value) { | |
locationCallback(value); | |
}, | |
controller: controller, | |
focusNode: focusNode, | |
decoration: InputDecoration( | |
prefixIcon: prefixIcon, | |
labelText: label, | |
filled: true, | |
fillColor: Colors.white, | |
enabledBorder: OutlineInputBorder( | |
borderRadius: const BorderRadius.all( | |
Radius.circular(10.0), | |
), | |
borderSide: BorderSide( | |
color: Colors.grey.shade400, | |
width: 2, | |
), | |
), | |
focusedBorder: OutlineInputBorder( | |
borderRadius: const BorderRadius.all( | |
Radius.circular(10.0), | |
), | |
borderSide: BorderSide( | |
color: Colors.blue.shade300, | |
width: 2, | |
), | |
), | |
contentPadding: const EdgeInsets.all(15), | |
hintText: hint, | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
file_name : request_method.dart
`import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
class RequestMethod {
static Future receiveRequest(String url) async {
}
}`