Merge branch 'mobile_face' into fix_face_thumbnail

This commit is contained in:
ashilkn 2024-04-27 11:10:10 +05:30
commit 58cd9350c0
4 changed files with 118 additions and 12 deletions

View file

@ -348,6 +348,18 @@ class FaceMLDataDB {
return result;
}
Future<int?> getClusterIDForFaceID(String faceID) async {
final db = await instance.sqliteAsyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
'SELECT $fcClusterID FROM $faceClustersTable WHERE $fcFaceId = ?',
[faceID],
);
if (maps.isEmpty) {
return null;
}
return maps.first[fcClusterID] as int;
}
Future<Map<int, Iterable<String>>> getAllClusterIdToFaceIDs() async {
final db = await instance.sqliteAsyncDB;
final Map<int, List<String>> result = {};
@ -420,8 +432,8 @@ class FaceMLDataDB {
Future<Map<String, int?>> getFaceIdsToClusterIds(
Iterable<String> faceIds,
) async {
final db = await instance.sqliteAsyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
final db = await instance.database;
final List<Map<String, dynamic>> maps = await db.rawQuery(
'SELECT $fcFaceId, $fcClusterID FROM $faceClustersTable where $fcFaceId IN (${faceIds.map((id) => "'$id'").join(",")})',
);
final Map<String, int?> result = {};
@ -433,8 +445,8 @@ class FaceMLDataDB {
Future<Map<int, Set<int>>> getFileIdToClusterIds() async {
final Map<int, Set<int>> result = {};
final db = await instance.sqliteAsyncDB;
final List<Map<String, dynamic>> maps = await db.getAll(
final db = await instance.database;
final List<Map<String, dynamic>> maps = await db.rawQuery(
'SELECT $fcClusterID, $fcFaceId FROM $faceClustersTable',
);

View file

@ -966,7 +966,12 @@ class FaceMlService {
switch (typeOfData) {
case FileDataForML.fileData:
final stopwatch = Stopwatch()..start();
final File? file = await getFile(enteFile, isOrigin: true);
File? file;
if (enteFile.fileType == FileType.video) {
file = await getThumbnailForUploadedFile(enteFile);
} else {
file = await getFile(enteFile, isOrigin: true);
}
if (file == null) {
_logger.warning("Could not get file for $enteFile");
imagePath = null;
@ -1294,10 +1299,6 @@ class FaceMlService {
if (!enteFile.isUploaded || enteFile.isOwner == false) {
return true;
}
// Skip if the file is a video
if (enteFile.fileType == FileType.video) {
return true;
}
// I don't know how motionPhotos and livePhotos work, so I'm also just skipping them for now
if (enteFile.fileType == FileType.other) {
return true;

View file

@ -4,6 +4,7 @@ import "dart:typed_data";
import "package:flutter/cupertino.dart";
import "package:flutter/foundation.dart" show kDebugMode;
import "package:flutter/material.dart";
import "package:photos/extensions/stop_watch.dart";
import "package:photos/face/db.dart";
import "package:photos/face/model/face.dart";
import "package:photos/face/model/person.dart";
@ -65,7 +66,50 @@ class _FaceWidgetState extends State<FaceWidget> {
name: "FaceWidget",
);
if (widget.person == null && widget.clusterID == null) {
return;
// Get faceID and double check that it doesn't belong to an existing clusterID. If it does, push that cluster page
final w = (kDebugMode ? EnteWatch('FaceWidget') : null)
?..start();
final existingClusterID = await FaceMLDataDB.instance
.getClusterIDForFaceID(widget.face.faceID);
w?.log('getting existing clusterID for faceID');
if (existingClusterID != null) {
final fileIdsToClusterIds =
await FaceMLDataDB.instance.getFileIdToClusterIds();
final files = await SearchService.instance.getAllFiles();
final clusterFiles = files
.where(
(file) =>
fileIdsToClusterIds[file.uploadedFileID]
?.contains(existingClusterID) ??
false,
)
.toList();
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ClusterPage(
clusterFiles,
clusterID: existingClusterID,
),
),
);
}
// Create new clusterID for the faceID and update DB to assign the faceID to the new clusterID
final int newClusterID =
DateTime.now().microsecondsSinceEpoch;
await FaceMLDataDB.instance.updateFaceIdToClusterId(
{widget.face.faceID: newClusterID},
);
// Push page for the new cluster
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ClusterPage(
[widget.file],
clusterID: newClusterID,
),
),
);
}
if (widget.person != null) {
await Navigator.of(context).push(
@ -230,7 +274,49 @@ class _FaceWidgetState extends State<FaceWidget> {
name: "FaceWidget",
);
if (widget.person == null && widget.clusterID == null) {
return;
// Get faceID and double check that it doesn't belong to an existing clusterID. If it does, push that cluster page
final w = (kDebugMode ? EnteWatch('FaceWidget') : null)
?..start();
final existingClusterID = await FaceMLDataDB.instance
.getClusterIDForFaceID(widget.face.faceID);
w?.log('getting existing clusterID for faceID');
if (existingClusterID != null) {
final fileIdsToClusterIds =
await FaceMLDataDB.instance.getFileIdToClusterIds();
final files = await SearchService.instance.getAllFiles();
final clusterFiles = files
.where(
(file) =>
fileIdsToClusterIds[file.uploadedFileID]
?.contains(existingClusterID) ??
false,
)
.toList();
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ClusterPage(
clusterFiles,
clusterID: existingClusterID,
),
),
);
}
// Create new clusterID for the faceID and update DB to assign the faceID to the new clusterID
final int newClusterID = DateTime.now().microsecondsSinceEpoch;
await FaceMLDataDB.instance.updateFaceIdToClusterId(
{widget.face.faceID: newClusterID},
);
// Push page for the new cluster
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ClusterPage(
[widget.file],
clusterID: newClusterID,
),
),
);
}
if (widget.person != null) {
await Navigator.of(context).push(

View file

@ -4,8 +4,10 @@ import "dart:io" show File;
import 'package:flutter/material.dart';
import "package:photos/face/model/face.dart";
import "package:photos/models/file/file.dart";
import "package:photos/models/file/file_type.dart";
import "package:photos/ui/viewer/file/thumbnail_widget.dart";
import "package:photos/utils/file_util.dart";
import "package:photos/utils/thumbnail_util.dart";
class CroppedFaceInfo {
final Image image;
@ -103,7 +105,12 @@ class CroppedFaceImageView extends StatelessWidget {
}
Future<Image?> getImage() async {
final File? ioFile = await getFile(enteFile);
final File? ioFile;
if (enteFile.fileType == FileType.video) {
ioFile = await getThumbnailForUploadedFile(enteFile);
} else {
ioFile = await getFile(enteFile);
}
if (ioFile == null) {
return null;
}