Merge branch 'mobile_face' into fix_face_thumbnail
This commit is contained in:
commit
58cd9350c0
|
@ -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',
|
||||
);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue