[mob][photos] Add guards to make sure no email is linked to more than one person
This commit is contained in:
@@ -24,6 +24,7 @@ import 'package:photos/ui/components/models/button_type.dart';
|
||||
import "package:photos/ui/components/text_input_widget.dart";
|
||||
import 'package:photos/ui/sharing/user_avator_widget.dart';
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
import "package:photos/utils/person_contact_linking_util.dart";
|
||||
import "package:photos/utils/share_util.dart";
|
||||
|
||||
class LinkEmailScreen extends StatefulWidget {
|
||||
@@ -214,17 +215,21 @@ class _LinkEmailScreen extends State<LinkEmailScreen> {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final result = await linkEmailToPerson(
|
||||
newEmail,
|
||||
widget.personID!,
|
||||
context,
|
||||
);
|
||||
if (!result) {
|
||||
_textController.clear();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final result = await linkEmailToPerson(
|
||||
newEmail,
|
||||
widget.personID!,
|
||||
context,
|
||||
);
|
||||
if (!result) {
|
||||
_textController.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.of(context).pop(newEmail);
|
||||
Navigator.of(context).pop(newEmail);
|
||||
} catch (e) {
|
||||
_logger.severe("Failed to link email to person", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -325,6 +330,10 @@ class _LinkEmailScreen extends State<LinkEmailScreen> {
|
||||
String personID,
|
||||
BuildContext context,
|
||||
) async {
|
||||
if (await checkIfEmailAlreadyAssignedToAPerson(context, email)) {
|
||||
throw Exception("Email already linked to a person");
|
||||
}
|
||||
|
||||
String? publicKey;
|
||||
|
||||
try {
|
||||
|
||||
@@ -17,6 +17,7 @@ import "package:photos/ui/components/dialog_widget.dart";
|
||||
import "package:photos/ui/components/models/button_type.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";
|
||||
import "package:photos/utils/toast_util.dart";
|
||||
|
||||
class PersonEntityWithThumbnailFile {
|
||||
@@ -45,6 +46,7 @@ class _LinkContactToPersonSelectionPageState
|
||||
extends State<LinkContactToPersonSelectionPage> {
|
||||
late Future<List<PersonEntityWithThumbnailFile>>
|
||||
_personEntitiesWithThumnailFile;
|
||||
final _logger = Logger('LinkContactToPersonSelectionPage');
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -115,15 +117,21 @@ class _LinkContactToPersonSelectionPageState
|
||||
itemBuilder: (context, index) {
|
||||
return _RoundedPersonFaceWidget(
|
||||
onTap: () async {
|
||||
await linkPersonToContact(
|
||||
context,
|
||||
emailToLink: widget.emailToLink!,
|
||||
personEntity: results[index].person,
|
||||
).then((updatedPerson) {
|
||||
if (updatedPerson != null) {
|
||||
Navigator.of(context).pop(updatedPerson);
|
||||
}
|
||||
});
|
||||
try {
|
||||
unawaited(
|
||||
linkPersonToContact(
|
||||
context,
|
||||
emailToLink: widget.emailToLink!,
|
||||
personEntity: results[index].person,
|
||||
).then((updatedPerson) {
|
||||
if (updatedPerson != null) {
|
||||
Navigator.of(context).pop(updatedPerson);
|
||||
}
|
||||
}),
|
||||
);
|
||||
} catch (e) {
|
||||
_logger.severe("Failed to link person to contact", e);
|
||||
}
|
||||
},
|
||||
itemSize: itemSize,
|
||||
personEntitiesWithThumbnailFile: results[index],
|
||||
@@ -141,6 +149,10 @@ class _LinkContactToPersonSelectionPageState
|
||||
required String emailToLink,
|
||||
required PersonEntity personEntity,
|
||||
}) async {
|
||||
if (await checkIfEmailAlreadyAssignedToAPerson(context, emailToLink)) {
|
||||
throw Exception("Email already linked");
|
||||
}
|
||||
|
||||
final personName = personEntity.data.name;
|
||||
PersonEntity? updatedPerson;
|
||||
final result = await showDialogWidget(
|
||||
|
||||
@@ -31,6 +31,7 @@ import "package:photos/ui/viewer/people/person_row_item.dart";
|
||||
import "package:photos/ui/viewer/search/result/person_face_widget.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
import "package:photos/utils/navigation_util.dart";
|
||||
import "package:photos/utils/person_contact_linking_util.dart";
|
||||
import "package:photos/utils/toast_util.dart";
|
||||
|
||||
class SaveOrEditPerson extends StatefulWidget {
|
||||
@@ -379,15 +380,23 @@ class _SaveOrEditPersonState extends State<SaveOrEditPerson> {
|
||||
shouldStickToDarkTheme: true,
|
||||
onTap: () async {
|
||||
if (widget.isEditing) {
|
||||
updatedPersonEntity = await updatePerson(context);
|
||||
try {
|
||||
updatedPersonEntity = await updatePerson(context);
|
||||
} catch (e) {
|
||||
_logger.severe("Error updating person", e);
|
||||
}
|
||||
} else {
|
||||
updatedPersonEntity = await addNewPerson(
|
||||
context,
|
||||
text: _inputName,
|
||||
clusterID: widget.clusterID!,
|
||||
birthdate: _selectedDate,
|
||||
email: _email,
|
||||
);
|
||||
try {
|
||||
updatedPersonEntity = await addNewPerson(
|
||||
context,
|
||||
text: _inputName,
|
||||
clusterID: widget.clusterID!,
|
||||
birthdate: _selectedDate,
|
||||
email: _email,
|
||||
);
|
||||
} catch (e) {
|
||||
_logger.severe("Error updating person", e);
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -530,6 +539,11 @@ class _SaveOrEditPersonState extends State<SaveOrEditPerson> {
|
||||
String? birthdate,
|
||||
String? email,
|
||||
}) async {
|
||||
if (email != null &&
|
||||
email.isNotEmpty &&
|
||||
await checkIfEmailAlreadyAssignedToAPerson(context, email)) {
|
||||
throw Exception("Email already assigned to a person");
|
||||
}
|
||||
try {
|
||||
if (userAlreadyAssigned) {
|
||||
return null;
|
||||
@@ -576,6 +590,12 @@ class _SaveOrEditPersonState extends State<SaveOrEditPerson> {
|
||||
|
||||
Future<PersonEntity?> updatePerson(BuildContext context) async {
|
||||
try {
|
||||
if (_email != null &&
|
||||
_email!.isNotEmpty &&
|
||||
_email != person!.data.email &&
|
||||
await checkIfEmailAlreadyAssignedToAPerson(context, _email!)) {
|
||||
throw Exception("Email already assigned to a person");
|
||||
}
|
||||
final String name = _inputName.trim();
|
||||
final String? birthDate = _selectedDate;
|
||||
final personEntity = await PersonService.instance.updateAttributes(
|
||||
|
||||
25
mobile/lib/utils/person_contact_linking_util.dart
Normal file
25
mobile/lib/utils/person_contact_linking_util.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
import "dart:io";
|
||||
|
||||
import "package:flutter/material.dart";
|
||||
import "package:photos/services/machine_learning/face_ml/person/person_service.dart";
|
||||
import "package:photos/utils/dialog_util.dart";
|
||||
|
||||
Future<bool> checkIfEmailAlreadyAssignedToAPerson(
|
||||
BuildContext context,
|
||||
String email,
|
||||
) async {
|
||||
final persons = await PersonService.instance.getPersons();
|
||||
for (var person in persons) {
|
||||
if (person.data.email == email) {
|
||||
await showErrorDialog(
|
||||
context,
|
||||
"Email already linked",
|
||||
"This email is already linked to a person",
|
||||
useRootNavigator: Platform.isIOS,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user