Skip to content

Commit

Permalink
Complete rewrite of location history to avoid multiple and added entr…
Browse files Browse the repository at this point in the history
…ies by Apple #165
  • Loading branch information
danny committed Feb 15, 2025
1 parent 22072ca commit 532e154
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 6 deletions.
29 changes: 25 additions & 4 deletions macless_haystack/lib/accessory/accessory_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ class Accessory {
var reportDate = report.timestamp ?? report.published!;
logger.d(
'Adding report with timestamp $reportDate and ${report.longitude} - ${report.latitude}');

Pair? closest;
//Find the closest history report by time
for (int i = 0; i < locationHistory.length; i++) {
Expand All @@ -303,7 +304,6 @@ class Accessory {
reportDate.isAtSameMomentAs(currentPair.end) ||
(reportDate.isAfter(locationHistory[0].start) &&
reportDate.isBefore(locationHistory[0].end))) {
//new element is after latest history entry, so break directly
closest = currentPair;
break;
}
Expand Down Expand Up @@ -338,14 +338,31 @@ class Accessory {
} else {
logger.d('Date not changed, because is before current date.');
}
} else {
} else if (!reportDate.isAtSameMomentAs(closest.start) &&
!reportDate.isAtSameMomentAs(closest.end)) {
logger.d('Adding new one, because closest is too far away');
//not like before, so add new one
Pair<LatLng, DateTime> pair = Pair(
LatLng(report.latitude!, report.longitude!),
reportDate,
reportDate);
//add the new one
locationHistory.add(pair);
if (reportDate.isAfter(closest.start) &&
reportDate.isBefore(closest.end)) {
logger.d(
'Splitting closest, because new entry is in between with other location.');
//add the closest entry again with the end time only
locationHistory.add(Pair(
LatLng(closest.location.latitude, closest.location.longitude),
closest.end,
closest.end));
//change the existing closest entry end date to the former start date
closest.end = closest.start;
}
} else {
logger.w(
'New entry at $reportDate (Lon: ${report.location.longitude}, Lat: ${report.location.latitude}) will be skipped, because we have already an entry at other location. (Lon: ${closest.location.longitude}, Lat: ${closest.location.latitude})');
}
} else {
logger.d('Closest not found. Adding to list.');
Expand Down Expand Up @@ -386,8 +403,12 @@ class Accessory {
void clearLocationHistory() {
locationHistory.clear();
}
List<Pair<dynamic, dynamic>> getLocationHistory(){

List<Pair<dynamic, dynamic>> getSortedLocationHistory() {
locationHistory.sort((a, b) {
return a.start.compareTo(b.start);
});

return locationHistory;
}

}
2 changes: 1 addition & 1 deletion macless_haystack/lib/history/accessory_history.dart
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class _AccessoryHistoryState extends State<AccessoryHistory> {

List<Pair<dynamic, dynamic>> filterHistoryEntries() {
var now = DateTime.now();
var filteredEntries = widget.accessory.locationHistory
var filteredEntries = widget.accessory.getSortedLocationHistory()
.where(
(element) => element.end.isAfter(
now.subtract(Duration(days: numberOfDays.round())),
Expand Down
2 changes: 1 addition & 1 deletion macless_haystack/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ dependencies:
# Storage
shared_preferences: ^2.5.2
flutter_secure_storage: ^9.2.4
file_picker: ^8.3.5
file_picker: ^8.3.7

# Sharing
share_plus: ^10.1.4
Expand Down
61 changes: 61 additions & 0 deletions macless_haystack/test/accessory/accessory_registry_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,67 @@ void main() {
expect(locationHistory.elementAt(2).end, DateTime(2024, 1, 1, 12, 0, 0));
});

test('Add other location in the middle should split entries', () async {
List<FindMyLocationReport> reports =
await fillDefaultLocations(registry, accessory);
reports.clear();
reports.add(FindMyLocationReport.withHash(
4,
5,
DateTime(2024, 1, 1, 8, 30, 0),
DateTime.now().microsecondsSinceEpoch.toString()));
await registry.fillLocationHistory(reports, accessory);
var locationHistory = accessory.getSortedLocationHistory();
expect(5, locationHistory.length);

var latest = accessory.datePublished;
var lastLocation = accessory.lastLocation;
var endOfFirstEntry = accessory.latestHistoryEntry();

expect(endOfFirstEntry, DateTime(2024, 1, 1, 8, 0, 0));
expect(latest, DateTime(2024, 1, 1, 12, 0, 0));
expect(lastLocation, const LatLng(1, 2));

expect(locationHistory.elementAt(1).start, DateTime(2024, 1, 1, 8, 30, 0));
expect(locationHistory.elementAt(1).end, DateTime(2024, 1, 1, 8, 30, 0));
expect(locationHistory.elementAt(2).start, DateTime(2024, 1, 1, 9, 0, 0));
expect(locationHistory.elementAt(2).end, DateTime(2024, 1, 1, 9, 0, 0));
});

test(
'Add location at time already exist will be skipped because of invalid data',
() async {
List<FindMyLocationReport> reports =
await fillDefaultLocations(registry, accessory);
reports.clear();
reports.add(FindMyLocationReport.withHash(
4,
5,
DateTime(2024, 1, 1, 8, 0, 0),
DateTime.now().microsecondsSinceEpoch.toString()));

reports.add(FindMyLocationReport.withHash(
4,
5,
DateTime(2024, 1, 1, 9, 0, 0),
DateTime.now().microsecondsSinceEpoch.toString()));
await registry.fillLocationHistory(reports, accessory);
var locationHistory = accessory.getSortedLocationHistory();
expect(3, locationHistory.length);

var latest = accessory.datePublished;
var lastLocation = accessory.lastLocation;
var endOfFirstEntry = accessory.latestHistoryEntry();

expect(endOfFirstEntry, DateTime(2024, 1, 1, 9, 0, 0));
expect(latest, DateTime(2024, 1, 1, 12, 0, 0));
expect(lastLocation, const LatLng(1, 2));
// Invalid locations added, but first location has not changed
expect(locationHistory.elementAt(0).location.latitude, 1);
expect(locationHistory.elementAt(0).location.longitude, 2);
expect(locationHistory.elementAt(0).start, DateTime(2024, 1, 1, 8, 0, 0));
});

test(
'Add other location at the end should create new entry and change latestLocationTimestamp',
() async {
Expand Down

0 comments on commit 532e154

Please sign in to comment.