116 lines
3.0 KiB
Dart

// Represents a collection of landmarks that represent a journey
// Different instances of a Trip can be saved and loaded by the user
import 'dart:collection';
import 'dart:convert';
import 'dart:developer';
import 'package:anyway/structs/landmark.dart';
import 'package:flutter/foundation.dart';
import 'package:geocoding/geocoding.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Trip with ChangeNotifier {
String uuid;
int totalTime;
LinkedList<Landmark> landmarks;
// could be empty as well
String? errorDescription;
Future<String> get cityName async {
List<double>? location = landmarks.firstOrNull?.location;
if (GeocodingPlatform.instance == null) {
return '$location';
} else if (location == null) {
return 'Unknown';
} else{
List<Placemark> placemarks = await placemarkFromCoordinates(location[0], location[1]);
return placemarks.first.locality ?? 'Unknown';
}
}
Trip({
this.uuid = 'pending',
this.totalTime = 0,
LinkedList<Landmark>? landmarks
// a trip can be created with no landmarks, but the list should be initialized anyway
}) : landmarks = landmarks ?? LinkedList<Landmark>();
factory Trip.fromJson(Map<String, dynamic> json) {
Trip trip = Trip(
uuid: json['uuid'],
totalTime: json['total_time'],
);
return trip;
}
void loadFromJson(Map<String, dynamic> json) {
uuid = json['uuid'];
totalTime = json['total_time'];
notifyListeners();
}
void addLandmark(Landmark landmark) {
landmarks.add(landmark);
notifyListeners();
}
void updateUUID(String newUUID) {
uuid = newUUID;
notifyListeners();
}
void removeLandmark(Landmark landmark) {
landmarks.remove(landmark);
notifyListeners();
}
void updateError(String error) {
errorDescription = error;
notifyListeners();
}
factory Trip.fromPrefs(SharedPreferences prefs, String uuid) {
String? content = prefs.getString('trip_$uuid');
Map<String, dynamic> json = jsonDecode(content!);
Trip trip = Trip.fromJson(json);
String? firstUUID = json['first_landmark_uuid'];
log('Loading trip $uuid with first landmark $firstUUID');
LinkedList<Landmark> landmarks = readLandmarks(prefs, firstUUID);
trip.landmarks = landmarks;
// notifyListeners();
return trip;
}
Map<String, dynamic> toJson() => {
'uuid': uuid,
'total_time': totalTime,
'first_landmark_uuid': landmarks.first.uuid
};
void toPrefs(SharedPreferences prefs){
Map<String, dynamic> json = toJson();
log('Saving trip $uuid : $json');
prefs.setString('trip_$uuid', jsonEncode(json));
for (Landmark landmark in landmarks) {
landmarkToPrefs(prefs, landmark, landmark.next);
}
}
}
// Helper
LinkedList<Landmark> readLandmarks(SharedPreferences prefs, String? firstUUID) {
LinkedList<Landmark> landmarks = LinkedList<Landmark>();
while (firstUUID != null) {
var (head, nextUUID) = getLandmarkFromPrefs(prefs, firstUUID);
landmarks.add(head);
firstUUID = nextUUID;
}
return landmarks;
}