Highlight relevant face

This commit is contained in:
laurenspriem
2024-04-03 16:59:38 +05:30
parent 934d0bb3a0
commit 6a240ee030
8 changed files with 94 additions and 32 deletions

View File

@@ -36,6 +36,14 @@ class ClusterFeedbackService {
static final ClusterFeedbackService instance =
ClusterFeedbackService._privateConstructor();
static int lastViewedClusterID = -1;
static setLastViewedClusterID(int clusterID) {
lastViewedClusterID = clusterID;
}
static resetLastViewedClusterID() {
lastViewedClusterID = -1;
}
/// Returns a map of person's clusterID to map of closest clusterID to with disstance
Future<Map<int, List<(int, double)>>> getSuggestionsUsingMean(
Person p, {

View File

@@ -835,7 +835,7 @@ class SearchService {
ClusterPage(
files,
tagPrefix: "${ResultType.faces.toString()}_$clusterName",
cluserID: clusterId,
clusterID: clusterId,
),
);
},

View File

@@ -9,6 +9,7 @@ import "package:photos/face/model/face.dart";
import "package:photos/face/model/person.dart";
import 'package:photos/models/file/file.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";
import "package:photos/ui/viewer/people/cluster_page.dart";
import "package:photos/ui/viewer/people/cropped_face_image_view.dart";
@@ -21,18 +22,20 @@ class FaceWidget extends StatelessWidget {
final Face face;
final Person? person;
final int? clusterID;
final bool highlight;
const FaceWidget(
this.file,
this.face, {
this.person,
this.clusterID,
this.highlight = false,
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
if (Platform.isIOS) {
if (Platform.isIOS || Platform.isAndroid) {
return FutureBuilder<Uint8List?>(
future: getFaceCrop(),
builder: (context, snapshot) {
@@ -71,7 +74,7 @@ class FaceWidget extends StatelessWidget {
MaterialPageRoute(
builder: (context) => ClusterPage(
clusterFiles,
cluserID: clusterID!,
clusterID: clusterID!,
),
),
);
@@ -79,15 +82,32 @@ class FaceWidget extends StatelessWidget {
},
child: Column(
children: [
ClipRRect(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
child: SizedBox(
width: 60,
height: 60,
child: Image(
image: imageProvider,
fit: BoxFit.cover,
// TODO: the edges of the green line are still not properly rounded around ClipRRect
Container(
height: 60,
width: 60,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
side: highlight
? BorderSide(
color: getEnteColorScheme(context).primary700,
width: 2.0,
)
: BorderSide.none,
),
),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
child: SizedBox(
width: 60,
height: 60,
child: Image(
image: imageProvider,
fit: BoxFit.cover,
),
),
),
),
@@ -105,6 +125,15 @@ class FaceWidget extends StatelessWidget {
style: Theme.of(context).textTheme.bodySmall,
maxLines: 1,
),
// if (kDebugMode)
// if (highlight)
// const Text(
// "Highlighted",
// style: TextStyle(
// color: Colors.red,
// fontSize: 12,
// ),
// ),
],
),
);
@@ -169,7 +198,7 @@ class FaceWidget extends StatelessWidget {
MaterialPageRoute(
builder: (context) => ClusterPage(
clusterFiles,
cluserID: clusterID!,
clusterID: clusterID!,
),
),
);
@@ -177,15 +206,31 @@ class FaceWidget extends StatelessWidget {
},
child: Column(
children: [
ClipRRect(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
child: SizedBox(
width: 60,
height: 60,
child: CroppedFaceImageView(
enteFile: file,
face: face,
Container(
height: 60,
width: 60,
decoration: ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
side: highlight
? BorderSide(
color: getEnteColorScheme(context).primary700,
width: 2.0,
)
: BorderSide.none,
),
),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.elliptical(16, 12)),
child: SizedBox(
width: 60,
height: 60,
child: CroppedFaceImageView(
enteFile: file,
face: face,
),
),
),
),

View File

@@ -4,6 +4,7 @@ import "package:photos/face/db.dart";
import "package:photos/face/model/face.dart";
import "package:photos/face/model/person.dart";
import "package:photos/models/file/file.dart";
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart";
import "package:photos/ui/components/buttons/chip_button_widget.dart";
import "package:photos/ui/components/info_item_widget.dart";
import "package:photos/ui/viewer/file_details/face_widget.dart";
@@ -68,16 +69,21 @@ class FacesItemWidget extends StatelessWidget {
final (clusterIDToPerson, _) =
await FaceMLDataDB.instance.getClusterIdToPerson();
final lastViewedClusterID = ClusterFeedbackService.lastViewedClusterID;
final faceWidgets = <FaceWidget>[];
for (final Face face in faces) {
final int? clusterID = faceIdsToClusterIds[face.faceID];
final Person? person = clusterIDToPerson[clusterID];
final highlight =
(clusterID == lastViewedClusterID) && (person == null);
faceWidgets.add(
FaceWidget(
file,
face,
clusterID: clusterID,
person: person,
highlight: highlight,
),
);
}

View File

@@ -11,6 +11,7 @@ import 'package:photos/models/file/file.dart';
import 'package:photos/models/file_load_result.dart';
import 'package:photos/models/gallery_type.dart';
import 'package:photos/models/selected_files.dart';
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart";
import "package:photos/ui/components/notification_widget.dart";
import 'package:photos/ui/viewer/actions/file_selection_overlay_bar.dart';
import 'package:photos/ui/viewer/gallery/gallery.dart';
@@ -25,7 +26,7 @@ class ClusterPage extends StatefulWidget {
final List<EnteFile> searchResult;
final bool enableGrouping;
final String tagPrefix;
final int cluserID;
final int clusterID;
final Person? personID;
static const GalleryType appBarType = GalleryType.cluster;
@@ -35,7 +36,7 @@ class ClusterPage extends StatefulWidget {
this.searchResult, {
this.enableGrouping = true,
this.tagPrefix = "",
required this.cluserID,
required this.clusterID,
this.personID,
Key? key,
}) : super(key: key);
@@ -52,6 +53,7 @@ class _ClusterPageState extends State<ClusterPage> {
@override
void initState() {
super.initState();
ClusterFeedbackService.setLastViewedClusterID(widget.clusterID);
files = widget.searchResult;
_filesUpdatedEvent =
Bus.instance.on<LocalPhotosUpdatedEvent>().listen((event) {
@@ -123,8 +125,8 @@ class _ClusterPageState extends State<ClusterPage> {
child: NotificationWidget(
startIcon: Icons.person_add_outlined,
actionIcon: Icons.add_outlined,
text: S.of(context).addAName,
subText:S.of(context).findPeopleByName,
text: S.of(context).addAName,
subText: S.of(context).findPeopleByName,
// text: S.of(context).addAName,
// subText: S.of(context).findPersonsByName,
type: NotificationType.greenBanner,
@@ -132,7 +134,7 @@ class _ClusterPageState extends State<ClusterPage> {
if (widget.personID == null) {
final result = await showAssignPersonAction(
context,
clusterID: widget.cluserID,
clusterID: widget.clusterID,
);
if (result != null && result is Person) {
Navigator.pop(context);
@@ -159,7 +161,7 @@ class _ClusterPageState extends State<ClusterPage> {
FileSelectionOverlayBar(
ClusterPage.overlayType,
_selectedFiles,
clusterID: widget.cluserID,
clusterID: widget.clusterID,
),
],
),

View File

@@ -12,6 +12,7 @@ import 'package:photos/models/file/file.dart';
import 'package:photos/models/file_load_result.dart';
import 'package:photos/models/gallery_type.dart';
import 'package:photos/models/selected_files.dart';
import "package:photos/services/machine_learning/face_ml/feedback/cluster_feedback.dart";
import "package:photos/services/search_service.dart";
import 'package:photos/ui/viewer/actions/file_selection_overlay_bar.dart';
import 'package:photos/ui/viewer/gallery/gallery.dart';
@@ -45,6 +46,7 @@ class _PeoplePageState extends State<PeoplePage> {
@override
void initState() {
super.initState();
ClusterFeedbackService.resetLastViewedClusterID();
_peopleChangedEvent = Bus.instance.on<PeopleChangedEvent>().listen((event) {
setState(() {});
});

View File

@@ -51,7 +51,7 @@ class _PersonClustersState extends State<PersonClusters> {
builder: (context) => ClusterPage(
files,
personID: widget.person,
cluserID: index,
clusterID: index,
),
),
);

View File

@@ -31,8 +31,7 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
Key futureBuilderKey = UniqueKey();
// Declare a variable for the future
late Future<List<ClusterSuggestion>>
futureClusterSuggestions;
late Future<List<ClusterSuggestion>> futureClusterSuggestions;
@override
void initState() {
@@ -74,7 +73,7 @@ class _PersonClustersState extends State<PersonReviewClusterSuggestion> {
builder: (context) => ClusterPage(
files,
personID: widget.person,
cluserID: clusterID,
clusterID: clusterID,
),
),
);