Skip to content

Commit 532e154

Browse files
author
danny
committed
Complete rewrite of location history to avoid multiple and added entries by Apple #165
1 parent 22072ca commit 532e154

File tree

4 files changed

+88
-6
lines changed

4 files changed

+88
-6
lines changed

macless_haystack/lib/accessory/accessory_model.dart

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ class Accessory {
294294
var reportDate = report.timestamp ?? report.published!;
295295
logger.d(
296296
'Adding report with timestamp $reportDate and ${report.longitude} - ${report.latitude}');
297+
297298
Pair? closest;
298299
//Find the closest history report by time
299300
for (int i = 0; i < locationHistory.length; i++) {
@@ -303,7 +304,6 @@ class Accessory {
303304
reportDate.isAtSameMomentAs(currentPair.end) ||
304305
(reportDate.isAfter(locationHistory[0].start) &&
305306
reportDate.isBefore(locationHistory[0].end))) {
306-
//new element is after latest history entry, so break directly
307307
closest = currentPair;
308308
break;
309309
}
@@ -338,14 +338,31 @@ class Accessory {
338338
} else {
339339
logger.d('Date not changed, because is before current date.');
340340
}
341-
} else {
341+
} else if (!reportDate.isAtSameMomentAs(closest.start) &&
342+
!reportDate.isAtSameMomentAs(closest.end)) {
342343
logger.d('Adding new one, because closest is too far away');
343344
//not like before, so add new one
344345
Pair<LatLng, DateTime> pair = Pair(
345346
LatLng(report.latitude!, report.longitude!),
346347
reportDate,
347348
reportDate);
349+
//add the new one
348350
locationHistory.add(pair);
351+
if (reportDate.isAfter(closest.start) &&
352+
reportDate.isBefore(closest.end)) {
353+
logger.d(
354+
'Splitting closest, because new entry is in between with other location.');
355+
//add the closest entry again with the end time only
356+
locationHistory.add(Pair(
357+
LatLng(closest.location.latitude, closest.location.longitude),
358+
closest.end,
359+
closest.end));
360+
//change the existing closest entry end date to the former start date
361+
closest.end = closest.start;
362+
}
363+
} else {
364+
logger.w(
365+
'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})');
349366
}
350367
} else {
351368
logger.d('Closest not found. Adding to list.');
@@ -386,8 +403,12 @@ class Accessory {
386403
void clearLocationHistory() {
387404
locationHistory.clear();
388405
}
389-
List<Pair<dynamic, dynamic>> getLocationHistory(){
406+
407+
List<Pair<dynamic, dynamic>> getSortedLocationHistory() {
408+
locationHistory.sort((a, b) {
409+
return a.start.compareTo(b.start);
410+
});
411+
390412
return locationHistory;
391413
}
392-
393414
}

macless_haystack/lib/history/accessory_history.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ class _AccessoryHistoryState extends State<AccessoryHistory> {
230230

231231
List<Pair<dynamic, dynamic>> filterHistoryEntries() {
232232
var now = DateTime.now();
233-
var filteredEntries = widget.accessory.locationHistory
233+
var filteredEntries = widget.accessory.getSortedLocationHistory()
234234
.where(
235235
(element) => element.end.isAfter(
236236
now.subtract(Duration(days: numberOfDays.round())),

macless_haystack/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ dependencies:
5656
# Storage
5757
shared_preferences: ^2.5.2
5858
flutter_secure_storage: ^9.2.4
59-
file_picker: ^8.3.5
59+
file_picker: ^8.3.7
6060

6161
# Sharing
6262
share_plus: ^10.1.4

macless_haystack/test/accessory/accessory_registry_test.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,67 @@ void main() {
168168
expect(locationHistory.elementAt(2).end, DateTime(2024, 1, 1, 12, 0, 0));
169169
});
170170

171+
test('Add other location in the middle should split entries', () async {
172+
List<FindMyLocationReport> reports =
173+
await fillDefaultLocations(registry, accessory);
174+
reports.clear();
175+
reports.add(FindMyLocationReport.withHash(
176+
4,
177+
5,
178+
DateTime(2024, 1, 1, 8, 30, 0),
179+
DateTime.now().microsecondsSinceEpoch.toString()));
180+
await registry.fillLocationHistory(reports, accessory);
181+
var locationHistory = accessory.getSortedLocationHistory();
182+
expect(5, locationHistory.length);
183+
184+
var latest = accessory.datePublished;
185+
var lastLocation = accessory.lastLocation;
186+
var endOfFirstEntry = accessory.latestHistoryEntry();
187+
188+
expect(endOfFirstEntry, DateTime(2024, 1, 1, 8, 0, 0));
189+
expect(latest, DateTime(2024, 1, 1, 12, 0, 0));
190+
expect(lastLocation, const LatLng(1, 2));
191+
192+
expect(locationHistory.elementAt(1).start, DateTime(2024, 1, 1, 8, 30, 0));
193+
expect(locationHistory.elementAt(1).end, DateTime(2024, 1, 1, 8, 30, 0));
194+
expect(locationHistory.elementAt(2).start, DateTime(2024, 1, 1, 9, 0, 0));
195+
expect(locationHistory.elementAt(2).end, DateTime(2024, 1, 1, 9, 0, 0));
196+
});
197+
198+
test(
199+
'Add location at time already exist will be skipped because of invalid data',
200+
() async {
201+
List<FindMyLocationReport> reports =
202+
await fillDefaultLocations(registry, accessory);
203+
reports.clear();
204+
reports.add(FindMyLocationReport.withHash(
205+
4,
206+
5,
207+
DateTime(2024, 1, 1, 8, 0, 0),
208+
DateTime.now().microsecondsSinceEpoch.toString()));
209+
210+
reports.add(FindMyLocationReport.withHash(
211+
4,
212+
5,
213+
DateTime(2024, 1, 1, 9, 0, 0),
214+
DateTime.now().microsecondsSinceEpoch.toString()));
215+
await registry.fillLocationHistory(reports, accessory);
216+
var locationHistory = accessory.getSortedLocationHistory();
217+
expect(3, locationHistory.length);
218+
219+
var latest = accessory.datePublished;
220+
var lastLocation = accessory.lastLocation;
221+
var endOfFirstEntry = accessory.latestHistoryEntry();
222+
223+
expect(endOfFirstEntry, DateTime(2024, 1, 1, 9, 0, 0));
224+
expect(latest, DateTime(2024, 1, 1, 12, 0, 0));
225+
expect(lastLocation, const LatLng(1, 2));
226+
// Invalid locations added, but first location has not changed
227+
expect(locationHistory.elementAt(0).location.latitude, 1);
228+
expect(locationHistory.elementAt(0).location.longitude, 2);
229+
expect(locationHistory.elementAt(0).start, DateTime(2024, 1, 1, 8, 0, 0));
230+
});
231+
171232
test(
172233
'Add other location at the end should create new entry and change latestLocationTimestamp',
173234
() async {

0 commit comments

Comments
 (0)