[mob] Rename and add more attr to PersonEntity

This commit is contained in:
Neeraj Gupta 2024-04-04 16:06:16 +05:30
parent 2163201046
commit f5a9679c0e
24 changed files with 159 additions and 98 deletions

View file

@ -154,6 +154,8 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- permission_handler_apple (9.1.1):
- Flutter
- photo_manager (2.0.0):
- Flutter
- FlutterMacOS
@ -272,6 +274,7 @@ DEPENDENCIES:
- open_mail_app (from `.symlinks/plugins/open_mail_app/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- photo_manager (from `.symlinks/plugins/photo_manager/ios`)
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
- screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`)
@ -383,6 +386,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios"
photo_manager:
:path: ".symlinks/plugins/photo_manager/ios"
receive_sharing_intent:
@ -462,6 +467,7 @@ SPEC CHECKSUMS:
OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
photo_manager: 4f6810b7dfc4feb03b461ac1a70dacf91fba7604
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825

View file

@ -226,8 +226,8 @@ class FaceMLDataDB {
final person = mapRowToPerson(maps.first);
final List<int> fileId = [recentFileID];
int? avatarFileId;
if (person.attr.avatarFaceId != null) {
avatarFileId = int.tryParse(person.attr.avatarFaceId!.split('-')[0]);
if (person.data.avatarFaceId != null) {
avatarFileId = int.tryParse(person.data.avatarFaceId!.split('-')[0]);
if (avatarFileId != null) {
fileId.add(avatarFileId);
}
@ -488,7 +488,7 @@ class FaceMLDataDB {
await db.execute(fcClusterIDIndex);
}
Future<void> insert(Person p, int cluserID) async {
Future<void> insert(PersonEntity p, int cluserID) async {
debugPrint("inserting person");
final db = await instance.database;
await db.insert(
@ -506,7 +506,7 @@ class FaceMLDataDB {
);
}
Future<void> updatePerson(Person p) async {
Future<void> updatePerson(PersonEntity p) async {
final db = await instance.database;
await db.update(
personTable,
@ -639,10 +639,11 @@ class FaceMLDataDB {
return result;
}
Future<(Map<int, Person>, Map<String, Person>)> getClusterIdToPerson() async {
Future<(Map<int, PersonEntity>, Map<String, PersonEntity>)>
getClusterIdToPerson() async {
final db = await instance.database;
final List<Person> persons = await getPersons();
final Map<String, Person> personMap = {};
final List<PersonEntity> persons = await getPersons();
final Map<String, PersonEntity> personMap = {};
for (final p in persons) {
personMap[p.remoteID] = p;
}
@ -650,9 +651,9 @@ class FaceMLDataDB {
'SELECT $personIdColumn, $cluserIDColumn FROM $clusterPersonTable',
);
final Map<int, Person> result = {};
final Map<int, PersonEntity> result = {};
for (final map in maps) {
final Person? p = personMap[map[personIdColumn] as String];
final PersonEntity? p = personMap[map[personIdColumn] as String];
if (p != null) {
result[map[cluserIDColumn] as int] = p;
} else {
@ -664,7 +665,7 @@ class FaceMLDataDB {
return (result, personMap);
}
Future<List<Person>> getPersons() async {
Future<List<PersonEntity>> getPersons() async {
final db = await instance.database;
final List<Map<String, dynamic>> maps = await db.query(
personTable,
@ -714,7 +715,10 @@ class FaceMLDataDB {
await db.execute(createClusterSummaryTable);
}
Future<void> removeFilesFromPerson(List<EnteFile> files, Person p) async {
Future<void> removeFilesFromPerson(
List<EnteFile> files,
PersonEntity p,
) async {
final db = await instance.database;
final faceIdsResult = await db.rawQuery(
'SELECT $fcFaceId FROM $faceClustersTable LEFT JOIN $clusterPersonTable '

View file

@ -50,6 +50,7 @@ const dropFaceClustersTable = 'DROP TABLE IF EXISTS $faceClustersTable';
const personTable = 'person';
const idColumn = 'id';
const nameColumn = 'name';
const enteUserIdColumn = 'ente_user_id';
const personHiddenColumn = 'hidden';
const clusterToFaceIdJson = 'clusterToFaceIds';
const coverFaceIDColumn = 'cover_face_id';

View file

@ -25,25 +25,26 @@ bool sqlIntToBool(int? value, {bool defaultValue = false}) {
}
}
Map<String, dynamic> mapPersonToRow(Person p) {
Map<String, dynamic> mapPersonToRow(PersonEntity p) {
return {
idColumn: p.remoteID,
nameColumn: p.attr.name,
personHiddenColumn: boolToSQLInt(p.attr.isHidden),
coverFaceIDColumn: p.attr.avatarFaceId,
clusterToFaceIdJson: jsonEncode(p.attr.faces.toList()),
nameColumn: p.data.name,
personHiddenColumn: boolToSQLInt(p.data.isHidden),
coverFaceIDColumn: p.data.avatarFaceId,
clusterToFaceIdJson:
p.data.assigned != null ? jsonEncode(p.data.assigned!.toList()) : '{}',
};
}
Person mapRowToPerson(Map<String, dynamic> row) {
return Person(
PersonEntity mapRowToPerson(Map<String, dynamic> row) {
return PersonEntity(
row[idColumn] as String,
PersonAttr(
PersonData(
name: row[nameColumn] as String,
isHidden: sqlIntToBool(row[personHiddenColumn] as int),
avatarFaceId: row[coverFaceIDColumn] as String?,
faces: (jsonDecode(row[clusterToFaceIdJson]) as List)
.map((e) => e.toString())
assigned: (json.decode(row[clusterToFaceIdJson] as String) as List)
.map((e) => ClusterInfo.fromJson(e as Map<String, dynamic>))
.toList(),
),
);

View file

@ -1,47 +1,77 @@
class Person {
// PersonEntity represents information about a Person in the context of FaceClustering that is stored.
// On the remote server, the PersonEntity is stored as {Entity} with type person.
// On the device, this information is stored as [LocalEntityData] with type person.
class PersonEntity {
final String remoteID;
final PersonAttr attr;
Person(
final PersonData data;
PersonEntity(
this.remoteID,
this.attr,
this.data,
);
// copyWith
Person copyWith({
PersonEntity copyWith({
String? remoteID,
PersonAttr? attr,
PersonData? data,
}) {
return Person(
return PersonEntity(
remoteID ?? this.remoteID,
attr ?? this.attr,
data ?? this.data,
);
}
}
class PersonAttr {
class ClusterInfo {
final int id;
final Set<String> faces;
ClusterInfo({
required this.id,
required this.faces,
});
// toJson
Map<String, dynamic> toJson() => {
'id': id,
'faces': faces.toList(),
};
// from Json
factory ClusterInfo.fromJson(Map<String, dynamic> json) {
return ClusterInfo(
id: json['id'] as int,
faces: Set<String>.from(json['faces'] as List<String>),
);
}
}
class PersonData {
final String name;
final bool isHidden;
String? avatarFaceId;
final List<String> faces;
List<ClusterInfo>? assigned = List<ClusterInfo>.empty();
List<ClusterInfo>? rejected = List<ClusterInfo>.empty();
final String? birthDate;
PersonAttr({
PersonData({
required this.name,
required this.faces,
this.assigned,
this.rejected,
this.avatarFaceId,
this.isHidden = false,
this.birthDate,
});
// copyWith
PersonAttr copyWith({
PersonData copyWith({
String? name,
List<String>? faces,
List<ClusterInfo>? assigned,
String? avatarFaceId,
bool? isHidden,
int? version,
String? birthDate,
}) {
return PersonAttr(
return PersonData(
name: name ?? this.name,
faces: faces ?? this.faces,
assigned: assigned ?? this.assigned,
avatarFaceId: avatarFaceId ?? this.avatarFaceId,
isHidden: isHidden ?? this.isHidden,
birthDate: birthDate ?? this.birthDate,
@ -51,20 +81,26 @@ class PersonAttr {
// toJson
Map<String, dynamic> toJson() => {
'name': name,
'faces': faces.toList(),
'assigned': assigned?.map((e) => e.toJson()).toList(),
'rejected': rejected?.map((e) => e.toJson()).toList(),
'avatarFaceId': avatarFaceId,
'isHidden': isHidden,
'birthDate': birthDate,
};
// fromJson
factory PersonAttr.fromJson(Map<String, dynamic> json) {
return PersonAttr(
factory PersonData.fromJson(Map<String, dynamic> json) {
return PersonData(
name: json['name'] as String,
faces: List<String>.from(json['faces'] as List<dynamic>),
assigned: List<ClusterInfo>.from(
(json['assigned'] as List<dynamic>).map((e) => ClusterInfo.fromJson(e)),
),
rejected: List<ClusterInfo>.from(
(json['rejected'] as List<dynamic>).map((e) => ClusterInfo.fromJson(e)),
),
avatarFaceId: json['avatarFaceId'] as String?,
isHidden: json['isHidden'] as bool? ?? false,
birthDate: json['birthDatae'] as String?,
birthDate: json['birthDate'] as String?,
);
}
}

View file

@ -233,6 +233,7 @@ class EnteFile {
}
String get downloadUrl {
return "http://localhost:8700/$uploadedFileID";
final endpoint = Configuration.instance.getHttpEndpoint();
if (endpoint != kDefaultProductionEndpoint ||
FeatureFlagService.instance.disableCFWorker()) {
@ -247,6 +248,7 @@ class EnteFile {
}
String get thumbnailUrl {
return "http://localhost:8700/thumb/$uploadedFileID";
final endpoint = Configuration.instance.getHttpEndpoint();
if (endpoint != kDefaultProductionEndpoint ||
FeatureFlagService.instance.disableCFWorker()) {

View file

@ -1,6 +1,7 @@
import "package:equatable/equatable.dart";
import "package:photos/models/api/entity/type.dart";
// LocalEntityData is a class that represents the data of an entity stored locally.
class LocalEntityData {
final String id;
final EntityType type;

View file

@ -48,7 +48,7 @@ class ClusterFeedbackService {
/// Returns a map of person's clusterID to map of closest clusterID to with disstance
Future<Map<int, List<(int, double)>>> getSuggestionsUsingMean(
Person p, {
PersonEntity p, {
double maxClusterDistance = 0.4,
}) async {
// Get all the cluster data
@ -58,7 +58,7 @@ class ClusterFeedbackService {
final ignoredClusters = await faceMlDb.getPersonIgnoredClusters(p.remoteID);
final personClusters = await faceMlDb.getPersonClusterIDs(p.remoteID);
dev.log(
'existing clusters for ${p.attr.name} are $personClusters',
'existing clusters for ${p.data.name} are $personClusters',
name: "ClusterFeedbackService",
);
@ -81,7 +81,7 @@ class ClusterFeedbackService {
// log suggestions
for (final entry in suggestions.entries) {
dev.log(
' ${entry.value.length} suggestion for ${p.attr.name} for cluster ID ${entry.key} are suggestions ${entry.value}}',
' ${entry.value.length} suggestion for ${p.data.name} for cluster ID ${entry.key} are suggestions ${entry.value}}',
name: "ClusterFeedbackService",
);
}
@ -93,7 +93,7 @@ class ClusterFeedbackService {
/// 2. distance: the distance between the person's cluster and the suggestion
/// 3. usedMean: whether the suggestion was found using the mean (true) or the median (false)
Future<List<(int, double, bool)>> getSuggestionsUsingMedian(
Person p, {
PersonEntity p, {
int sampleSize = 50,
double maxMedianDistance = 0.65,
double goodMedianDistance = 0.55,
@ -107,7 +107,7 @@ class ClusterFeedbackService {
final ignoredClusters = await faceMlDb.getPersonIgnoredClusters(p.remoteID);
final personClusters = await faceMlDb.getPersonClusterIDs(p.remoteID);
dev.log(
'existing clusters for ${p.attr.name} are $personClusters',
'existing clusters for ${p.data.name} are $personClusters',
name: "getSuggestionsUsingMedian",
);
@ -267,11 +267,11 @@ class ClusterFeedbackService {
/// 3. bool: whether the suggestion was found using the mean (true) or the median (false)
/// 4. List<EnteFile>: the files in the cluster
Future<List<ClusterSuggestion>> getSuggestionForPerson(
Person person, {
PersonEntity person, {
bool extremeFilesFirst = true,
}) async {
_logger.info(
'getClusterFilesForPersonID ${kDebugMode ? person.attr.name : person.remoteID}',
'getClusterFilesForPersonID ${kDebugMode ? person.data.name : person.remoteID}',
);
try {
@ -325,7 +325,7 @@ class ClusterFeedbackService {
}
}
Future<void> removeFilesFromPerson(List<EnteFile> files, Person p) {
Future<void> removeFilesFromPerson(List<EnteFile> files, PersonEntity p) {
return FaceMLDataDB.instance.removeFilesFromPerson(files, p);
}
@ -333,13 +333,13 @@ class ClusterFeedbackService {
return FaceMLDataDB.instance.removeFilesFromCluster(files, clusterID);
}
Future<bool> checkAndDoAutomaticMerges(Person p) async {
Future<bool> checkAndDoAutomaticMerges(PersonEntity p) async {
final faceMlDb = FaceMLDataDB.instance;
final allClusterIdsToCountMap = (await faceMlDb.clusterIdToFaceCount());
final ignoredClusters = await faceMlDb.getPersonIgnoredClusters(p.remoteID);
final personClusters = await faceMlDb.getPersonClusterIDs(p.remoteID);
dev.log(
'existing clusters for ${p.attr.name} are $personClusters',
'existing clusters for ${p.data.name} are $personClusters',
name: "ClusterFeedbackService",
);
@ -361,7 +361,7 @@ class ClusterFeedbackService {
if (suggestions.isEmpty) {
dev.log(
'No automatic merge suggestions for ${p.attr.name}',
'No automatic merge suggestions for ${p.data.name}',
name: "ClusterFeedbackService",
);
return false;
@ -370,7 +370,7 @@ class ClusterFeedbackService {
// log suggestions
for (final entry in suggestions.entries) {
dev.log(
' ${entry.value.length} suggestion for ${p.attr.name} for cluster ID ${entry.key} are suggestions ${entry.value}}',
' ${entry.value.length} suggestion for ${p.data.name} for cluster ID ${entry.key} are suggestions ${entry.value}}',
name: "ClusterFeedbackService",
);
}
@ -677,7 +677,7 @@ class ClusterFeedbackService {
}
Future<void> _sortSuggestionsOnDistanceToPerson(
Person person,
PersonEntity person,
List<ClusterSuggestion> suggestions,
) async {
if (suggestions.isEmpty) {

View file

@ -0,0 +1,10 @@
import "package:photos/face/db.dart";
import "package:photos/services/entity_service.dart";
import "package:shared_preferences/shared_preferences.dart";
class PersonService {
final EntityService entityService;
final FaceMLDataDB faceMLDataDB;
final SharedPreferences _prefs;
PersonService(this.entityService, this.faceMLDataDB, this._prefs);
}

View file

@ -753,7 +753,7 @@ class SearchService {
}
final cluserIds = fileIdToClusterID[f.uploadedFileID ?? -1]!;
for (final cluster in cluserIds) {
final Person? p = clusterIDToPerson[cluster];
final PersonEntity? p = clusterIDToPerson[cluster];
if (p != null) {
if (personIdToFiles.containsKey(p.remoteID)) {
personIdToFiles[p.remoteID]!.add(f);
@ -781,11 +781,11 @@ class SearchService {
if (files.isEmpty) {
continue;
}
final Person p = personIdToPerson[personID]!;
final PersonEntity p = personIdToPerson[personID]!;
facesResult.add(
GenericSearchResult(
ResultType.faces,
p.attr.name,
p.data.name,
files,
params: {
kPersonParamID: personID,
@ -795,7 +795,7 @@ class SearchService {
routeToPage(
ctx,
PeoplePage(
tagPrefix: "${ResultType.faces.toString()}_${p.attr.name}",
tagPrefix: "${ResultType.faces.toString()}_${p.data.name}",
person: p,
),
);
@ -813,7 +813,7 @@ class SearchService {
final files = clusterIdToFiles[clusterId]!;
// final String clusterName = "ID:$clusterId, ${files.length}";
final String clusterName = "${files.length}";
final Person? p = clusterIDToPerson[clusterId];
final PersonEntity? p = clusterIDToPerson[clusterId];
if (p != null) {
throw Exception("Person should be null");
}

View file

@ -12,7 +12,7 @@ import "package:photos/ui/viewer/actions/file_selection_actions_widget.dart";
class BottomActionBarWidget extends StatelessWidget {
final GalleryType galleryType;
final Collection? collection;
final Person? person;
final PersonEntity? person;
final int? clusterID;
final SelectedFiles selectedFiles;
final VoidCallback? onCancel;

View file

@ -243,13 +243,13 @@ class _FaceDebugSectionWidgetState extends State<FaceDebugSectionWidget> {
trailingIconIsMuted: true,
onTap: () async {
try {
final List<Person> persons =
final List<PersonEntity> persons =
await FaceMLDataDB.instance.getPersons();
final EnteWatch w = EnteWatch('feedback')..start();
for (final Person p in persons) {
for (final PersonEntity p in persons) {
await ClusterFeedbackService.instance
.getSuggestionsUsingMean(p);
w.logAndReset('suggestion calculated for ${p.attr.name}');
w.logAndReset('suggestion calculated for ${p.data.name}');
}
w.log("done with feedback");
showShortToast(context, "done avg");

View file

@ -45,7 +45,7 @@ class FileSelectionActionsWidget extends StatefulWidget {
final Collection? collection;
final DeviceCollection? deviceCollection;
final SelectedFiles selectedFiles;
final Person? person;
final PersonEntity? person;
final int? clusterID;
const FileSelectionActionsWidget(
@ -130,7 +130,7 @@ class _FileSelectionActionsWidgetState
items.add(
SelectionActionButton(
icon: Icons.remove_circle_outline,
labelText: 'Not ${widget.person!.attr.name}?',
labelText: 'Not ${widget.person!.data.name}?',
onTap: anyUploadedFiles ? _onNotpersonClicked : null,
),
);
@ -653,8 +653,8 @@ class _FileSelectionActionsWidgetState
Future<void> _setPersonCover() async {
final EnteFile file = widget.selectedFiles.files.first;
final Person newPerson = widget.person!.copyWith(
attr: widget.person!.attr
final PersonEntity newPerson = widget.person!.copyWith(
data: widget.person!.data
.copyWith(avatarFaceId: file.uploadedFileID.toString()),
);
await FaceMLDataDB.instance.updatePerson(newPerson);
@ -686,7 +686,7 @@ class _FileSelectionActionsWidgetState
isInAlert: true,
),
],
title: "Remove these photos for ${widget.person!.attr.name}?",
title: "Remove these photos for ${widget.person!.data.name}?",
actionSheetType: ActionSheetType.defaultActionSheet,
);
if (actionResult?.action != null) {

View file

@ -11,7 +11,7 @@ class FileSelectionOverlayBar extends StatefulWidget {
final SelectedFiles selectedFiles;
final Collection? collection;
final Color? backgroundColor;
final Person? person;
final PersonEntity? person;
final int? clusterID;
const FileSelectionOverlayBar(

View file

@ -20,7 +20,7 @@ import "package:photos/utils/thumbnail_util.dart";
class FaceWidget extends StatelessWidget {
final EnteFile file;
final Face face;
final Person? person;
final PersonEntity? person;
final int? clusterID;
final bool highlight;
@ -114,7 +114,7 @@ class FaceWidget extends StatelessWidget {
const SizedBox(height: 8),
if (person != null)
Text(
person!.attr.name.trim(),
person!.data.name.trim(),
style: Theme.of(context).textTheme.bodySmall,
overflow: TextOverflow.ellipsis,
maxLines: 1,
@ -237,7 +237,7 @@ class FaceWidget extends StatelessWidget {
const SizedBox(height: 8),
if (person != null)
Text(
person!.attr.name.trim(),
person!.data.name.trim(),
style: Theme.of(context).textTheme.bodySmall,
overflow: TextOverflow.ellipsis,
maxLines: 1,

View file

@ -74,7 +74,7 @@ class FacesItemWidget extends StatelessWidget {
final faceWidgets = <FaceWidget>[];
for (final Face face in faces) {
final int? clusterID = faceIdsToClusterIds[face.faceID];
final Person? person = clusterIDToPerson[clusterID];
final PersonEntity? person = clusterIDToPerson[clusterID];
final highlight =
(clusterID == lastViewedClusterID) && (person == null);
faceWidgets.add(

View file

@ -178,7 +178,7 @@ class _PersonActionSheetState extends State<PersonActionSheet> {
return Flexible(
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 24, 4, 0),
child: FutureBuilder<List<Person>>(
child: FutureBuilder<List<PersonEntity>>(
future: _getPersons(),
builder: (context, snapshot) {
if (snapshot.hasError) {
@ -186,11 +186,11 @@ class _PersonActionSheetState extends State<PersonActionSheet> {
//Need to show an error on the UI here
return const SizedBox.shrink();
} else if (snapshot.hasData) {
final persons = snapshot.data as List<Person>;
final persons = snapshot.data as List<PersonEntity>;
final searchResults = _searchQuery.isNotEmpty
? persons
.where(
(element) => element.attr.name
(element) => element.data.name
.toLowerCase()
.contains(_searchQuery),
)
@ -270,9 +270,9 @@ class _PersonActionSheetState extends State<PersonActionSheet> {
}
try {
final String id = const Uuid().v4().toString();
final Person p = Person(
final PersonEntity p = PersonEntity(
id,
PersonAttr(name: text, faces: <String>[]),
PersonData(name: text, assigned: <ClusterInfo>[]),
);
await FaceMLDataDB.instance.insert(p, clusterID);
final bool extraPhotosFound = await ClusterFeedbackService.instance
@ -295,7 +295,7 @@ class _PersonActionSheetState extends State<PersonActionSheet> {
}
}
Future<List<Person>> _getPersons() async {
Future<List<PersonEntity>> _getPersons() async {
return FaceMLDataDB.instance.getPersons();
}
}

View file

@ -24,7 +24,7 @@ class ClusterAppBar extends StatefulWidget {
final String? title;
final SelectedFiles selectedFiles;
final int clusterID;
final Person? person;
final PersonEntity? person;
const ClusterAppBar(
this.type,

View file

@ -27,7 +27,7 @@ class ClusterPage extends StatefulWidget {
final bool enableGrouping;
final String tagPrefix;
final int clusterID;
final Person? personID;
final PersonEntity? personID;
final String appendTitle;
static const GalleryType appBarType = GalleryType.cluster;
@ -137,7 +137,7 @@ class _ClusterPageState extends State<ClusterPage> {
context,
clusterID: widget.clusterID,
);
if (result != null && result is Person) {
if (result != null && result is PersonEntity) {
Navigator.pop(context);
// ignore: unawaited_futures
routeToPage(context, PeoplePage(person: result));

View file

@ -22,7 +22,7 @@ class PeopleAppBar extends StatefulWidget {
final GalleryType type;
final String? title;
final SelectedFiles selectedFiles;
final Person person;
final PersonEntity person;
const PeopleAppBar(
this.type,
@ -100,7 +100,7 @@ class _AppBarWidgetState extends State<PeopleAppBar> {
submitButtonLabel: S.of(context).done,
hintText: S.of(context).enterAlbumName,
alwaysShowSuccessState: true,
initialValue: widget.person.attr.name,
initialValue: widget.person.data.name,
textCapitalization: TextCapitalization.words,
onSubmit: (String text) async {
// indicates user cancelled the rename request
@ -110,7 +110,7 @@ class _AppBarWidgetState extends State<PeopleAppBar> {
try {
final updatePerson = widget.person
.copyWith(attr: widget.person.attr.copyWith(name: text));
.copyWith(data: widget.person.data.copyWith(name: text));
await FaceMLDataDB.instance.updatePerson(updatePerson);
if (mounted) {
_appBarTitle = text;

View file

@ -20,7 +20,7 @@ import "package:photos/ui/viewer/people/people_app_bar.dart";
class PeoplePage extends StatefulWidget {
final String tagPrefix;
final Person person;
final PersonEntity person;
static const GalleryType appBarType = GalleryType.peopleTag;
static const GalleryType overlayType = GalleryType.peopleTag;
@ -86,13 +86,13 @@ class _PeoplePageState extends State<PeoplePage> {
@override
Widget build(BuildContext context) {
_logger.info("Building for ${widget.person.attr.name}");
_logger.info("Building for ${widget.person.data.name}");
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(50.0),
child: PeopleAppBar(
GalleryType.peopleTag,
widget.person.attr.name,
widget.person.data.name,
_selectedFiles,
widget.person,
),

View file

@ -14,7 +14,7 @@ import "package:photos/ui/viewer/people/cluster_page.dart";
import "package:photos/ui/viewer/search/result/person_face_widget.dart";
class PersonClusters extends StatefulWidget {
final Person person;
final PersonEntity person;
const PersonClusters(
this.person, {
@ -31,7 +31,7 @@ class _PersonClustersState extends State<PersonClusters> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.person.attr.name),
title: Text(widget.person.data.name),
),
body: FutureBuilder<Map<int, List<EnteFile>>>(
future: SearchService.instance

View file

@ -15,7 +15,7 @@ import "package:photos/ui/viewer/people/cluster_page.dart";
import "package:photos/ui/viewer/search/result/person_face_widget.dart";
class PersonReviewClusterSuggestion extends StatefulWidget {
final Person person;
final PersonEntity person;
const PersonReviewClusterSuggestion(
this.person, {
@ -55,7 +55,7 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
if (snapshot.data!.isEmpty) {
return Center(
child: Text(
"No suggestions for ${widget.person.attr.name}",
"No suggestions for ${widget.person.data.name}",
style: getEnteTextTheme(context).largeMuted,
),
);
@ -160,8 +160,8 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
),
Text(
files.length > 1
? "These photos belong to ${widget.person.attr.name}?"
: "This photo belongs to ${widget.person.attr.name}?",
? "These photos belong to ${widget.person.data.name}?"
: "This photo belongs to ${widget.person.data.name}?",
style: getEnteTextTheme(context).largeMuted,
),
const SizedBox(height: 24),

View file

@ -2,7 +2,7 @@ import "package:flutter/material.dart";
import "package:photos/face/model/person.dart";
class PersonRowItem extends StatelessWidget {
final Person person;
final PersonEntity person;
final VoidCallback onTap;
const PersonRowItem({
@ -15,9 +15,9 @@ class PersonRowItem extends StatelessWidget {
Widget build(BuildContext context) {
return ListTile(
leading: CircleAvatar(
child: Text(person.attr.name.substring(0, 1)),
child: Text(person.data.name.substring(0, 1)),
),
title: Text(person.attr.name),
title: Text(person.data.name),
onTap: onTap,
);
}