Explorar o código

fix(mobile): fix asset removal edge cases (#2251)

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex <alex.tran1502@gmail.com>
Fynn Petersen-Frey %!s(int64=2) %!d(string=hai) anos
pai
achega
1a64075027

+ 3 - 0
mobile/lib/shared/services/sync.service.dart

@@ -9,6 +9,7 @@ import 'package:immich_mobile/shared/models/store.dart';
 import 'package:immich_mobile/shared/models/user.dart';
 import 'package:immich_mobile/shared/providers/db.provider.dart';
 import 'package:immich_mobile/utils/async_mutex.dart';
+import 'package:immich_mobile/utils/builtin_extensions.dart';
 import 'package:immich_mobile/utils/diff.dart';
 import 'package:immich_mobile/utils/tuple.dart';
 import 'package:isar/isar.dart';
@@ -674,7 +675,9 @@ Pair<List<int>, List<Asset>> _handleAssetRemoval(
     return const Pair([], []);
   }
   deleteCandidates.sort(Asset.compareById);
+  deleteCandidates.uniqueConsecutive((a) => a.id);
   existing.sort(Asset.compareById);
+  existing.uniqueConsecutive((a) => a.id);
   final triple = _diffAssets(
     existing,
     deleteCandidates,

+ 17 - 0
mobile/lib/utils/builtin_extensions.dart

@@ -18,3 +18,20 @@ extension DurationExtension on String {
     return int.parse(this);
   }
 }
+
+extension ListExtension<E> on List<E> {
+  List<E> uniqueConsecutive<T>([T Function(E element)? key]) {
+    key ??= (E e) => e as T;
+    int i = 1, j = 1;
+    for (; i < length; i++) {
+      if (key(this[i]) != key(this[i - 1])) {
+        if (i != j) {
+          this[j] = this[i];
+        }
+        j++;
+      }
+    }
+    length = length == 0 ? 0 : j;
+    return this;
+  }
+}

+ 31 - 0
mobile/test/builtin_extensions_text.dart

@@ -15,4 +15,35 @@ void main() {
       expect("a:b:c".toDuration(), null);
     });
   });
+  group('Test uniqueConsecutive', () {
+    test('empty', () {
+      final a = [];
+      expect(a.uniqueConsecutive(), []);
+    });
+
+    test('singleElement', () {
+      final a = [5];
+      expect(a.uniqueConsecutive(), [5]);
+    });
+
+    test('noDuplicates', () {
+      final a = [1, 2, 3];
+      expect(a.uniqueConsecutive(), [1, 2, 3]);
+    });
+
+    test('unsortedDuplicates', () {
+      final a = [1, 2, 1, 3];
+      expect(a.uniqueConsecutive(), [1, 2, 1, 3]);
+    });
+
+    test('sortedDuplicates', () {
+      final a = [6, 6, 2, 3, 3, 3, 4, 5, 1, 1];
+      expect(a.uniqueConsecutive(), [6, 2, 3, 4, 5, 1]);
+    });
+
+    test('withKey', () {
+      final a = ["a", "bb", "cc", "ddd"];
+      expect(a.uniqueConsecutive((s) => s.length), ["a", "bb", "ddd"]);
+    });
+  });
 }