diff --git a/mobile/lib/ui/viewer/file_details/face_widget.dart b/mobile/lib/ui/viewer/file_details/face_widget.dart index 1ec7a2eb2d..67d2368d71 100644 --- a/mobile/lib/ui/viewer/file_details/face_widget.dart +++ b/mobile/lib/ui/viewer/file_details/face_widget.dart @@ -293,7 +293,7 @@ class _FaceWidgetState extends State { } } - Future?> getFaceCrop() async { + Future?> getFaceCrop({int fetchAttempt = 1}) async { try { final Uint8List? cachedFace = faceCropCache.get(widget.face.faceID); if (cachedFace != null) { @@ -326,6 +326,10 @@ class _FaceWidgetState extends State { error: e, stackTrace: s, ); + resetPool(fullFile: true); + if (fetchAttempt <= retryLimit) { + return getFaceCrop(fetchAttempt: fetchAttempt + 1); + } return null; } } diff --git a/mobile/lib/ui/viewer/file_details/faces_item_widget.dart b/mobile/lib/ui/viewer/file_details/faces_item_widget.dart index ed2fb0f12e..cb22e53b82 100644 --- a/mobile/lib/ui/viewer/file_details/faces_item_widget.dart +++ b/mobile/lib/ui/viewer/file_details/faces_item_widget.dart @@ -173,7 +173,9 @@ class _FacesItemWidgetState extends State { } Future?> getRelevantFaceCrops( - Iterable faces, + Iterable faces, { + int fetchAttempt = 1, + } ) async { try { final faceIdToCrop = {}; @@ -223,6 +225,10 @@ class _FacesItemWidgetState extends State { error: e, stackTrace: s, ); + resetPool(fullFile: true); + if(fetchAttempt <= retryLimit) { + return getRelevantFaceCrops(faces, fetchAttempt: fetchAttempt + 1); + } return null; } } diff --git a/mobile/lib/ui/viewer/search/result/person_face_widget.dart b/mobile/lib/ui/viewer/search/result/person_face_widget.dart index 8be99e5f6e..57fe5af654 100644 --- a/mobile/lib/ui/viewer/search/result/person_face_widget.dart +++ b/mobile/lib/ui/viewer/search/result/person_face_widget.dart @@ -121,7 +121,7 @@ class PersonFaceWidget extends StatelessWidget { ); } - Future getFaceCrop() async { + Future getFaceCrop({int fetchAttempt = 1}) async { try { final Face? face = await _getFace(); if (face == null) { @@ -187,6 +187,10 @@ class PersonFaceWidget extends StatelessWidget { error: e, stackTrace: s, ); + resetPool(fullFile: useFullFile); + if(fetchAttempt <= retryLimit) { + return getFaceCrop(fetchAttempt: fetchAttempt + 1); + } return null; } } diff --git a/mobile/lib/utils/face/face_box_crop.dart b/mobile/lib/utils/face/face_box_crop.dart index 281c0ef495..4dd1778f72 100644 --- a/mobile/lib/utils/face/face_box_crop.dart +++ b/mobile/lib/utils/face/face_box_crop.dart @@ -11,11 +11,20 @@ import "package:photos/utils/image_ml_isolate.dart"; import "package:photos/utils/thumbnail_util.dart"; import "package:pool/pool.dart"; +void resetPool({required bool fullFile}) { + if (fullFile) { + poolFullFileFaceGenerations = Pool(20, timeout: const Duration(seconds: 15)); + } else { + poolThumbnailFaceGenerations = Pool(100, timeout: const Duration(seconds: 15)); + } +} + +const int retryLimit = 3; final LRUMap faceCropCache = LRUMap(1000); final LRUMap faceCropThumbnailCache = LRUMap(1000); -final poolFullFileFaceGenerations = +Pool poolFullFileFaceGenerations = Pool(20, timeout: const Duration(seconds: 15)); -final poolThumbnailFaceGenerations = +Pool poolThumbnailFaceGenerations = Pool(100, timeout: const Duration(seconds: 15)); Future?> getFaceCrops( EnteFile file,