From 62856cd5015ec05d584071e1fe3a57e30ff5a4f9 Mon Sep 17 00:00:00 2001 From: Yaros Date: Wed, 3 Jun 2026 18:13:39 +0200 Subject: [PATCH] feat: min face count per-user --- mobile/lib/domain/models/user_metadata.model.dart | 13 +++++++++++-- mobile/lib/domain/services/people.service.dart | 4 ++-- .../repositories/people.repository.dart | 4 ++-- .../providers/infrastructure/people.provider.dart | 4 +++- .../infrastructure/user_metadata.provider.dart | 4 ++-- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/mobile/lib/domain/models/user_metadata.model.dart b/mobile/lib/domain/models/user_metadata.model.dart index 3da1d94799..b73f798255 100644 --- a/mobile/lib/domain/models/user_metadata.model.dart +++ b/mobile/lib/domain/models/user_metadata.model.dart @@ -55,6 +55,7 @@ class Preferences { final bool tagsEnabled; final AvatarColor userAvatarColor; final bool showSupportBadge; + final int minimumFaces; const Preferences({ this.foldersEnabled = false, @@ -65,6 +66,7 @@ class Preferences { this.tagsEnabled = false, this.userAvatarColor = AvatarColor.primary, this.showSupportBadge = true, + this.minimumFaces = 3, }); Preferences copyWith({ @@ -76,6 +78,7 @@ class Preferences { bool? tagsEnabled, AvatarColor? userAvatarColor, bool? showSupportBadge, + int? minimumFaces, }) { return Preferences( foldersEnabled: foldersEnabled ?? this.foldersEnabled, @@ -86,6 +89,7 @@ class Preferences { tagsEnabled: tagsEnabled ?? this.tagsEnabled, userAvatarColor: userAvatarColor ?? this.userAvatarColor, showSupportBadge: showSupportBadge ?? this.showSupportBadge, + minimumFaces: minimumFaces ?? this.minimumFaces, ); } @@ -99,6 +103,7 @@ class Preferences { preferences["tags-Enabled"] = tagsEnabled; preferences["avatar-Color"] = userAvatarColor.value; preferences["purchase-ShowSupportBadge"] = showSupportBadge; + preferences["minimumFaces"] = minimumFaces; return preferences; } @@ -115,6 +120,7 @@ class Preferences { orElse: () => AvatarColor.primary, ), showSupportBadge: (map["purchase"] as Map?)?["showSupportBadge"] as bool? ?? true, + minimumFaces: (map["people"] as Map?)?["minimumFaces"] as int? ?? 3, ); } @@ -129,6 +135,7 @@ sharedLinksEnabled: $sharedLinksEnabled, tagsEnabled: $tagsEnabled, userAvatarColor: $userAvatarColor, showSupportBadge: $showSupportBadge, +minimumFaces: $minimumFaces, }'''; } @@ -145,7 +152,8 @@ showSupportBadge: $showSupportBadge, other.sharedLinksEnabled == sharedLinksEnabled && other.tagsEnabled == tagsEnabled && other.userAvatarColor == userAvatarColor && - other.showSupportBadge == showSupportBadge; + other.showSupportBadge == showSupportBadge && + other.minimumFaces == minimumFaces; } @override @@ -157,7 +165,8 @@ showSupportBadge: $showSupportBadge, sharedLinksEnabled.hashCode ^ tagsEnabled.hashCode ^ userAvatarColor.hashCode ^ - showSupportBadge.hashCode; + showSupportBadge.hashCode ^ + minimumFaces.hashCode; } } diff --git a/mobile/lib/domain/services/people.service.dart b/mobile/lib/domain/services/people.service.dart index ecfe83e5cb..73972dbdc0 100644 --- a/mobile/lib/domain/services/people.service.dart +++ b/mobile/lib/domain/services/people.service.dart @@ -18,8 +18,8 @@ class DriftPeopleService { return _repository.getAssetPeople(assetId); } - Future> getAllPeople() { - return _repository.getAllPeople(); + Future> getAllPeople({int minFaces = 3}) { + return _repository.getAllPeople(minFaces: minFaces); } Future updateName(String personId, String name) async { diff --git a/mobile/lib/infrastructure/repositories/people.repository.dart b/mobile/lib/infrastructure/repositories/people.repository.dart index 9e55d44867..cb32279a07 100644 --- a/mobile/lib/infrastructure/repositories/people.repository.dart +++ b/mobile/lib/infrastructure/repositories/people.repository.dart @@ -32,7 +32,7 @@ class DriftPeopleRepository extends DriftDatabaseRepository { }).get(); } - Future> getAllPeople() async { + Future> getAllPeople({int minFaces = 3}) async { final people = _db.personEntity; final faces = _db.assetFaceEntity; final assets = _db.remoteAssetEntity; @@ -49,7 +49,7 @@ class DriftPeopleRepository extends DriftDatabaseRepository { faces.isVisible.equals(true) & faces.deletedAt.isNull(), ) - ..groupBy([people.id], having: faces.id.count().isBiggerOrEqualValue(3) | people.name.equals('').not()) + ..groupBy([people.id], having: faces.id.count().isBiggerOrEqualValue(minFaces) | people.name.equals('').not()) ..orderBy([ OrderingTerm(expression: people.name.equals('').not(), mode: OrderingMode.desc), OrderingTerm(expression: faces.id.count(), mode: OrderingMode.desc), diff --git a/mobile/lib/providers/infrastructure/people.provider.dart b/mobile/lib/providers/infrastructure/people.provider.dart index 94a1b2447f..1939940975 100644 --- a/mobile/lib/providers/infrastructure/people.provider.dart +++ b/mobile/lib/providers/infrastructure/people.provider.dart @@ -3,6 +3,7 @@ import 'package:immich_mobile/domain/models/person.model.dart'; import 'package:immich_mobile/domain/services/people.service.dart'; import 'package:immich_mobile/infrastructure/repositories/people.repository.dart'; import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/user_metadata.provider.dart'; import 'package:immich_mobile/repositories/person_api.repository.dart'; final driftPeopleRepositoryProvider = Provider( @@ -20,5 +21,6 @@ final driftPeopleAssetProvider = FutureProvider.family, String final driftGetAllPeopleProvider = FutureProvider>((ref) async { final service = ref.watch(driftPeopleServiceProvider); - return service.getAllPeople(); + final prefs = await ref.watch(userMetadataPreferencesProvider.future); + return service.getAllPeople(minFaces: prefs?.minimumFaces ?? 3); }); diff --git a/mobile/lib/providers/infrastructure/user_metadata.provider.dart b/mobile/lib/providers/infrastructure/user_metadata.provider.dart index e5b9aa2a6e..357b43f4f6 100644 --- a/mobile/lib/providers/infrastructure/user_metadata.provider.dart +++ b/mobile/lib/providers/infrastructure/user_metadata.provider.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/user_metadata.model.dart'; import 'package:immich_mobile/infrastructure/repositories/user_metadata.repository.dart'; @@ -19,6 +20,5 @@ final userMetadataProvider = FutureProvider>((ref) async { final userMetadataPreferencesProvider = FutureProvider((ref) async { final metadataList = await ref.watch(userMetadataProvider.future); - final metadataWithPrefs = metadataList.firstWhere((meta) => meta.preferences != null); - return metadataWithPrefs.preferences; + return metadataList.firstWhereOrNull((meta) => meta.preferences != null)?.preferences; });