[mob] Rename and add more attr to PersonEntity
This commit is contained in:
parent
2163201046
commit
f5a9679c0e
|
@ -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
|
||||
|
|
|
@ -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 '
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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(),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -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?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue