bare implementation of comuncation with the api
This commit is contained in:
parent
016622c7af
commit
5748630b99
@ -20,26 +20,40 @@ class Greeter extends StatefulWidget {
|
||||
class _GreeterState extends State<Greeter> {
|
||||
Widget greeterBuild (BuildContext context, AsyncSnapshot<Trip> snapshot) {
|
||||
ThemeData theme = Theme.of(context);
|
||||
String cityName = "";
|
||||
Widget topGreeter;
|
||||
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) {
|
||||
cityName = "error";
|
||||
} else { // still awaiting the cityname
|
||||
cityName = "...";
|
||||
topGreeter = const Padding(
|
||||
padding: EdgeInsets.only(top: 20, bottom: 20),
|
||||
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) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 24.0),
|
||||
child: topGreeter,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Center(
|
||||
|
@ -63,9 +63,8 @@ class _NewTripPageState extends State<NewTripPage> {
|
||||
double.parse(latController.text),
|
||||
double.parse(lonController.text)
|
||||
];
|
||||
UserPreferences preferences = UserPreferences();
|
||||
preferences.load();
|
||||
Future<Trip> trip = fetchTrip(startPoint, preferences);
|
||||
Future<UserPreferences> preferences = loadUserPreferences();
|
||||
Future<Trip>? trip = fetchTrip(startPoint, preferences);
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
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
|
||||
return '''
|
||||
{
|
||||
"sightseeing": {"type": "sightseeing", "score": ${sightseeing.value}},
|
||||
"shopping": {"type": "shopping", "score": ${shopping.value}},
|
||||
"nature": {"type": "nature", "score": ${nature.value}},
|
||||
"max_time_minutes": ${maxTime.value},
|
||||
"detour_tolerance_minute": ${maxDetour.value}
|
||||
}
|
||||
''';
|
||||
return {
|
||||
"sightseeing": {"type": "sightseeing", "score": sightseeing.value},
|
||||
"shopping": {"type": "shopping", "score": shopping.value},
|
||||
"nature": {"type": "nature", "score": nature.value},
|
||||
"max_time_minute": maxTime.value,
|
||||
"detour_tolerance_minute": maxDetour.value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ class Trip {
|
||||
final String uuid;
|
||||
final String cityName;
|
||||
// TODO: cityName should be inferred from coordinates of the Landmarks
|
||||
final int totalTime;
|
||||
final LinkedList<Landmark> landmarks;
|
||||
// could be empty as well
|
||||
|
||||
@ -19,15 +20,18 @@ class Trip {
|
||||
required this.uuid,
|
||||
required this.cityName,
|
||||
required this.landmarks,
|
||||
this.totalTime = 0
|
||||
});
|
||||
|
||||
|
||||
factory Trip.fromJson(Map<String, dynamic> json) {
|
||||
return Trip(
|
||||
Trip trip = Trip(
|
||||
uuid: json['uuid'],
|
||||
cityName: json['city_name'],
|
||||
cityName: json['city_name'] ?? 'Not communicated',
|
||||
landmarks: LinkedList()
|
||||
);
|
||||
|
||||
return trip;
|
||||
}
|
||||
|
||||
|
||||
@ -44,7 +48,7 @@ class Trip {
|
||||
Map<String, dynamic> toJson() => {
|
||||
'uuid': uuid,
|
||||
'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:anyway/constants.dart';
|
||||
import "package:anyway/structs/landmark.dart";
|
||||
import "package:anyway/structs/trip.dart";
|
||||
import "package:anyway/structs/preferences.dart";
|
||||
|
||||
import "package:anyway/structs/linked_landmarks.dart";
|
||||
|
||||
Dio dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: API_URL_BASE,
|
||||
// baseUrl: 'http://localhost:8000',
|
||||
connectTimeout: const Duration(seconds: 5),
|
||||
receiveTimeout: const Duration(seconds: 60),
|
||||
receiveTimeout: const Duration(seconds: 120),
|
||||
// api is notoriously slow
|
||||
// headers: {
|
||||
// HttpHeaders.userAgentHeader: 'dio',
|
||||
@ -18,19 +21,25 @@ Dio dio = Dio(
|
||||
// },
|
||||
contentType: Headers.jsonContentType,
|
||||
responseType: ResponseType.json,
|
||||
|
||||
),
|
||||
);
|
||||
|
||||
Future<Trip> fetchTrip(
|
||||
Future<Trip>? fetchTrip(
|
||||
List<double> startPoint,
|
||||
UserPreferences preferences,
|
||||
Future<UserPreferences> preferences,
|
||||
) 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(
|
||||
"/trip/new",
|
||||
data: {
|
||||
'preferences': preferences.toJson(),
|
||||
'start': startPoint
|
||||
}
|
||||
data: data
|
||||
);
|
||||
|
||||
// handle errors
|
||||
@ -40,6 +49,37 @@ Future<Trip> fetchTrip(
|
||||
if (response.data["error"] != null) {
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user