diff --git a/mobile/lib/models/search/hierarchical/magic_filter.dart b/mobile/lib/models/search/hierarchical/magic_filter.dart index 765a52e286..841e0427a3 100644 --- a/mobile/lib/models/search/hierarchical/magic_filter.dart +++ b/mobile/lib/models/search/hierarchical/magic_filter.dart @@ -1,41 +1,48 @@ -import "package:flutter/widgets.dart"; +import "package:flutter/material.dart"; import "package:photos/models/file/file.dart"; import "package:photos/models/search/hierarchical/hierarchical_search_filter.dart"; class MagicFilter extends HierarchicalSearchFilter { + final String filterName; + final int occurrence; + + MagicFilter({ + required this.filterName, + required this.occurrence, + super.matchedUploadedIDs, + }); + @override Set getMatchedUploadedIDs() { - // TODO: implement getMatchedUploadedIDs - throw UnimplementedError(); + return matchedUploadedIDs; } @override IconData? icon() { - // TODO: implement icon - throw UnimplementedError(); + return Icons.auto_awesome; } @override bool isMatch(EnteFile file) { - // TODO: implement isMatch throw UnimplementedError(); } @override bool isSameFilter(HierarchicalSearchFilter other) { - // TODO: implement isSameFilter - throw UnimplementedError(); + if (other is MagicFilter && other.name() == name()) { + return true; + } + + return false; } @override String name() { - // TODO: implement name - throw UnimplementedError(); + return filterName; } @override int relevance() { - // TODO: implement relevance - throw UnimplementedError(); + return occurrence; } } diff --git a/mobile/lib/services/magic_cache_service.dart b/mobile/lib/services/magic_cache_service.dart index 2fb2f8fbed..ce1aceff63 100644 --- a/mobile/lib/services/magic_cache_service.dart +++ b/mobile/lib/services/magic_cache_service.dart @@ -16,6 +16,7 @@ import "package:photos/models/file/extensions/file_props.dart"; import "package:photos/models/file/file.dart"; import "package:photos/models/ml/discover/prompt.dart"; import "package:photos/models/search/generic_search_result.dart"; +import "package:photos/models/search/hierarchical/hierarchical_search_filter.dart"; import "package:photos/models/search/hierarchical/magic_filter.dart"; import "package:photos/models/search/search_types.dart"; import "package:photos/service_locator.dart"; @@ -141,12 +142,18 @@ GenericSearchResult? toGenericSearchResult( ResultType.magic, title, enteFilesInMagicCache, - hierarchicalSearchFilter: MagicFilter(), + hierarchicalSearchFilter: + //TODO: Check if matchedUploadedIDs should be passed + MagicFilter(filterName: title, occurrence: kMostRelevantFilter), ).heroTag(), ), ); }, - hierarchicalSearchFilter: MagicFilter(), + //TODO: Check if matchedUploadedIDs should be passed + hierarchicalSearchFilter: MagicFilter( + filterName: title, + occurrence: kMostRelevantFilter, + ), ); } @@ -269,7 +276,7 @@ class MagicCacheService { return _promptFuture!; } - Future> _getMagicCache() async { + Future> getMagicCache() async { if (_magicCacheFuture != null) { return _magicCacheFuture!; } @@ -310,7 +317,7 @@ class MagicCacheService { final EnteWatch? w = kDebugMode ? EnteWatch("magicGenericSearchResult") : null; w?.start(); - final magicCaches = await _getMagicCache(); + final magicCaches = await getMagicCache(); final List prompts = await getPrompts(); if (magicCaches.isEmpty) { w?.log("No magic cache found"); diff --git a/mobile/lib/services/search_service.dart b/mobile/lib/services/search_service.dart index 50e037b90a..12eefd3d45 100644 --- a/mobile/lib/services/search_service.dart +++ b/mobile/lib/services/search_service.dart @@ -1240,12 +1240,20 @@ class SearchService { ResultType.magic, query, files, - hierarchicalSearchFilter: MagicFilter(), + hierarchicalSearchFilter: MagicFilter( + filterName: query, + occurrence: kMostRelevantFilter, + matchedUploadedIDs: filesToUploadedFileIDs(files), + ), ).heroTag(), ), ); }, - hierarchicalSearchFilter: MagicFilter(), + hierarchicalSearchFilter: MagicFilter( + filterName: query, + occurrence: kMostRelevantFilter, + matchedUploadedIDs: filesToUploadedFileIDs(files), + ), ), ); } diff --git a/mobile/lib/utils/hierarchical_search_util.dart b/mobile/lib/utils/hierarchical_search_util.dart index 7317a7556f..4b0e1f46d0 100644 --- a/mobile/lib/utils/hierarchical_search_util.dart +++ b/mobile/lib/utils/hierarchical_search_util.dart @@ -16,12 +16,15 @@ import "package:photos/models/search/hierarchical/face_filter.dart"; import "package:photos/models/search/hierarchical/file_type_filter.dart"; import "package:photos/models/search/hierarchical/hierarchical_search_filter.dart"; import "package:photos/models/search/hierarchical/location_filter.dart"; +import "package:photos/models/search/hierarchical/magic_filter.dart"; import "package:photos/services/collections_service.dart"; import "package:photos/services/location_service.dart"; import "package:photos/services/machine_learning/face_ml/face_filtering/face_filtering_constants.dart"; import "package:photos/services/machine_learning/face_ml/person/person_service.dart"; +import "package:photos/services/magic_cache_service.dart"; import "package:photos/services/search_service.dart"; import "package:photos/ui/viewer/gallery/state/search_filter_data_provider.dart"; +import "package:photos/utils/file_util.dart"; Future> getFilteredFiles( List filters, @@ -118,9 +121,11 @@ void curateFilters( ); final contactsFilters = _curateContactsFilter(files); final faceFilters = await curateFaceFilters(files); + final magicFilters = await curateMagicFilters(files); searchFilterDataProvider.clearAndAddRecommendations( [ + ...magicFilters, ...faceFilters, ...fileTypeFilters, ...contactsFilters, @@ -358,3 +363,25 @@ Future> curateFaceFilters( rethrow; } } + +Future> curateMagicFilters(List files) async { + final magicFilters = []; + + final magicCaches = await MagicCacheService.instance.getMagicCache(); + final filesUploadedFileIDs = filesToUploadedFileIDs(files); + for (MagicCache magicCache in magicCaches) { + final uploadedIDs = magicCache.fileUploadedIDs.toSet(); + final intersection = uploadedIDs.intersection(filesUploadedFileIDs); + + if (intersection.length > 3) { + magicFilters.add( + MagicFilter( + filterName: magicCache.title, + occurrence: intersection.length, + ), + ); + } + } + + return magicFilters; +}