Cluster trigger (#4750)

## Description

Trigger clustering when user presses on unclustered face from file info.
This commit is contained in:
Laurens Priem
2025-01-17 14:05:22 +05:30
committed by GitHub
2 changed files with 26 additions and 18 deletions

View File

@@ -43,10 +43,10 @@ class MLService {
bool get isInitialized => _isInitialized;
bool get showClusteringIsHappening => _showClusteringIsHappening;
bool get showClusteringIsHappening => _clusteringIsHappening;
bool debugIndexingDisabled = false;
bool _showClusteringIsHappening = false;
bool _clusteringIsHappening = false;
bool _mlControllerStatus = false;
bool _isIndexingOrClusteringRunning = false;
bool _isRunningML = false;
@@ -123,7 +123,7 @@ class MLService {
if (force) {
_mlControllerStatus = true;
}
if (_cannotRunMLFunction() && !force) return;
if (!_canRunMLFunction(function: "AllML") && !force) return;
_isRunningML = true;
await sync();
@@ -182,7 +182,7 @@ class MLService {
/// This function first fetches from remote and checks if the image has already been analyzed
/// with the lastest faceMlVersion and stored on remote or local database. If so, it skips the image.
Future<void> fetchAndIndexAllImages() async {
if (_cannotRunMLFunction()) return;
if (!_canRunMLFunction(function: "Indexing")) return;
try {
_isIndexingOrClusteringRunning = true;
@@ -237,11 +237,19 @@ class MLService {
}
}
Future<void> clusterAllImages({bool clusterInBuckets = true}) async {
if (_cannotRunMLFunction()) return;
Future<void> clusterAllImages({
bool clusterInBuckets = true,
bool force = false,
}) async {
if (!_canRunMLFunction(function: "Clustering") && !force) return;
if (_clusteringIsHappening) {
_logger.info("clusterAllImages() is already running, returning");
return;
}
_logger.info("`clusterAllImages()` called");
_isIndexingOrClusteringRunning = true;
_clusteringIsHappening = true;
final clusterAllImagesTime = DateTime.now();
_logger.info('Pulling remote feedback before actually clustering');
@@ -261,11 +269,8 @@ class MLService {
}
try {
_showClusteringIsHappening = true;
// Get a sense of the total number of faces in the database
final int totalFaces =
await MLDataDB.instance.getTotalFaceCount();
final int totalFaces = await MLDataDB.instance.getTotalFaceCount();
final fileIDToCreationTime =
await FilesDB.instance.getFileIDToCreationTime();
final startEmbeddingFetch = DateTime.now();
@@ -414,7 +419,7 @@ class MLService {
} catch (e, s) {
_logger.severe("`clusterAllImages` failed", e, s);
} finally {
_showClusteringIsHappening = false;
_clusteringIsHappening = false;
_isIndexingOrClusteringRunning = false;
_cancelPauseIndexingAndClustering();
}
@@ -532,30 +537,30 @@ class MLService {
}
}
bool _cannotRunMLFunction({String function = ""}) {
bool _canRunMLFunction({required String function}) {
if (kDebugMode && Platform.isIOS && !_isIndexingOrClusteringRunning) {
return false;
return true;
}
if (_isIndexingOrClusteringRunning) {
_logger.info(
"Cannot run $function because indexing or clustering is already running",
);
_logStatus();
return true;
return false;
}
if (_mlControllerStatus == false) {
_logger.info(
"Cannot run $function because MLController does not allow it",
);
_logStatus();
return true;
return false;
}
if (debugIndexingDisabled) {
_logger.info(
"Cannot run $function because debugIndexingDisabled is true",
);
_logStatus();
return true;
return false;
}
if (_shouldPauseIndexingAndClustering) {
// This should ideally not be triggered, because one of the above should be triggered instead.
@@ -563,9 +568,9 @@ class MLService {
"Cannot run $function because indexing and clustering is being paused",
);
_logStatus();
return true;
return false;
}
return false;
return true;
}
void _logStatus() {

View File

@@ -1,3 +1,4 @@
import "dart:async";
import "dart:developer" show log;
import "dart:typed_data";
@@ -13,6 +14,7 @@ import "package:photos/models/ml/face/person.dart";
import "package:photos/services/machine_learning/face_ml/face_detection/detection.dart";
import "package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart";
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart";
import "package:photos/services/machine_learning/ml_service.dart";
import "package:photos/services/search_service.dart";
import "package:photos/theme/ente_theme.dart";
import "package:photos/ui/viewer/file/no_thumbnail_widget.dart";
@@ -121,6 +123,7 @@ class _FaceWidgetState extends State<FaceWidget> {
context,
S.of(context).faceNotClusteredYet,
);
unawaited(MLService.instance.clusterAllImages(force: true));
return;
}
if (widget.person != null) {