diff --git a/mobile/lib/face/db.dart b/mobile/lib/face/db.dart index 2778ec289..4d9c200aa 100644 --- a/mobile/lib/face/db.dart +++ b/mobile/lib/face/db.dart @@ -629,14 +629,9 @@ class FaceMLDataDB { return result; } - Future<(Map, Map)> - getClusterIdToPerson() async { + Future> getClusterIdToPerson( + Map personMap,) async { final db = await instance.database; - final List persons = await getPersons(); - final Map personMap = {}; - for (final p in persons) { - personMap[p.remoteID] = p; - } final List> maps = await db.rawQuery( 'SELECT $personIdColumn, $cluserIDColumn FROM $clusterPersonTable', ); @@ -652,7 +647,7 @@ class FaceMLDataDB { ); } } - return (result, personMap); + return result; } Future> getPersons() async { diff --git a/mobile/lib/face/model/person.dart b/mobile/lib/face/model/person.dart index abf2ac38c..10e1c77bf 100644 --- a/mobile/lib/face/model/person.dart +++ b/mobile/lib/face/model/person.dart @@ -52,6 +52,8 @@ class PersonData { List? rejected = List.empty(); final String? birthDate; + bool hasAvatar() => avatarFaceId != null; + PersonData({ required this.name, this.assigned, @@ -93,10 +95,14 @@ class PersonData { return PersonData( name: json['name'] as String, assigned: List.from( - (json['assigned'] as List).map((e) => ClusterInfo.fromJson(e)), + (json['assigned'] as List?) + ?.map((e) => ClusterInfo.fromJson(e)) ?? + List.empty(), ), rejected: List.from( - (json['rejected'] as List).map((e) => ClusterInfo.fromJson(e)), + (json['rejected'] as List?) + ?.map((e) => ClusterInfo.fromJson(e)) ?? + List.empty(), ), avatarFaceId: json['avatarFaceId'] as String?, isHidden: json['isHidden'] as bool? ?? false, diff --git a/mobile/lib/services/machine_learning/face_ml/person/person_service.dart b/mobile/lib/services/machine_learning/face_ml/person/person_service.dart index d2f05b7cc..55a7930ab 100644 --- a/mobile/lib/services/machine_learning/face_ml/person/person_service.dart +++ b/mobile/lib/services/machine_learning/face_ml/person/person_service.dart @@ -28,6 +28,31 @@ class PersonService { _instance = PersonService(entityService, faceMLDataDB, prefs); } + Future> getPersons() async { + final entities = await entityService.getEntities(EntityType.person); + return entities + .map( + (e) => PersonEntity(e.id, PersonData.fromJson(json.decode(e.data))), + ) + .toList(); + } + + Future> getPersonsMap() async { + final entities = await entityService.getEntities(EntityType.person); + final Map map = {}; + entities.forEach((e) { + final person = + PersonEntity(e.id, PersonData.fromJson(json.decode(e.data))); + map[person.remoteID] = person; + }); + return map; + } + + Future> personIDs() async { + final entities = await entityService.getEntities(EntityType.person); + return entities.map((e) => e.id).toSet(); + } + Future addPerson(String name, int clusterID) async { final faceIds = await faceMLDataDB.getFaceIDsForCluster(clusterID); final data = PersonData( diff --git a/mobile/lib/services/search_service.dart b/mobile/lib/services/search_service.dart index d2b831c24..06a6dc5e6 100644 --- a/mobile/lib/services/search_service.dart +++ b/mobile/lib/services/search_service.dart @@ -28,6 +28,7 @@ import "package:photos/models/search/search_constants.dart"; import "package:photos/models/search/search_types.dart"; import 'package:photos/services/collections_service.dart'; import "package:photos/services/location_service.dart"; +import "package:photos/services/machine_learning/face_ml/person/person_service.dart"; import 'package:photos/services/machine_learning/semantic_search/semantic_search_service.dart'; import "package:photos/states/location_screen_state.dart"; import "package:photos/ui/viewer/location/add_location_sheet.dart"; @@ -739,8 +740,10 @@ class SearchService { debugPrint("getting faces"); final Map> fileIdToClusterID = await FaceMLDataDB.instance.getFileIdToClusterIds(); - final (clusterIDToPerson, personIdToPerson) = - await FaceMLDataDB.instance.getClusterIdToPerson(); + final Map personIdToPerson = + await PersonService.instance.getPersonsMap(); + final clusterIDToPerson = + await FaceMLDataDB.instance.getClusterIdToPerson(personIdToPerson); debugPrint("building result"); final List facesResult = []; diff --git a/mobile/lib/ui/settings/debug/face_debug_section_widget.dart b/mobile/lib/ui/settings/debug/face_debug_section_widget.dart index a4861964f..55e09e030 100644 --- a/mobile/lib/ui/settings/debug/face_debug_section_widget.dart +++ b/mobile/lib/ui/settings/debug/face_debug_section_widget.dart @@ -11,6 +11,7 @@ import "package:photos/face/model/person.dart"; import "package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart"; import 'package:photos/services/machine_learning/face_ml/face_ml_service.dart'; import 'package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart'; +import "package:photos/services/machine_learning/face_ml/person/person_service.dart"; // import "package:photos/services/search_service.dart"; import 'package:photos/theme/ente_theme.dart'; import 'package:photos/ui/components/captioned_text_widget.dart'; @@ -244,7 +245,7 @@ class _FaceDebugSectionWidgetState extends State { onTap: () async { try { final List persons = - await FaceMLDataDB.instance.getPersons(); + await PersonService.instance.getPersons(); final EnteWatch w = EnteWatch('feedback')..start(); for (final PersonEntity p in persons) { await ClusterFeedbackService.instance 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 c5c8921f5..3efb094a5 100644 --- a/mobile/lib/ui/viewer/file_details/faces_item_widget.dart +++ b/mobile/lib/ui/viewer/file_details/faces_item_widget.dart @@ -5,6 +5,7 @@ import "package:photos/face/model/face.dart"; import "package:photos/face/model/person.dart"; import "package:photos/models/file/file.dart"; import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart"; +import "package:photos/services/machine_learning/face_ml/person/person_service.dart"; import "package:photos/ui/components/buttons/chip_button_widget.dart"; import "package:photos/ui/components/info_item_widget.dart"; import "package:photos/ui/viewer/file_details/face_widget.dart"; @@ -66,8 +67,10 @@ class FacesItemWidget extends StatelessWidget { // TODO: add deduplication of faces of same person final faceIdsToClusterIds = await FaceMLDataDB.instance .getFaceIdsToClusterIds(faces.map((face) => face.faceID)); - final (clusterIDToPerson, _) = - await FaceMLDataDB.instance.getClusterIdToPerson(); + final Map persons = + await PersonService.instance.getPersonsMap(); + final clusterIDToPerson = + await FaceMLDataDB.instance.getClusterIdToPerson(persons); final lastViewedClusterID = ClusterFeedbackService.lastViewedClusterID; diff --git a/mobile/lib/ui/viewer/people/add_person_action_sheet.dart b/mobile/lib/ui/viewer/people/add_person_action_sheet.dart index 16213db51..67759dcf7 100644 --- a/mobile/lib/ui/viewer/people/add_person_action_sheet.dart +++ b/mobile/lib/ui/viewer/people/add_person_action_sheet.dart @@ -178,7 +178,7 @@ class _PersonActionSheetState extends State { return Flexible( child: Padding( padding: const EdgeInsets.fromLTRB(16, 24, 4, 0), - child: FutureBuilder>( + child: FutureBuilder>( future: _getPersons(), builder: (context, snapshot) { if (snapshot.hasError) { @@ -290,7 +290,7 @@ class _PersonActionSheetState extends State { } } - Future> _getPersons() async { - return FaceMLDataDB.instance.getPersons(); + Future> _getPersons() async { + return PersonService.instance.getPersons(); } }