bare implementation of comuncation with the api
This commit is contained in:
		| @@ -20,26 +20,40 @@ class Greeter extends StatefulWidget { | |||||||
| class _GreeterState extends State<Greeter> { | class _GreeterState extends State<Greeter> { | ||||||
|   Widget greeterBuild (BuildContext context, AsyncSnapshot<Trip> snapshot) { |   Widget greeterBuild (BuildContext context, AsyncSnapshot<Trip> snapshot) { | ||||||
|     ThemeData theme = Theme.of(context); |     ThemeData theme = Theme.of(context); | ||||||
|     String cityName = ""; |     Widget topGreeter; | ||||||
|     if (snapshot.hasData) { |     if (snapshot.hasData) { | ||||||
|       cityName = snapshot.data?.cityName ?? '...'; |       topGreeter = Padding( | ||||||
|  |         padding: const EdgeInsets.only(top: 20, bottom: 20), | ||||||
|  |         child: Text( | ||||||
|  |           'Welcome to ${snapshot.data?.cityName}!', | ||||||
|  |           style: TextStyle(color: theme.primaryColor, fontWeight: FontWeight.bold, fontSize: 24), | ||||||
|  |         ) | ||||||
|  |       ); | ||||||
|     } else if (snapshot.hasError) { |     } else if (snapshot.hasError) { | ||||||
|       cityName = "error"; |       topGreeter = const Padding( | ||||||
|     } else { // still awaiting the cityname |         padding: EdgeInsets.only(top: 20, bottom: 20), | ||||||
|       cityName = "..."; |         child: Text('Error while fetching trip') | ||||||
|  |       ); | ||||||
|  |     } else { | ||||||
|  |       // still awaiting the cityname | ||||||
|  |       // Show a linear loader at the bottom and an info message above | ||||||
|  |       topGreeter = Column( | ||||||
|  |         mainAxisAlignment: MainAxisAlignment.end, | ||||||
|  |         children: [ | ||||||
|  |           Padding( | ||||||
|  |             padding: const EdgeInsets.only(top: 20, bottom: 20), | ||||||
|  |             child: const Text('Generating your trip...', style: TextStyle(fontSize: 20),) | ||||||
|  |           ), | ||||||
|  |           const LinearProgressIndicator() | ||||||
|  |         ] | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Widget topGreeter = Text( |      | ||||||
|       'Welcome to $cityName!', |  | ||||||
|       style: TextStyle(color: theme.primaryColor, fontWeight: FontWeight.bold, fontSize: 24), |  | ||||||
|     ); |  | ||||||
|  |  | ||||||
|     if (widget.standalone) { |     if (widget.standalone) { | ||||||
|       return Center( |       return Center( | ||||||
|         child: Padding( |  | ||||||
|           padding: EdgeInsets.only(top: 24.0), |  | ||||||
|         child: topGreeter, |         child: topGreeter, | ||||||
|         ), |  | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       return Center( |       return Center( | ||||||
|   | |||||||
| @@ -63,9 +63,8 @@ class _NewTripPageState extends State<NewTripPage> { | |||||||
|                         double.parse(latController.text), |                         double.parse(latController.text), | ||||||
|                         double.parse(lonController.text) |                         double.parse(lonController.text) | ||||||
|                       ]; |                       ]; | ||||||
|                       UserPreferences preferences = UserPreferences(); |                       Future<UserPreferences> preferences = loadUserPreferences(); | ||||||
|                       preferences.load(); |                       Future<Trip>? trip = fetchTrip(startPoint, preferences); | ||||||
|                       Future<Trip> trip = fetchTrip(startPoint, preferences); |  | ||||||
|                         Navigator.of(context).push( |                         Navigator.of(context).push( | ||||||
|                           MaterialPageRoute( |                           MaterialPageRoute( | ||||||
|                             builder: (context) => BasePage(mainScreen: "map", trip: trip) |                             builder: (context) => BasePage(mainScreen: "map", trip: trip) | ||||||
|   | |||||||
| @@ -82,17 +82,15 @@ class UserPreferences { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   String toJson() { |   Map<String, dynamic> toJson() { | ||||||
|       // This is "opinionated" JSON, corresponding to the backend's expectations |       // This is "opinionated" JSON, corresponding to the backend's expectations | ||||||
|     return ''' |       return { | ||||||
|     { |         "sightseeing": {"type": "sightseeing", "score": sightseeing.value}, | ||||||
|       "sightseeing": {"type": "sightseeing", "score": ${sightseeing.value}}, |         "shopping": {"type": "shopping", "score": shopping.value}, | ||||||
|       "shopping": {"type": "shopping", "score": ${shopping.value}}, |         "nature": {"type": "nature", "score": nature.value}, | ||||||
|       "nature": {"type": "nature", "score": ${nature.value}}, |         "max_time_minute": maxTime.value, | ||||||
|       "max_time_minutes": ${maxTime.value}, |         "detour_tolerance_minute": maxDetour.value | ||||||
|       "detour_tolerance_minute": ${maxDetour.value} |       }; | ||||||
|     } |  | ||||||
|     '''; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ class Trip { | |||||||
|   final String uuid; |   final String uuid; | ||||||
|   final String cityName; |   final String cityName; | ||||||
|   // TODO: cityName should be inferred from coordinates of the Landmarks |   // TODO: cityName should be inferred from coordinates of the Landmarks | ||||||
|  |   final int totalTime; | ||||||
|   final LinkedList<Landmark> landmarks; |   final LinkedList<Landmark> landmarks; | ||||||
|   // could be empty as well |   // could be empty as well | ||||||
|  |  | ||||||
| @@ -19,15 +20,18 @@ class Trip { | |||||||
|     required this.uuid, |     required this.uuid, | ||||||
|     required this.cityName, |     required this.cityName, | ||||||
|     required this.landmarks, |     required this.landmarks, | ||||||
|  |     this.totalTime = 0 | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|  |  | ||||||
|   factory Trip.fromJson(Map<String, dynamic> json) { |   factory Trip.fromJson(Map<String, dynamic> json) { | ||||||
|     return Trip( |     Trip trip = Trip( | ||||||
|       uuid: json['uuid'], |       uuid: json['uuid'], | ||||||
|       cityName: json['city_name'], |       cityName: json['city_name'] ?? 'Not communicated', | ||||||
|       landmarks: LinkedList() |       landmarks: LinkedList() | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  |     return trip; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -44,7 +48,7 @@ class Trip { | |||||||
|   Map<String, dynamic> toJson() => { |   Map<String, dynamic> toJson() => { | ||||||
|     'uuid': uuid, |     'uuid': uuid, | ||||||
|     'city_name': cityName, |     'city_name': cityName, | ||||||
|     'entry_uuid': landmarks.first?.uuid ?? '' |     'first_landmark_uuid': landmarks.first.uuid | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,16 +1,19 @@ | |||||||
|  | import "dart:convert"; | ||||||
|  | import "dart:developer"; | ||||||
|  |  | ||||||
| import 'package:dio/dio.dart'; | import 'package:dio/dio.dart'; | ||||||
| import 'package:anyway/constants.dart'; | import 'package:anyway/constants.dart'; | ||||||
| import "package:anyway/structs/landmark.dart"; | import "package:anyway/structs/landmark.dart"; | ||||||
| import "package:anyway/structs/trip.dart"; | import "package:anyway/structs/trip.dart"; | ||||||
| import "package:anyway/structs/preferences.dart"; | import "package:anyway/structs/preferences.dart"; | ||||||
|  |  | ||||||
| import "package:anyway/structs/linked_landmarks.dart"; |  | ||||||
|  |  | ||||||
| Dio dio = Dio( | Dio dio = Dio( | ||||||
|     BaseOptions( |     BaseOptions( | ||||||
|       baseUrl: API_URL_BASE, |       baseUrl: API_URL_BASE, | ||||||
|  |       // baseUrl: 'http://localhost:8000', | ||||||
|       connectTimeout: const Duration(seconds: 5), |       connectTimeout: const Duration(seconds: 5), | ||||||
|       receiveTimeout: const Duration(seconds: 60), |       receiveTimeout: const Duration(seconds: 120), | ||||||
|       // api is notoriously slow |       // api is notoriously slow | ||||||
|       // headers: { |       // headers: { | ||||||
|       //   HttpHeaders.userAgentHeader: 'dio', |       //   HttpHeaders.userAgentHeader: 'dio', | ||||||
| @@ -18,19 +21,25 @@ Dio dio = Dio( | |||||||
|       // }, |       // }, | ||||||
|       contentType: Headers.jsonContentType, |       contentType: Headers.jsonContentType, | ||||||
|       responseType: ResponseType.json, |       responseType: ResponseType.json, | ||||||
|  |          | ||||||
|   ), |   ), | ||||||
| ); | ); | ||||||
|  |  | ||||||
| Future<Trip> fetchTrip( | Future<Trip>? fetchTrip( | ||||||
|   List<double> startPoint, |   List<double> startPoint, | ||||||
|   UserPreferences preferences, |   Future<UserPreferences> preferences, | ||||||
| ) async { | ) async { | ||||||
|  |   UserPreferences prefs = await preferences; | ||||||
|  |   Map<String, dynamic> data = { | ||||||
|  |     "preferences": prefs.toJson(), | ||||||
|  |     "start": startPoint | ||||||
|  |   }; | ||||||
|  |   String dataString = jsonEncode(data); | ||||||
|  |   log(dataString); | ||||||
|  |  | ||||||
|   final response = await dio.post( |   final response = await dio.post( | ||||||
|     "/trip/new", |     "/trip/new", | ||||||
|     data: { |     data: data | ||||||
|       'preferences': preferences.toJson(), |  | ||||||
|       'start': startPoint |  | ||||||
|     } |  | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
|   // handle errors |   // handle errors | ||||||
| @@ -40,6 +49,37 @@ Future<Trip> fetchTrip( | |||||||
|   if (response.data["error"] != null) { |   if (response.data["error"] != null) { | ||||||
|     throw Exception(response.data["error"]); |     throw Exception(response.data["error"]); | ||||||
|   } |   } | ||||||
|   return Trip.fromJson(response.data); |   log(response.data.toString()); | ||||||
|  |   Map<String, dynamic> json = response.data; | ||||||
|  |  | ||||||
|  |   // only fetch the trip "meta" data for now | ||||||
|  |   Trip trip = Trip.fromJson(json); | ||||||
|  |  | ||||||
|  |   String? nextUUID = json["first_landmark_uuid"]; | ||||||
|  |   while (nextUUID != null) { | ||||||
|  |     var (landmark, newUUID) = await fetchLandmark(nextUUID); | ||||||
|  |     trip.landmarks.add(landmark); | ||||||
|  |     nextUUID = newUUID; | ||||||
|  |   } | ||||||
|  |   return trip; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Future<(Landmark, String?)> fetchLandmark(String uuid) async { | ||||||
|  |   final response = await dio.get( | ||||||
|  |     "/landmark/$uuid" | ||||||
|  |   ); | ||||||
|  |  | ||||||
|  |   // handle errors | ||||||
|  |   if (response.statusCode != 200) { | ||||||
|  |     throw Exception('Failed to load landmark'); | ||||||
|  |   } | ||||||
|  |   if (response.data["error"] != null) { | ||||||
|  |     throw Exception(response.data["error"]); | ||||||
|  |   } | ||||||
|  |   log(response.data.toString()); | ||||||
|  |   Map<String, dynamic> json = response.data; | ||||||
|  |   String? nextUUID = json["next_uuid"]; | ||||||
|  |   return (Landmark.fromJson(json), nextUUID); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user