Some checks failed
Build and release debug APK / Build APK (pull_request) Failing after 3m52s
126 lines
3.6 KiB
Dart
126 lines
3.6 KiB
Dart
import "dart:convert";
|
|
import "dart:developer";
|
|
import "package:anyway/main.dart";
|
|
import 'package:dio/dio.dart';
|
|
|
|
import 'package:anyway/constants.dart';
|
|
import "package:anyway/utils/load_landmark_image.dart";
|
|
import "package:anyway/structs/landmark.dart";
|
|
import "package:anyway/structs/trip.dart";
|
|
import "package:anyway/structs/preferences.dart";
|
|
|
|
|
|
Dio dio = Dio(
|
|
BaseOptions(
|
|
baseUrl: API_URL_BASE,
|
|
connectTimeout: const Duration(seconds: 5),
|
|
receiveTimeout: const Duration(seconds: 120),
|
|
// also accept 500 errors, since we cannot rule out that the server is at fault. We still want to gracefully handle these errors
|
|
validateStatus: (status) => status! <= 500,
|
|
receiveDataWhenStatusError: true,
|
|
// api is notoriously slow
|
|
// headers: {
|
|
// HttpHeaders.userAgentHeader: 'dio',
|
|
// 'api': '1.0.0',
|
|
// },
|
|
contentType: Headers.jsonContentType,
|
|
responseType: ResponseType.json,
|
|
),
|
|
);
|
|
|
|
|
|
fetchTrip(
|
|
Trip trip,
|
|
UserPreferences preferences,
|
|
) async {
|
|
Map<String, dynamic> data = {
|
|
"preferences": preferences.toJson(),
|
|
"start": trip.landmarks!.first.location,
|
|
};
|
|
String dataString = jsonEncode(data);
|
|
log(dataString);
|
|
|
|
late Response response;
|
|
try {
|
|
response = await dio.post(
|
|
"/trip/new",
|
|
data: data
|
|
);
|
|
} catch (e) {
|
|
trip.updateUUID("error");
|
|
trip.updateError(e.toString());
|
|
log(e.toString());
|
|
return;
|
|
}
|
|
|
|
// handle errors
|
|
if (response.statusCode != 200) {
|
|
trip.updateUUID("error");
|
|
String errorDetail;
|
|
if (response.data.runtimeType == String) {
|
|
errorDetail = response.data;
|
|
} else {
|
|
errorDetail = response.data["detail"] ?? "Unknown error";
|
|
}
|
|
trip.updateError(errorDetail);
|
|
log(errorDetail);
|
|
// Actualy no need to throw an exception, we can just log the error and let the user retry
|
|
// throw Exception(errorDetail);
|
|
} else {
|
|
Map<String, dynamic> json = response.data;
|
|
|
|
// only fill in the trip "meta" data for now
|
|
trip.loadFromJson(json);
|
|
|
|
// now fill the trip with landmarks
|
|
// we are going to recreate ALL the landmarks from the information given by the api
|
|
trip.landmarks.remove(trip.landmarks.first);
|
|
String? nextUUID = json["first_landmark_uuid"];
|
|
while (nextUUID != null) {
|
|
var (landmark, newUUID) = await fetchLandmark(nextUUID);
|
|
trip.addLandmark(landmark);
|
|
nextUUID = newUUID;
|
|
}
|
|
|
|
log(response.data.toString());
|
|
// Also save the trip for the user's convenience
|
|
savedTrips.addTrip(trip);
|
|
}
|
|
}
|
|
|
|
|
|
patchLandmarkImage(Landmark landmark) async {
|
|
// patch the landmark to include an image from an external source
|
|
if (landmark.imageURL == null) {
|
|
String? newUrl = await getImageUrlFromName(landmark.name);
|
|
if (newUrl != null) {
|
|
landmark.imageURL = newUrl;
|
|
}
|
|
} else if (landmark.imageURL!.contains("photos.app.goo.gl")) {
|
|
// the image is a google photos link, we should get the image behind the link
|
|
String? newUrl = await getImageUrlFromGooglePhotos(landmark.imageURL!);
|
|
// also set the new url if it is null
|
|
landmark.imageURL = newUrl;
|
|
}
|
|
}
|
|
|
|
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["detail"] != null) {
|
|
throw Exception(response.data["detail"]);
|
|
}
|
|
// log(response.data.toString());
|
|
Map<String, dynamic> json = response.data;
|
|
String? nextUUID = json["next_uuid"];
|
|
Landmark landmark = Landmark.fromJson(json);
|
|
patchLandmarkImage(landmark);
|
|
return (landmark, nextUUID);
|
|
}
|