diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 4aced6fc9ab5cc52a337b36eff08862b639b0ccb..89d872b66336adb9f8e2ab01480213fd85ba1e4f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -30,5 +30,9 @@ <meta-data android:name="flutterEmbedding" android:value="2" /> + <meta-data android:name="com.google.andoid.geo.API_KEY" + android:value="AIzaSyAzedQacDEZmyxAOUEEeocvehT8MEdMWys"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> </application> </manifest> diff --git a/assets/destMarker.png b/assets/destMarker.png new file mode 100644 index 0000000000000000000000000000000000000000..d41ee5806ea6b43c51c1582bea22131fc4152ef9 Binary files /dev/null and b/assets/destMarker.png differ diff --git a/assets/originMarker.png b/assets/originMarker.png new file mode 100644 index 0000000000000000000000000000000000000000..da3a41688f7a49b84d51c217ab2309897f6f4cf0 Binary files /dev/null and b/assets/originMarker.png differ diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2c081ca474dc39948c24ac7fdd737301db822abd..2ab740a9787f625462f889072aeb26ea2b78a285 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -4,11 +4,33 @@ PODS: - Flutter - geocoder (0.0.1): - Flutter + - geocoding_ios (1.0.5): + - Flutter + - geolocator_apple (1.2.0): + - Flutter + - google_maps_flutter_ios (0.0.1): + - Flutter + - GoogleMaps + - GoogleMaps (5.2.0): + - GoogleMaps/Maps (= 5.2.0) + - GoogleMaps/Base (5.2.0) + - GoogleMaps/Maps (5.2.0): + - GoogleMaps/Base + - location (0.0.1): + - Flutter DEPENDENCIES: - Flutter (from `Flutter`) - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) - geocoder (from `.symlinks/plugins/geocoder/ios`) + - geocoding_ios (from `.symlinks/plugins/geocoding_ios/ios`) + - geolocator_apple (from `.symlinks/plugins/geolocator_apple/ios`) + - google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`) + - location (from `.symlinks/plugins/location/ios`) + +SPEC REPOS: + trunk: + - GoogleMaps EXTERNAL SOURCES: Flutter: @@ -17,11 +39,24 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" geocoder: :path: ".symlinks/plugins/geocoder/ios" + geocoding_ios: + :path: ".symlinks/plugins/geocoding_ios/ios" + geolocator_apple: + :path: ".symlinks/plugins/geolocator_apple/ios" + google_maps_flutter_ios: + :path: ".symlinks/plugins/google_maps_flutter_ios/ios" + location: + :path: ".symlinks/plugins/location/ios" SPEC CHECKSUMS: Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 geocoder: 3cfab70531a0b367e917bafe82df4c30f6d4c45a + geocoding_ios: a389ea40f6f548de6e63006a2e31bf66ff80769a + geolocator_apple: cc556e6844d508c95df1e87e3ea6fa4e58c50401 + google_maps_flutter_ios: 3e0b99383a8003b8169d06e7e324170bd0424105 + GoogleMaps: 025272d5876d3b32604e5c080dc25eaf68764693 + location: 3a2eed4dd2fab25e7b7baf2a9efefe82b512d740 PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a6bced3294a836e53d5152d892304aa5e17946b8..32a1b47c29f68e43a3b09877ea8a0ea9db1c3f80 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -68,7 +68,6 @@ A7B92C277CEDD40DE17CA3E7 /* Pods-Runner.release.xcconfig */, 158D80A13A80AEF06A81D155 /* Pods-Runner.profile.xcconfig */, ); - name = Pods; path = Pods; sourceTree = "<group>"; }; @@ -140,6 +139,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 2B9445729AF37972D8DF8E85 /* [CP] Embed Pods Frameworks */, + 89B2A8318CC2B1F42C3CC7FF /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -230,6 +230,23 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 89B2A8318CC2B1F42C3CC7FF /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -358,13 +375,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = WQ97GY8U8F; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.routerApp; + PRODUCT_BUNDLE_IDENTIFIER = com.testing.routerApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -486,13 +504,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = WQ97GY8U8F; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.routerApp; + PRODUCT_BUNDLE_IDENTIFIER = com.testing.routerApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -508,13 +527,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = WQ97GY8U8F; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.routerApp; + PRODUCT_BUNDLE_IDENTIFIER = com.testing.routerApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4a8c128fc4350b157416374ca599ac8c7b..828fbd3d92dad930a2486b3f6b1797c0d58c7ec6 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,4 +1,5 @@ import UIKit +import GoogleMaps import Flutter @UIApplicationMain @@ -7,6 +8,7 @@ import Flutter _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { + GMSServices.provideAPIKey("AIzaSyAzedQacDEZmyxAOUEEeocvehT8MEdMWys") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index e44f1cdcbf8cd970490981b426fed01d2a3b18ec..648d01f65345a5368d15f251ec0e6406448c9d5c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -2,6 +2,8 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>CADisableMinimumFrameDurationOnPhone</key> + <true/> <key>CFBundleDevelopmentRegion</key> <string>$(DEVELOPMENT_LANGUAGE)</string> <key>CFBundleDisplayName</key> @@ -24,6 +26,14 @@ <string>$(FLUTTER_BUILD_NUMBER)</string> <key>LSRequiresIPhoneOS</key> <true/> + <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> + <string>This app needs access to location when open and in the background.</string> + <key>NSLocationAlwaysUsageDescription</key> + <string>This app needs access to location when in the background.</string> + <key>NSLocationWhenInUseUsageDescription</key> + <string>This app needs access to location when open.</string> + <key>UIApplicationSupportsIndirectInputEvents</key> + <true/> <key>UILaunchStoryboardName</key> <string>LaunchScreen</string> <key>UIMainStoryboardFile</key> @@ -43,9 +53,5 @@ </array> <key>UIViewControllerBasedStatusBarAppearance</key> <false/> - <key>CADisableMinimumFrameDurationOnPhone</key> - <true/> - <key>UIApplicationSupportsIndirectInputEvents</key> - <true/> </dict> </plist> diff --git a/lib/main.dart b/lib/main.dart index b4a81bb319b5686065ee2f0a2efc0ae3258ba3fe..777ef3e4b72c47c56d37ed7e9c842fa2a47cca3a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,14 @@ // ignore_for_file: prefer_const_constructors, sort_child_properties_last, import_of_legacy_library_into_null_safe, prefer_is_not_empty, unnecessary_null_comparison, deprecated_member_use, depend_on_referenced_packages import 'package:flutter/material.dart'; -import 'package:http/http.dart' as http; +import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:intl/intl.dart'; -import './widgets/map.dart'; -import 'widgets/returnStarting.dart'; -import './widgets/returnDestination.dart'; -import 'dart:async'; +import 'widgets/returnOrigin.dart'; +import 'widgets/returnDestination.dart'; +import 'widgets/directionsRepo.dart'; +import 'widgets/directions.dart'; +import 'package:geocoding/geocoding.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:http/http.dart' as http; import 'dart:convert'; void main() => runApp(MyApp()); @@ -20,7 +23,7 @@ class MyApp extends StatelessWidget { home: MyHomePage(), theme: ThemeData( fontFamily: 'Rubik', - primaryColor: Color.fromRGBO(22, 31, 68, 0.898), + primaryColor: Color.fromRGBO(22, 31, 68, 0.95), accentColor: Color.fromRGBO(250, 250, 250, 0.85), ), ); @@ -35,82 +38,114 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State<MyHomePage> { - String startingText = 'Starting Point'; - String destinationText = 'Destination'; - bool isDateChosen = false; - DateTimeRange dateRange = DateTimeRange( + // Initial map coords and map controller to control camera movements. + static const _initialCameraPosition = + CameraPosition(target: LatLng(52.5163, 13.3777), zoom: 12); + late GoogleMapController _mapController; + + // Set origin/dest coords, respective markers, lat/lng coords between poits and polyline corresponding to coords. + late LatLng _originCoordinates; + late LatLng _destCoordinates; + final Set<Marker> _markers = {}; + late Directions _info; + final Set<Polyline> _polyline = {}; + + // Input field texts for origin/dest points. + String originText = 'Starting Point...'; + String destinationText = 'Destination...'; + + // Variables for calendar + DateTimeRange _dateRange = DateTimeRange( start: DateTime.now(), end: DateTime.now(), ); + bool _isDateChosen = false; + FloatingActionButtonLocation _floatingActionButtonLocation = FloatingActionButtonLocation.centerFloat; - String get getStartingText { - if (startingText != null) { - if (startingText.length > 15) { - return '${startingText.substring(0, 15)}...'; + // Format text. + String getFormattedText(String inputText) { + if (inputText != null) { + if (inputText.length > 15) { + return '${inputText.substring(0, 15)}...'; } } - return startingText; - } - - String get getDestinationText { - if (destinationText != null) { - if (destinationText.length > 15) { - return '${destinationText.substring(0, 15)}...'; - } - } - return destinationText; + return inputText; } + // Wait return value of input page to take origin point and update it's coords. void _awaitStartingPointReturnValue(BuildContext context) async { final result = await Navigator.push( context, MaterialPageRoute( - builder: (context) => ReturnStarting(), + builder: (context) => ReturnOrigin(originText), ), ); if (result != null) { + List<Location> originLoc = await locationFromAddress(result); setState(() { - startingText = result; + originText = result; + _originCoordinates = + LatLng(originLoc[0].latitude, originLoc[0].longitude); }); } + // Toggle keyboard + FocusManager.instance.primaryFocus?.unfocus(); + // Animate camera to the starting point. + _mapController.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition(target: _originCoordinates, zoom: 14), + ), + ); } + // Wait return value of input page to take dest point and update it's coords. void _awaitDestinationPointReturnValue(BuildContext context) async { final result = await Navigator.push( context, MaterialPageRoute( - builder: (context) => ReturnDestination(), + builder: (context) => ReturnDestination(destinationText), ), ); if (result != null) { + List<Location> destLoc = await locationFromAddress(result); setState( () { destinationText = result; + _destCoordinates = LatLng(destLoc[0].latitude, destLoc[0].longitude); }, ); } + // Toggle keyboard + FocusManager.instance.primaryFocus?.unfocus(); + // Animate camera to the destination point. + _mapController.animateCamera( + CameraUpdate.newCameraPosition( + CameraPosition(target: _destCoordinates, zoom: 14), + ), + ); } + // Pick date _rangeDatePicker(BuildContext ctx) async { DateTimeRange? newDateTimeRange = await showDateRangePicker( initialEntryMode: DatePickerEntryMode.calendarOnly, context: context, firstDate: DateTime.now(), lastDate: DateTime(DateTime.now().year + 2), - initialDateRange: dateRange, + initialDateRange: _dateRange, builder: (context, child) { return Theme( data: Theme.of(context).copyWith( colorScheme: ColorScheme.light( - primary: Theme.of(context).primaryColor, // <-- SEE HERE - onPrimary: Theme.of(context).accentColor, // <-- SEE HERE - onSurface: Theme.of(context).accentColor, // <-- SEE HERE + primary: Theme.of(context).primaryColor, + onPrimary: Theme.of(context).accentColor, + onSurface: Theme.of(context).accentColor, ), textButtonTheme: TextButtonThemeData( style: TextButton.styleFrom( - primary: Theme.of(context).accentColor, // button text color + primary: Theme.of(context).accentColor, // Button text color ), ), ), @@ -119,13 +154,15 @@ class _MyHomePageState extends State<MyHomePage> { }, ); + // Update chosen date of global date variable. if (newDateTimeRange == null) return; setState(() { - dateRange = newDateTimeRange; - isDateChosen = true; + _dateRange = newDateTimeRange; + _isDateChosen = true; }); } + // Format and display date. String convertDateFormat(date) { DateFormat formatter = DateFormat('dd/MM'); String formatted = formatter.format(date); @@ -133,18 +170,117 @@ class _MyHomePageState extends State<MyHomePage> { } String displayDate() { - if (isDateChosen) { - return "${convertDateFormat(dateRange.start)} - ${convertDateFormat(dateRange.end)}"; + if (_isDateChosen) { + return "${convertDateFormat(_dateRange.start)} - ${convertDateFormat(_dateRange.end)}"; } return ''; } + // Get shortest path. + void _getShortestPath() async { + _addMarker(); + + _getDirections(); + + _drawPolyline(); + + // Animate camera to the shortest path. + _mapController.animateCamera( + CameraUpdate.newLatLngBounds(_info.bounds, 100.0), + ); + } + + // Add markers for origin/dest coords. + void _addMarker() { + _markers.add( + Marker( + markerId: MarkerId('origin'), + infoWindow: InfoWindow(title: 'Origin'), + icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueAzure), + position: _originCoordinates, + ), + ); + + _markers.add( + Marker( + markerId: MarkerId('destination'), + infoWindow: InfoWindow(title: 'Destination'), + icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueRed), + position: _destCoordinates, + ), + ); + + setState(() { + _markers; + }); + } + + // Get coords between origin/dest points corresponding to shortest path and update _info. + // This part is going to be updated to take directions from backend instead of Direction API. + void _getDirections() async { + final directions = await DirectionsRepo().getDirections( + origin: _originCoordinates, destination: _destCoordinates); + + setState(() { + _info = directions; + }); + } + + // Draw Polyline between given list of coordinates and update _polyline.. + void _drawPolyline() { + _polyline.add(Polyline( + polylineId: PolylineId("polylineId"), + color: Theme.of(context).primaryColor, + width: 4, + points: _info.polylinePoints + .map((e) => LatLng(e.latitude, e.longitude)) + .toList(), + )); + + setState(() { + _polyline; + }); + } + + // Get user location info with geolocation. + _getCurrentLocation() async { + await Geolocator.requestPermission().then( + (value) => { + Geolocator.getCurrentPosition( + desiredAccuracy: LocationAccuracy.best, + forceAndroidLocationManager: true) + .then( + (Position position) async { + final url = Uri.parse( + 'https://maps.googleapis.com/maps/api/geocode/json?latlng=${position.latitude},${position.longitude}&key='); + final response = await http.get(url); + setState(() { + originText = + json.decode(response.body)['results'][0]['formatted_address']; + }); + }, + ).catchError( + (e) { + throw Error(); + }, + ), + }, + ); + } + @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ - Map(), + GoogleMap( + initialCameraPosition: _initialCameraPosition, + myLocationButtonEnabled: false, + zoomControlsEnabled: false, + onMapCreated: (controller) => _mapController = controller, + markers: _markers, + polylines: _polyline, + ), Column( children: [ // Starting Input @@ -184,8 +320,8 @@ class _MyHomePageState extends State<MyHomePage> { color: Color.fromRGBO(20, 20, 20, 1), ), border: InputBorder.none, - prefixText: getStartingText, - labelText: getStartingText, + prefixText: getFormattedText(originText), + labelText: getFormattedText(originText), floatingLabelBehavior: FloatingLabelBehavior.never, ), style: TextStyle( @@ -200,11 +336,14 @@ class _MyHomePageState extends State<MyHomePage> { SizedBox( height: 45, child: Container( - padding: EdgeInsets.only(right: 17, left: 10), - child: Icon( - Icons.my_location_outlined, - size: 24, - color: Theme.of(context).primaryColor, + padding: EdgeInsets.only(right: 6, left: 10), + child: IconButton( + iconSize: 24, + icon: Icon( + Icons.my_location_outlined, + color: Theme.of(context).primaryColor, + ), + onPressed: _getCurrentLocation, ), ), ), @@ -247,8 +386,8 @@ class _MyHomePageState extends State<MyHomePage> { color: Color.fromRGBO(20, 20, 20, 1), ), border: InputBorder.none, - prefixText: getDestinationText, - labelText: getDestinationText, + prefixText: getFormattedText(destinationText), + labelText: getFormattedText(destinationText), floatingLabelBehavior: FloatingLabelBehavior.never, ), style: TextStyle( @@ -276,7 +415,6 @@ class _MyHomePageState extends State<MyHomePage> { ], ), ), - // Insert Date to Map ], ), DraggableScrollableSheet( @@ -287,7 +425,10 @@ class _MyHomePageState extends State<MyHomePage> { return Container( margin: EdgeInsets.only(top: 0), decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), + borderRadius: BorderRadius.only( + topRight: Radius.circular(20), + topLeft: Radius.circular(20), + ), color: Theme.of(context).primaryColor, ), child: NotificationListener( @@ -340,9 +481,9 @@ class _MyHomePageState extends State<MyHomePage> { floatingActionButton: Container( padding: EdgeInsets.only(bottom: 50), child: FloatingActionButton.extended( - onPressed: () {}, + onPressed: _getShortestPath, label: Text( - 'Get route', + 'Get Route', style: TextStyle( fontSize: 18, ), diff --git a/lib/widgets/directions.dart b/lib/widgets/directions.dart new file mode 100644 index 0000000000000000000000000000000000000000..b9ef276dffc5ba99b7caee1299cc911a41256052 --- /dev/null +++ b/lib/widgets/directions.dart @@ -0,0 +1,33 @@ +// ignore_for_file: import_of_legacy_library_into_null_safe + +import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +class Directions { + final LatLngBounds bounds; + final List<PointLatLng> polylinePoints; + + const Directions({ + required this.bounds, + required this.polylinePoints, + }); + + factory Directions.fromMap(Map<String, dynamic> map) { + // Get route information + final data = Map<String, dynamic>.from(map['routes'][0]); + + // Bounds + final northeast = data['bounds']['northeast']; + final southwest = data['bounds']['southwest']; + final bounds = LatLngBounds( + northeast: LatLng(northeast['lat'], northeast['lng']), + southwest: LatLng(southwest['lat'], southwest['lng']), + ); + + return Directions( + bounds: bounds, + polylinePoints: + PolylinePoints().decodePolyline(data['overview_polyline']['points']), + ); + } +} diff --git a/lib/widgets/directionsRepo.dart b/lib/widgets/directionsRepo.dart new file mode 100644 index 0000000000000000000000000000000000000000..0766f121cdcd6dae0e3c6f90bf61e67caf8446ef --- /dev/null +++ b/lib/widgets/directionsRepo.dart @@ -0,0 +1,35 @@ +// ignore_for_file: file_names + +import 'package:dio/dio.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import './directions.dart'; + +class DirectionsRepo { + static const String _baseUrl = + 'https://maps.googleapis.com/maps/api/directions/json?'; + + final Dio _dio; + + DirectionsRepo({Dio? dio}) : _dio = dio ?? Dio(); + + Future<Directions> getDirections({ + required LatLng origin, + required LatLng destination, + }) async { + final response = await _dio.get( + _baseUrl, + queryParameters: { + 'origin': '${origin.latitude},${origin.longitude}', + 'destination': '${destination.latitude},${destination.longitude}', + 'key': '', + }, + ); + + // Check if response is successful + if (response.statusCode == 200) { + return Directions.fromMap(response.data); + } else { + throw Error(); + } + } +} diff --git a/lib/widgets/map.dart b/lib/widgets/map.dart deleted file mode 100644 index 7ce93663696a262fbfa076cc0b21db5882a04b89..0000000000000000000000000000000000000000 --- a/lib/widgets/map.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_map/flutter_map.dart'; -import 'package:latlong/latlong.dart'; -import 'package:flutter_map/plugin_api.dart'; // Only import if required functionality is not exposed by default -import 'package:intl/intl.dart'; - -class Map extends StatefulWidget { - const Map({super.key}); - - @override - State<Map> createState() => _MapState(); -} - -class _MapState extends State<Map> { - LatLng markerPoint = LatLng(52.5163, 13.3777); - - @override - Widget build(BuildContext context) { - return FlutterMap( - options: MapOptions( - onTap: (p) { - setState(() { - markerPoint = p; - }); - }, - center: LatLng(52.5163, 13.3777), - zoom: 13, - ), - layers: [ - TileLayerOptions( - urlTemplate: - 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{@2x}.png', - subdomains: ['a', 'b', 'c'], - ), - MarkerLayerOptions(markers: [ - Marker( - width: 200, - height: 200, - point: markerPoint, - builder: (context) => const Icon( - Icons.location_on, - color: Colors.red, - ), - ) - ]) - ], - ); - } -} diff --git a/lib/widgets/returnDestination.dart b/lib/widgets/returnDestination.dart index 8647b8e5b3379bb500bd66c23337058699d2902d..b2675023ae421f2067a5d684c16ac974ca84dfc3 100644 --- a/lib/widgets/returnDestination.dart +++ b/lib/widgets/returnDestination.dart @@ -1,4 +1,4 @@ -// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors +// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, prefer_is_not_empty import 'dart:convert'; @@ -7,6 +7,8 @@ import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:http/http.dart' as http; class ReturnDestination extends StatefulWidget { + String destinationText; + ReturnDestination(this.destinationText); @override State<ReturnDestination> createState() => _ReturnDestinationState(); } @@ -16,28 +18,15 @@ class _ReturnDestinationState extends State<ReturnDestination> { List<String> suggestions = []; Future<List<String>> fetchLocation(String query) async { - final cityResponse = await http.get( + final response = await http.get( Uri.parse( - 'https://api.geoapify.com/v1/geocode/autocomplete?text=$query&type=city&format=json&apiKey=bc28b0ffd28a458c866bf21813ada611', + 'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$query&radius=500&key=', ), ); - - final streetResponse = await http.get( - Uri.parse( - 'https://api.geoapify.com/v1/geocode/autocomplete?text=$query&type=street&format=json&apiKey=bc28b0ffd28a458c866bf21813ada611', - ), - ); - - var jsonDataCity = jsonDecode(cityResponse.body); - var jsonDataStreet = jsonDecode(streetResponse.body); + var jsonData = jsonDecode(response.body); suggestions = []; - suggestions.add( - jsonDataCity['results'][0]['formatted'].toString(), - ); - for (var i = 0; i < 6; i++) { - suggestions.add( - jsonDataStreet['results'][i]['formatted'].toString(), - ); + for (int i = 0; i < 10; i++) { + suggestions.add(jsonData['predictions'][i]['description'].toString()); } return suggestions; } @@ -51,77 +40,110 @@ class _ReturnDestinationState extends State<ReturnDestination> { @override Widget build(BuildContext context) { return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).primaryColor, + title: Text( + 'Destination Point', + style: TextStyle( + color: Theme.of(context).accentColor, + fontSize: 24, + ), + ), + leading: IconButton( + iconSize: 26, + icon: Icon( + Icons.arrow_back_ios_rounded, + color: Theme.of(context).accentColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ), body: Container( - margin: EdgeInsets.only(top: 60, right: 35), child: Column( children: [ - Row( - children: [ - IconButton( - icon: Icon( - Icons.arrow_back_ios_rounded, - color: Theme.of(context).primaryColor, - ), - onPressed: () { - Navigator.pop(context); - }, - ), - Expanded( - child: TypeAheadField( - animationStart: 0, - animationDuration: Duration.zero, - textFieldConfiguration: TextFieldConfiguration( - onSubmitted: (_) { - _sendDataBack(context); - }, - controller: textFieldController, - autofocus: false, - decoration: InputDecoration( - labelText: 'Destination', - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - borderRadius: - BorderRadius.all(Radius.circular(30))), + Container( + margin: EdgeInsets.only(top: 15, right: 20, left: 20), + child: Row( + children: [ + Expanded( + child: Container( + padding: EdgeInsets.only(left: 20), + decoration: BoxDecoration( + border: Border.all( + width: 1.5, + color: Theme.of(context).primaryColor, + ), + borderRadius: BorderRadius.all( + Radius.circular(30), + ), ), - style: TextStyle( - fontSize: 20, - ), - ), - suggestionsBoxDecoration: - SuggestionsBoxDecoration(elevation: 0), - suggestionsCallback: (pattern) { - fetchLocation(pattern); - return suggestions; - }, - itemBuilder: (context, textField) { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - child: Icon( - Icons.location_city_rounded, + height: 50, + child: TypeAheadField( + animationStart: 0, + animationDuration: Duration.zero, + textFieldConfiguration: TextFieldConfiguration( + onSubmitted: (_) { + _sendDataBack(context); + }, + controller: textFieldController, + autofocus: false, + decoration: InputDecoration( + border: InputBorder.none, + labelStyle: TextStyle( + color: Theme.of(context).primaryColor, ), + labelText: widget.destinationText, + floatingLabelBehavior: FloatingLabelBehavior.never, ), - Expanded( - child: Container( - margin: EdgeInsets.all(10), - width: double.infinity, - child: Text( - textField.toString(), - style: TextStyle(fontSize: 20), - ), - ), + style: TextStyle( + fontSize: 22, + color: Theme.of(context).primaryColor, ), - ], - ); - }, - onSuggestionSelected: (suggestion) { - textFieldController.text = suggestion.toString(); - _sendDataBack(context); - }, + ), + suggestionsBoxDecoration: + SuggestionsBoxDecoration(elevation: 0), + suggestionsCallback: (pattern) { + fetchLocation(pattern); + return suggestions; + }, + itemBuilder: (context, textField) { + return Container( + padding: EdgeInsets.only(top: 1), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + child: Icon(Icons.location_city_rounded, + color: Theme.of(context).primaryColor), + ), + Expanded( + child: Container( + margin: EdgeInsets.all(10), + width: double.infinity, + child: Text( + textField.toString(), + style: TextStyle( + fontSize: 21, + color: Theme.of(context).primaryColor, + ), + ), + ), + ), + ], + ), + ); + }, + onSuggestionSelected: (suggestion) { + textFieldController.text = suggestion.toString(); + _sendDataBack(context); + }, + ), + ), ), - ), - ], + ], + ), ), ], ), diff --git a/lib/widgets/returnOrigin.dart b/lib/widgets/returnOrigin.dart new file mode 100644 index 0000000000000000000000000000000000000000..67af48b998903cc60992d83396a8163f52d25808 --- /dev/null +++ b/lib/widgets/returnOrigin.dart @@ -0,0 +1,152 @@ +// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, prefer_is_not_empty + +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:flutter_typeahead/flutter_typeahead.dart'; +import 'package:http/http.dart' as http; + +class ReturnOrigin extends StatefulWidget { + String originText; + ReturnOrigin(this.originText); + @override + State<ReturnOrigin> createState() => _ReturnOriginState(); +} + +class _ReturnOriginState extends State<ReturnOrigin> { + TextEditingController textFieldController = TextEditingController(); + List<String> suggestions = []; + + Future<List<String>> fetchLocation(String query) async { + final response = await http.get( + Uri.parse( + 'https://maps.googleapis.com/maps/api/place/autocomplete/json?input=$query&radius=500&key=', + ), + ); + var jsonData = jsonDecode(response.body); + suggestions = []; + for (int i = 0; i < 10; i++) { + suggestions.add(jsonData['predictions'][i]['description'].toString()); + } + return suggestions; + } + + void _sendDataBack(BuildContext context) { + String textToSendBack = textFieldController.text; + if (textToSendBack.isEmpty) return; + Navigator.pop(context, textToSendBack); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Theme.of(context).primaryColor, + title: Text( + 'Starting Point', + style: TextStyle( + color: Theme.of(context).accentColor, + fontSize: 24, + ), + ), + leading: IconButton( + iconSize: 26, + icon: Icon( + Icons.arrow_back_ios_rounded, + color: Theme.of(context).accentColor, + ), + onPressed: () { + Navigator.pop(context); + }, + ), + ), + body: Container( + child: Column( + children: [ + Container( + margin: EdgeInsets.only(top: 15, right: 20, left: 20), + child: Row( + children: [ + Expanded( + child: Container( + padding: EdgeInsets.only(left: 20), + decoration: BoxDecoration( + border: Border.all( + width: 1.5, + color: Theme.of(context).primaryColor, + ), + borderRadius: BorderRadius.all( + Radius.circular(30), + ), + ), + height: 50, + child: TypeAheadField( + animationStart: 0, + animationDuration: Duration.zero, + textFieldConfiguration: TextFieldConfiguration( + onSubmitted: (_) { + _sendDataBack(context); + }, + controller: textFieldController, + autofocus: false, + decoration: InputDecoration( + border: InputBorder.none, + labelStyle: TextStyle( + color: Theme.of(context).primaryColor, + ), + labelText: widget.originText, + floatingLabelBehavior: FloatingLabelBehavior.never, + ), + style: TextStyle( + fontSize: 22, + color: Theme.of(context).primaryColor, + ), + ), + suggestionsBoxDecoration: + SuggestionsBoxDecoration(elevation: 0), + suggestionsCallback: (pattern) { + fetchLocation(pattern); + return suggestions; + }, + itemBuilder: (context, textField) { + return Container( + padding: EdgeInsets.only(top: 1), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + child: Icon(Icons.location_city_rounded, + color: Theme.of(context).primaryColor), + ), + Expanded( + child: Container( + margin: EdgeInsets.all(10), + width: double.infinity, + child: Text( + textField.toString(), + style: TextStyle( + fontSize: 21, + color: Theme.of(context).primaryColor, + ), + ), + ), + ), + ], + ), + ); + }, + onSuggestionSelected: (suggestion) { + textFieldController.text = suggestion.toString(); + _sendDataBack(context); + }, + ), + ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/returnStarting.dart b/lib/widgets/returnStarting.dart deleted file mode 100644 index 75834968ecce8f4c06ae4b9140456c36661377df..0000000000000000000000000000000000000000 --- a/lib/widgets/returnStarting.dart +++ /dev/null @@ -1,131 +0,0 @@ -// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, prefer_is_not_empty - -import 'dart:convert'; - -import 'package:flutter/material.dart'; -import 'package:flutter_typeahead/flutter_typeahead.dart'; -import 'package:http/http.dart' as http; - -class ReturnStarting extends StatefulWidget { - @override - State<ReturnStarting> createState() => _ReturnStartingState(); -} - -class _ReturnStartingState extends State<ReturnStarting> { - TextEditingController textFieldController = TextEditingController(); - List<String> suggestions = []; - - Future<List<String>> fetchLocation(String query) async { - final cityResponse = await http.get( - Uri.parse( - 'https://api.geoapify.com/v1/geocode/autocomplete?text=$query&type=city&format=json&apiKey=bc28b0ffd28a458c866bf21813ada611', - ), - ); - - final streetResponse = await http.get( - Uri.parse( - 'https://api.geoapify.com/v1/geocode/autocomplete?text=$query&type=street&format=json&apiKey=bc28b0ffd28a458c866bf21813ada611', - ), - ); - - var jsonDataCity = jsonDecode(cityResponse.body); - var jsonDataStreet = jsonDecode(streetResponse.body); - suggestions = []; - suggestions.add( - jsonDataCity['results'][0]['formatted'].toString(), - ); - for (var i = 0; i < 6; i++) { - suggestions.add( - jsonDataStreet['results'][i]['formatted'].toString(), - ); - } - return suggestions; - } - - void _sendDataBack(BuildContext context) { - String textToSendBack = textFieldController.text; - if (textToSendBack.isEmpty) return; - Navigator.pop(context, textToSendBack); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - margin: EdgeInsets.only(top: 60, right: 35), - child: Column( - children: [ - Row( - children: [ - IconButton( - icon: Icon( - Icons.arrow_back_ios_rounded, - color: Theme.of(context).primaryColor, - ), - onPressed: () { - Navigator.pop(context); - }, - ), - Expanded( - child: TypeAheadField( - animationStart: 0, - animationDuration: Duration.zero, - textFieldConfiguration: TextFieldConfiguration( - onSubmitted: (_) { - _sendDataBack(context); - }, - controller: textFieldController, - autofocus: false, - decoration: InputDecoration( - labelText: 'Starting Point', - border: OutlineInputBorder( - borderSide: BorderSide(color: Colors.black), - borderRadius: - BorderRadius.all(Radius.circular(30))), - ), - style: TextStyle( - fontSize: 20, - ), - ), - suggestionsBoxDecoration: - SuggestionsBoxDecoration(elevation: 0), - suggestionsCallback: (pattern) { - fetchLocation(pattern); - return suggestions; - }, - itemBuilder: (context, textField) { - return Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - child: Icon( - Icons.location_city_rounded, - ), - ), - Expanded( - child: Container( - margin: EdgeInsets.all(10), - width: double.infinity, - child: Text( - textField.toString(), - style: TextStyle(fontSize: 20), - ), - ), - ), - ], - ); - }, - onSuggestionSelected: (suggestion) { - textFieldController.text = suggestion.toString(); - _sendDataBack(context); - }, - ), - ), - ], - ), - ], - ), - ), - ); - } -} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817a52206e8a8eef501faed292993ff21a31..b1d4adfbdf1422da8430563631b9342fe82cfa69 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,10 @@ import FlutterMacOS import Foundation +import geolocator_apple +import location func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 5b19a102760cc6da9cb0a3734b2e6253b161f836..d0380820a4a861a9557ef7151481da98c1e0ecc5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -65,6 +65,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + dio: + dependency: "direct main" + description: + name: dio + sha256: "7d328c4d898a61efc3cd93655a0955858e29a0aa647f0f9e02d59b3bb275e2e8" + url: "https://pub.dev" + source: hosted + version: "4.0.6" fake_async: dependency: transitive description: @@ -150,6 +158,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.12.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf + url: "https://pub.dev" + source: hosted + version: "2.0.9" + flutter_polyline_points: + dependency: "direct main" + description: + name: flutter_polyline_points + sha256: "1544a383c30dfa0117b02785a28da8b27dc595897a2f1f90980a2a6276e6c0e3" + url: "https://pub.dev" + source: hosted + version: "0.2.6" flutter_test: dependency: "direct dev" description: flutter @@ -176,6 +200,118 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1" + geocoding: + dependency: "direct main" + description: + name: geocoding + sha256: b34c0501bbbaf3190b85bef3078b27cf66c28a8915c6d3af50d67f356aa7da31 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + geocoding_android: + dependency: transitive + description: + name: geocoding_android + sha256: "5a1fc0cec9b0497b44ca31c1fa8d1c891f3aded1053e6bb2eac075d3bd1bf046" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + geocoding_ios: + dependency: transitive + description: + name: geocoding_ios + sha256: c85495ce8fb34e4fbd2dd8fc5f79263d622d9f88c4af948c965daf6b27a7f3a1 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + geocoding_platform_interface: + dependency: transitive + description: + name: geocoding_platform_interface + sha256: "8848605d307d844d89937cdb4b8ad7dfa880552078f310fa24d8a460f6dddab4" + url: "https://pub.dev" + source: hosted + version: "2.0.1" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: "5c23f3613f50586c0bbb2b8f970240ae66b3bd992088cf60dd5ee2e6f7dde3a8" + url: "https://pub.dev" + source: hosted + version: "9.0.2" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: "2ba24690aee0a3e1b6b7bd47c2711a50c874e95e4c758346589d35194adf6d6a" + url: "https://pub.dev" + source: hosted + version: "4.1.7" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: "22b60ca3b8c0f58e6a9688ff855ee39ab813ca3f0c0609a48d282f6631266f2e" + url: "https://pub.dev" + source: hosted + version: "2.2.5" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: af4d69231452f9620718588f41acc4cb58312368716bfff2e92e770b46ce6386 + url: "https://pub.dev" + source: hosted + version: "4.0.7" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: f68a122da48fcfff68bbc9846bb0b74ef651afe84a1b1f6ec20939de4d6860e1 + url: "https://pub.dev" + source: hosted + version: "2.1.6" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: f5911c88e23f48b598dd506c7c19eff0e001645bdc03bb6fecb9f4549208354d + url: "https://pub.dev" + source: hosted + version: "0.1.1" + google_maps_flutter: + dependency: "direct main" + description: + name: google_maps_flutter + sha256: "24392ef192f3b00bcd93151375676805a9933574423a5bd5509a0ead2e8a4215" + url: "https://pub.dev" + source: hosted + version: "2.2.5" + google_maps_flutter_android: + dependency: transitive + description: + name: google_maps_flutter_android + sha256: a8ee18649a67750cbd477a6867a1bf9c4154c5e9f69d722c8b53a627a6d58303 + url: "https://pub.dev" + source: hosted + version: "2.4.9" + google_maps_flutter_ios: + dependency: transitive + description: + name: google_maps_flutter_ios + sha256: e9ad74415a222573625a2c1717adc1e375b18e8ce660fc12db734d1bda1132d4 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + google_maps_flutter_platform_interface: + dependency: transitive + description: + name: google_maps_flutter_platform_interface + sha256: a07811d2b82055815ede75e1fe4b7b76f71a0b4820b26f71bdaddd157d6a3e20 + url: "https://pub.dev" + source: hosted + version: "2.2.6" http: dependency: "direct main" description: @@ -240,6 +376,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.1.6" + location: + dependency: "direct main" + description: + name: location + sha256: "9051959f6f2ccadd887b28b66e9cbbcc25b6838e37cf9e894c421ccc0ebf80b5" + url: "https://pub.dev" + source: hosted + version: "4.4.0" + location_platform_interface: + dependency: transitive + description: + name: location_platform_interface + sha256: "62eeaf1658e92e4459b727f55a3c328eccbac8ba043fa6d262ac5286ad48384c" + url: "https://pub.dev" + source: hosted + version: "2.3.0" + location_web: + dependency: transitive + description: + name: location_web + sha256: "6c08c408a040534c0269c4ff9fe17eebb5a36dea16512fbaf116b9c8bc21545b" + url: "https://pub.dev" + source: hosted + version: "3.1.1" logging: dependency: transitive description: @@ -349,6 +509,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -431,4 +599,4 @@ packages: version: "1.0.7" sdks: dart: ">=2.19.2 <3.0.0" - flutter: ">=2.0.0" + flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index ac917fa7d4232274d43df1e0ac14d42b5ba1b88c..306b871454cd3e682950093c260697b1f04966d3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,15 +32,22 @@ dependencies: sdk: flutter flutter_typeahead: ^4.3.7 + dio: ^4.0.0 + flutter_polyline_points: ^0.2.6 + google_maps_flutter: ^2.0.2 + geocoding: ^2.1.0 + location: ^4.2.0 + # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 http: ^0.13.5 flutter_map: ^0.12.0 - geocoder: ^0.2.1 tuple: ^1.0.2 latlong: ^0.6.1 latlong2: ^0.8.1 + geolocator: ^9.0.2 + geocoder: ^0.2.1 dev_dependencies: flutter_test: @@ -64,9 +71,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg + assets: + - assets/ # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 8b6d4680af388f28db8742ef7fb8246e2bb1fffb..1ece8f252d3eb458885d641a914f1dae7322c3bd 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,9 @@ #include "generated_plugin_registrant.h" +#include <geolocator_windows/geolocator_windows.h> void RegisterPlugins(flutter::PluginRegistry* registry) { + GeolocatorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("GeolocatorWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index b93c4c30c16703f640bc38523e56204ade09399e..7f101a778fa2fe0c922135de613a7be45b6d26cf 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + geolocator_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST