[mob][photos] Handle error + refactoring (#5172)

This commit is contained in:
Ashil
2025-02-26 14:33:25 +05:30
committed by GitHub
5 changed files with 86 additions and 49 deletions

View File

@@ -4,6 +4,7 @@ import "dart:developer";
import "package:flutter/foundation.dart";
import "package:logging/logging.dart";
import "package:photos/core/event_bus.dart";
import "package:photos/db/files_db.dart";
import "package:photos/db/ml/db.dart";
import "package:photos/events/people_changed_event.dart";
import "package:photos/extensions/stop_watch.dart";
@@ -483,37 +484,48 @@ class PersonService {
}
}
Future<EnteFile> getRecentFileOfPerson(
Future<EnteFile?> getThumbnailFileOfPerson(
PersonEntity person,
) async {
final clustersToFiles =
await SearchService.instance.getClusterFilesForPersonID(
person.remoteID,
);
int? avatarFileID;
if (person.data.hasAvatar()) {
avatarFileID = tryGetFileIdFromFaceId(person.data.avatarFaceID!);
}
EnteFile? resultFile;
// iterate over all clusters and get the first file
for (final clusterFiles in clustersToFiles.values) {
for (final file in clusterFiles) {
if (avatarFileID != null && file.uploadedFileID! == avatarFileID) {
resultFile = file;
break;
}
resultFile ??= file;
if (resultFile.creationTime! < file.creationTime!) {
resultFile = file;
try {
if (person.data.hasAvatar()) {
final avatarFileID = tryGetFileIdFromFaceId(person.data.avatarFaceID!);
if (avatarFileID != null) {
final file = (await FilesDB.instance
.getFileIDToFileFromIDs([avatarFileID]))[avatarFileID];
if (file != null) {
return file;
} else {
logger.severe("Avatar File not found for face ${person.data}");
}
}
}
}
if (resultFile == null) {
debugPrint(
"Person ${kDebugMode ? person.data.name : person.remoteID} has no files",
final clustersToFiles =
await SearchService.instance.getClusterFilesForPersonID(
person.remoteID,
);
return EnteFile();
EnteFile? resultFile;
// iterate over all clusters and get the first file
for (final clusterFiles in clustersToFiles.values) {
for (final file in clusterFiles) {
resultFile ??= file;
if (resultFile.creationTime! < file.creationTime!) {
resultFile = file;
}
}
}
if (resultFile == null) {
logger.warning(
"Person ${kDebugMode ? person.data.name : person.remoteID} has no files",
);
return null;
}
return resultFile;
} catch (e, s) {
logger.severe("Error in getThumbnailFileOfPerson", e, s);
return null;
}
return resultFile;
}
}

View File

@@ -80,7 +80,7 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
);
if (person != null) {
_faceThumbnail =
await PersonService.instance.getRecentFileOfPerson(person);
await PersonService.instance.getThumbnailFileOfPerson(person);
}
return person?.remoteID;
});
@@ -117,18 +117,25 @@ class _UserAvatarWidgetState extends State<UserAvatarWidget> {
if (snapshot.hasData) {
final personID = snapshot.data as String;
return ClipOval(
child: PersonFaceWidget(
_faceThumbnail!,
personId: personID,
onErrorCallback: () {
if (mounted) {
setState(() {
_personID = null;
_faceThumbnail = null;
});
}
},
),
child: _faceThumbnail == null
? _FirstLetterCircularAvatar(
user: widget.user,
currentUserID: widget.currentUserID,
thumbnailView: widget.thumbnailView,
type: widget.type,
)
: PersonFaceWidget(
_faceThumbnail!,
personId: personID,
onErrorCallback: () {
if (mounted) {
setState(() {
_personID = null;
_faceThumbnail = null;
});
}
},
),
);
} else if (snapshot.hasError) {
_logger.severe("Error loading personID", snapshot.error);

View File

@@ -16,6 +16,7 @@ import "package:photos/ui/common/loading_widget.dart";
import "package:photos/ui/components/buttons/button_widget.dart";
import "package:photos/ui/components/dialog_widget.dart";
import "package:photos/ui/components/models/button_type.dart";
import "package:photos/ui/viewer/file/no_thumbnail_widget.dart";
import "package:photos/ui/viewer/search/result/person_face_widget.dart";
import "package:photos/utils/dialog_util.dart";
import "package:photos/utils/person_contact_linking_util.dart";
@@ -23,7 +24,7 @@ import "package:photos/utils/toast_util.dart";
class PersonEntityWithThumbnailFile {
final PersonEntity person;
final EnteFile thumbnailFile;
final EnteFile? thumbnailFile;
const PersonEntityWithThumbnailFile(
this.person,
@@ -61,7 +62,8 @@ class _LinkContactToPersonSelectionPageState
(person.data.isHidden || person.data.isIgnored)) {
continue;
}
final file = await PersonService.instance.getRecentFileOfPerson(person);
final file =
await PersonService.instance.getThumbnailFileOfPerson(person);
result.add(PersonEntityWithThumbnailFile(person, file));
}
return result;
@@ -70,6 +72,7 @@ class _LinkContactToPersonSelectionPageState
@override
Widget build(BuildContext context) {
_logger.info("Building LinkContactToPersonSelectionPage");
final smallFontSize = getEnteTextTheme(context).small.fontSize!;
final textScaleFactor =
MediaQuery.textScalerOf(context).scale(smallFontSize) / smallFontSize;
@@ -88,6 +91,11 @@ class _LinkContactToPersonSelectionPageState
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: EnteLoadingWidget());
} else if (snapshot.hasError) {
_logger.severe(
"Failed to load _personEntitiesWithThumnailFile",
snapshot.error,
snapshot.stackTrace,
);
return const Center(child: Icon(Icons.error_outline_rounded));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text(S.of(context).noResultsFound + '.'));
@@ -229,7 +237,8 @@ class _ReassignMeSelectionPageState extends State<ReassignMeSelectionPage> {
(person.data.isHidden || person.data.isIgnored)) {
continue;
}
final file = await PersonService.instance.getRecentFileOfPerson(person);
final file =
await PersonService.instance.getThumbnailFileOfPerson(person);
result.add(PersonEntityWithThumbnailFile(person, file));
}
return result;
@@ -238,6 +247,7 @@ class _ReassignMeSelectionPageState extends State<ReassignMeSelectionPage> {
@override
Widget build(BuildContext context) {
_logger.info("Building ReassignMeSelectionPage");
final smallFontSize = getEnteTextTheme(context).small.fontSize!;
final textScaleFactor =
MediaQuery.textScalerOf(context).scale(smallFontSize) / smallFontSize;
@@ -256,6 +266,11 @@ class _ReassignMeSelectionPageState extends State<ReassignMeSelectionPage> {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: EnteLoadingWidget());
} else if (snapshot.hasError) {
_logger.severe(
"Failed to load _personEntitiesWithThumnailFile",
snapshot.error,
snapshot.stackTrace,
);
return const Center(child: Icon(Icons.error_outline_rounded));
} else if (!snapshot.hasData || snapshot.data!.isEmpty) {
return Center(child: Text(S.of(context).noResultsFound + '.'));
@@ -410,11 +425,14 @@ class _RoundedPersonFaceWidget extends StatelessWidget {
),
),
),
child: PersonFaceWidget(
personEntitiesWithThumbnailFile.thumbnailFile,
personId: personEntitiesWithThumbnailFile.person.remoteID,
useFullFile: true,
),
child: personEntitiesWithThumbnailFile.thumbnailFile == null
? const NoThumbnailWidget(addBorder: false)
: PersonFaceWidget(
personEntitiesWithThumbnailFile.thumbnailFile!,
personId:
personEntitiesWithThumbnailFile.person.remoteID,
useFullFile: true,
),
),
),
),

View File

@@ -89,7 +89,7 @@ class _ContactSearchThumbnailWidgetState
if (person == null) {
return null;
} else {
return PersonService.instance.getRecentFileOfPerson(person);
return PersonService.instance.getThumbnailFileOfPerson(person);
}
});
}

View File

@@ -163,7 +163,7 @@ class _ContactRecommendationState extends State<ContactRecommendation> {
if (person == null) {
return null;
} else {
return PersonService.instance.getRecentFileOfPerson(person);
return PersonService.instance.getThumbnailFileOfPerson(person);
}
});
}