115 lines
3.9 KiB
Dart
115 lines
3.9 KiB
Dart
import 'package:anyway/data/datasources/trip_local_datasource.dart';
|
|
import 'package:anyway/data/datasources/trip_remote_datasource.dart';
|
|
import 'package:anyway/domain/entities/landmark.dart';
|
|
import 'package:anyway/domain/entities/preferences.dart';
|
|
import 'package:anyway/domain/entities/trip.dart';
|
|
import 'package:anyway/domain/repositories/trip_repository.dart';
|
|
|
|
class BackendTripRepository implements TripRepository {
|
|
final TripRemoteDataSource remote;
|
|
final TripLocalDataSource local;
|
|
|
|
BackendTripRepository({required this.remote, required this.local});
|
|
|
|
@override
|
|
Future<Trip> getTrip({Preferences? preferences, String? tripUUID, List<Landmark>? landmarks}) async {
|
|
try {
|
|
Map<String, dynamic> json;
|
|
|
|
if (tripUUID != null) {
|
|
json = await remote.fetchTrip(tripUUID);
|
|
} else {
|
|
if (preferences == null) {
|
|
throw ArgumentError('Either preferences or tripUUID must be provided');
|
|
}
|
|
|
|
final Map<String, dynamic> prefsPayload = _buildPreferencesPayload(preferences);
|
|
List<Map<String, dynamic>> landmarkBodies = landmarks != null
|
|
? landmarks.map((lm) => lm.toJson()).toList()
|
|
: await _fetchLandmarkPayloads(prefsPayload, preferences.startLocation);
|
|
|
|
// TODO: remove
|
|
// restrict the landmark list to 30 to iterate quickly
|
|
landmarkBodies = landmarkBodies.take(30).toList();
|
|
// change the json key because of backend inconsistency
|
|
for (var lm in landmarkBodies) {
|
|
if (lm.containsKey('type')) {
|
|
lm['type'] = "sightseeing";
|
|
}
|
|
lm['osm_type'] = 'node';
|
|
lm['osm_id'] = 1;
|
|
}
|
|
|
|
final Map<String, dynamic> body = {
|
|
'preferences': prefsPayload,
|
|
'landmarks': landmarkBodies,
|
|
'start': preferences.startLocation,
|
|
};
|
|
if (preferences.endLocation != null) {
|
|
body['end'] = preferences.endLocation;
|
|
}
|
|
if (preferences.detourToleranceMinutes != null) {
|
|
body['detour_tolerance_minute'] = preferences.detourToleranceMinutes;
|
|
}
|
|
|
|
json = await remote.createTrip(body);
|
|
}
|
|
|
|
return Trip.fromJson(json);
|
|
} catch (e) {
|
|
throw Exception('Failed to fetch trip: ${e.toString()}');
|
|
}
|
|
}
|
|
|
|
|
|
// TODO - maybe shorten this
|
|
@override
|
|
Future<List<Landmark>> searchLandmarks(Preferences preferences) async {
|
|
final Map<String, dynamic> prefsPayload = _buildPreferencesPayload(preferences);
|
|
final List<Map<String, dynamic>> rawLandmarks = await _fetchLandmarkPayloads(prefsPayload, preferences.startLocation);
|
|
return rawLandmarks.map((lmJson) => Landmark.fromJson(lmJson)).toList();
|
|
}
|
|
|
|
Future<List<Map<String, dynamic>>> _fetchLandmarkPayloads(
|
|
Map<String, dynamic> prefsPayload, List<double> startLocation) async {
|
|
final Map<String, dynamic> landmarkRequest = {
|
|
'preferences': prefsPayload,
|
|
'start': startLocation,
|
|
};
|
|
|
|
return await remote.fetchLandmarks(landmarkRequest);
|
|
}
|
|
|
|
Map<String, dynamic> _buildPreferencesPayload(Preferences preferences) {
|
|
final Map<String, dynamic> prefsPayload = {};
|
|
preferences.scores.forEach((type, score) {
|
|
prefsPayload[type] = {'type': type, 'score': score};
|
|
});
|
|
prefsPayload['max_time_minute'] = preferences.maxTimeMinutes;
|
|
return prefsPayload;
|
|
}
|
|
|
|
// TODO - should this be moved to a separate local repository?
|
|
@override
|
|
Future<List<Trip>> getSavedTrips() async {
|
|
final rawTrips = await local.loadTrips();
|
|
return rawTrips.map(Trip.fromJson).toList(growable: false);
|
|
}
|
|
|
|
@override
|
|
Future<Trip?> getSavedTrip(String uuid) async {
|
|
final json = await local.getTrip(uuid);
|
|
return json == null ? null : Trip.fromJson(json);
|
|
}
|
|
|
|
@override
|
|
Future<void> saveTrip(Trip trip) async {
|
|
await local.upsertTrip(trip.toJson());
|
|
}
|
|
|
|
@override
|
|
Future<void> deleteSavedTrip(String uuid) async {
|
|
await local.deleteTrip(uuid);
|
|
}
|
|
}
|