3
mobile/lib/events/magic_cache_updated_event.dart
Normal file
3
mobile/lib/events/magic_cache_updated_event.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
import "package:photos/events/event.dart";
|
||||
|
||||
class MagicCacheUpdatedEvent extends Event {}
|
||||
@@ -6,6 +6,7 @@ import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/events/collection_updated_event.dart";
|
||||
import "package:photos/events/event.dart";
|
||||
import "package:photos/events/location_tag_updated_event.dart";
|
||||
import "package:photos/events/magic_cache_updated_event.dart";
|
||||
import "package:photos/events/people_changed_event.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/collection/collection.dart";
|
||||
@@ -291,6 +292,8 @@ extension SectionTypeExtensions on SectionType {
|
||||
switch (this) {
|
||||
case SectionType.location:
|
||||
return [Bus.instance.on<LocationTagUpdatedEvent>()];
|
||||
case SectionType.magic:
|
||||
return [Bus.instance.on<MagicCacheUpdatedEvent>()];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ class SemanticSearchService {
|
||||
return results;
|
||||
}
|
||||
|
||||
Future<Set<int>> getMatchingFileIDs(
|
||||
Future<List<int>> getMatchingFileIDs(
|
||||
String query,
|
||||
double minimumSimilarity,
|
||||
) async {
|
||||
@@ -187,7 +187,7 @@ class SemanticSearchService {
|
||||
textEmbedding,
|
||||
minimumSimilarity: minimumSimilarity,
|
||||
);
|
||||
final result = <int>{};
|
||||
final result = <int>[];
|
||||
for (final r in queryResults) {
|
||||
result.add(r.id);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import "package:logging/logging.dart";
|
||||
import "package:path_provider/path_provider.dart";
|
||||
import "package:photos/core/event_bus.dart";
|
||||
import "package:photos/events/file_uploaded_event.dart";
|
||||
import "package:photos/events/magic_cache_updated_event.dart";
|
||||
import "package:photos/extensions/stop_watch.dart";
|
||||
import "package:photos/models/file/extensions/file_props.dart";
|
||||
import "package:photos/models/file/file.dart";
|
||||
@@ -24,13 +25,26 @@ import "package:shared_preferences/shared_preferences.dart";
|
||||
|
||||
class MagicCache {
|
||||
final String title;
|
||||
final Set<int> fileUploadedIDs;
|
||||
final List<int> fileUploadedIDs;
|
||||
Map<int, int>? _fileIdToPositionMap;
|
||||
|
||||
MagicCache(this.title, this.fileUploadedIDs);
|
||||
|
||||
// Get map of uploadID to index in fileUploadedIDs
|
||||
Map<int, int> get fileIdToPositionMap {
|
||||
if (_fileIdToPositionMap == null) {
|
||||
_fileIdToPositionMap = {};
|
||||
for (int i = 0; i < fileUploadedIDs.length; i++) {
|
||||
_fileIdToPositionMap![fileUploadedIDs[i]] = i;
|
||||
}
|
||||
}
|
||||
return _fileIdToPositionMap!;
|
||||
}
|
||||
|
||||
factory MagicCache.fromJson(Map<String, dynamic> json) {
|
||||
return MagicCache(
|
||||
json['title'],
|
||||
Set<int>.from(json['fileUploadedIDs']),
|
||||
List<int>.from(json['fileUploadedIDs']),
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() {
|
||||
@@ -54,14 +68,25 @@ class MagicCache {
|
||||
GenericSearchResult? toGenericSearchResult(
|
||||
Prompt prompt,
|
||||
List<EnteFile> enteFilesInMagicCache,
|
||||
Map<int, int> fileIdToPositionMap,
|
||||
) {
|
||||
if (enteFilesInMagicCache.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
if (!prompt.recentFirst) {
|
||||
enteFilesInMagicCache.sort((a, b) {
|
||||
return fileIdToPositionMap[a.uploadedFileID!]!
|
||||
.compareTo(fileIdToPositionMap[b.uploadedFileID!]!);
|
||||
});
|
||||
}
|
||||
return GenericSearchResult(
|
||||
ResultType.magic,
|
||||
prompt.title,
|
||||
enteFilesInMagicCache,
|
||||
params: {
|
||||
"enableGrouping": prompt.recentFirst,
|
||||
"fileIdToPosMap": fileIdToPositionMap
|
||||
},
|
||||
onResultTap: (ctx) {
|
||||
routeToPage(
|
||||
ctx,
|
||||
@@ -69,6 +94,7 @@ GenericSearchResult? toGenericSearchResult(
|
||||
enteFilesInMagicCache,
|
||||
name: prompt.title,
|
||||
enableGrouping: prompt.recentFirst,
|
||||
fileIdToPosMap: fileIdToPositionMap,
|
||||
heroTag: GenericSearchResult(
|
||||
ResultType.magic,
|
||||
prompt.title,
|
||||
@@ -122,8 +148,7 @@ class MagicCacheService {
|
||||
return _prefs.getInt(_lastMagicCacheUpdateTime) ?? 0;
|
||||
}
|
||||
|
||||
bool get enableDiscover =>
|
||||
localSettings.isMLIndexingEnabled && flagService.internalUser;
|
||||
bool get enableDiscover => localSettings.isMLIndexingEnabled;
|
||||
|
||||
Future<void> _updateCacheIfTheTimeHasCome() async {
|
||||
if (!enableDiscover) {
|
||||
@@ -133,13 +158,11 @@ class MagicCacheService {
|
||||
.getAssetIfUpdated(_kMagicPromptsDataUrl);
|
||||
if (updatedJSONFile != null) {
|
||||
_pendingUpdateReason.add("Prompts data updated");
|
||||
} else {
|
||||
if (lastMagicCacheUpdateTime <
|
||||
DateTime.now()
|
||||
.subtract(const Duration(days: 3))
|
||||
.millisecondsSinceEpoch) {
|
||||
_pendingUpdateReason.add("Cache is old");
|
||||
}
|
||||
} else if (lastMagicCacheUpdateTime <
|
||||
DateTime.now()
|
||||
.subtract(const Duration(days: 1))
|
||||
.millisecondsSinceEpoch) {
|
||||
_pendingUpdateReason.add("Cache is old");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,10 +170,13 @@ class MagicCacheService {
|
||||
return (await getApplicationSupportDirectory()).path + "/cache/magic_cache";
|
||||
}
|
||||
|
||||
Future<void> updateCache() async {
|
||||
Future<void> updateCache({bool forced = false}) async {
|
||||
if (!enableDiscover) {
|
||||
return;
|
||||
}
|
||||
if (forced) {
|
||||
_pendingUpdateReason.add("Forced update");
|
||||
}
|
||||
try {
|
||||
if (_pendingUpdateReason.isEmpty || _isUpdateInProgress) {
|
||||
_logger.info(
|
||||
@@ -178,10 +204,12 @@ class MagicCacheService {
|
||||
w?.log("cacheWritten");
|
||||
await _resetLastMagicCacheUpdateTime();
|
||||
w?.logAndReset('done');
|
||||
Bus.instance.fire(MagicCacheUpdatedEvent());
|
||||
} catch (e, s) {
|
||||
_logger.info("Error updating magic cache", e, s);
|
||||
} finally {
|
||||
_isUpdateInProgress = false;
|
||||
Bus.instance.fire(MagicCacheUpdatedEvent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,9 +269,12 @@ class MagicCacheService {
|
||||
w?.log("cacheFound");
|
||||
}
|
||||
final Map<String, List<EnteFile>> magicIdToFiles = {};
|
||||
|
||||
final Map<String, Prompt> promptMap = {};
|
||||
final Map<String, Map<int, int>> promptFileOrder = {};
|
||||
for (MagicCache c in magicCaches) {
|
||||
magicIdToFiles[c.title] = [];
|
||||
promptFileOrder[c.title] = c.fileIdToPositionMap;
|
||||
}
|
||||
for (final p in prompts) {
|
||||
promptMap[p.title] = p;
|
||||
@@ -253,7 +284,8 @@ class MagicCacheService {
|
||||
for (EnteFile file in files) {
|
||||
if (!file.isUploaded) continue;
|
||||
for (MagicCache magicCache in magicCaches) {
|
||||
if (magicCache.fileUploadedIDs.contains(file.uploadedFileID!)) {
|
||||
if (magicCache.fileIdToPositionMap
|
||||
.containsKey(file.uploadedFileID!)) {
|
||||
if (file.isVideo &&
|
||||
(promptMap[magicCache.title]?.showVideo ?? true) == false) {
|
||||
continue;
|
||||
@@ -266,6 +298,7 @@ class MagicCacheService {
|
||||
final genericSearchResult = toGenericSearchResult(
|
||||
p,
|
||||
magicIdToFiles[p.title] ?? [],
|
||||
promptFileOrder[p.title] ?? {},
|
||||
);
|
||||
if (genericSearchResult != null) {
|
||||
genericSearchResults.add(genericSearchResult);
|
||||
|
||||
@@ -1039,6 +1039,7 @@ class SearchService {
|
||||
MagicResultScreen(
|
||||
files,
|
||||
name: query,
|
||||
enableGrouping: false,
|
||||
heroTag: GenericSearchResult(ResultType.magic, query, files)
|
||||
.heroTag(),
|
||||
),
|
||||
|
||||
@@ -222,7 +222,7 @@ class _MLDebugSectionWidgetState extends State<MLDebugSectionWidget> {
|
||||
trailingIconIsMuted: true,
|
||||
onTap: () async {
|
||||
try {
|
||||
await MagicCacheService.instance.updateCache();
|
||||
await MagicCacheService.instance.updateCache(forced: true);
|
||||
} catch (e, s) {
|
||||
logger.warning('Update discover failed', e, s);
|
||||
await showGenericErrorDialog(context: context, error: e);
|
||||
|
||||
@@ -21,6 +21,7 @@ class MagicResultScreen extends StatefulWidget {
|
||||
final String name;
|
||||
final String heroTag;
|
||||
final bool enableGrouping;
|
||||
final Map<int, int> fileIdToPosMap;
|
||||
|
||||
static const GalleryType appBarType = GalleryType.magic;
|
||||
static const GalleryType overlayType = GalleryType.magic;
|
||||
@@ -29,6 +30,7 @@ class MagicResultScreen extends StatefulWidget {
|
||||
this.files, {
|
||||
required this.name,
|
||||
this.enableGrouping = false,
|
||||
this.fileIdToPosMap = const {},
|
||||
this.heroTag = "",
|
||||
super.key,
|
||||
});
|
||||
@@ -65,10 +67,20 @@ class _MagicResultScreenState extends State<MagicResultScreen> {
|
||||
_magicSortChangeEvent =
|
||||
Bus.instance.on<MagicSortChangeEvent>().listen((event) {
|
||||
if (event.sortType == MagicSortType.mostRelevant) {
|
||||
if (_enableGrouping) {
|
||||
files.sort(
|
||||
(a, b) =>
|
||||
widget.fileIdToPosMap[a.uploadedFileID]! -
|
||||
widget.fileIdToPosMap[b.uploadedFileID]!,
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
_enableGrouping = false;
|
||||
});
|
||||
} else if (event.sortType == MagicSortType.mostRecent) {
|
||||
if (!_enableGrouping) {
|
||||
files.sort((a, b) => b.creationTime!.compareTo(a.creationTime!));
|
||||
}
|
||||
setState(() {
|
||||
_enableGrouping = true;
|
||||
});
|
||||
|
||||
@@ -170,12 +170,13 @@ class _SearchSectionAllPageState extends State<SearchSectionAllPage> {
|
||||
MagicResultScreen(
|
||||
magicSectionResult.resultFiles(),
|
||||
name: magicSectionResult.name(),
|
||||
enableGrouping: magicSectionResult
|
||||
.params["enableGrouping"]! as bool,
|
||||
fileIdToPosMap: magicSectionResult
|
||||
.params["fileIdToPosMap"]
|
||||
as Map<int, int>,
|
||||
heroTag: "searchable_item" +
|
||||
GenericSearchResult(
|
||||
ResultType.magic,
|
||||
magicSectionResult.name(),
|
||||
magicSectionResult.resultFiles(),
|
||||
).heroTag(),
|
||||
magicSectionResult.heroTag(),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -12,7 +12,7 @@ description: ente photos application
|
||||
# Read more about iOS versioning at
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
|
||||
version: 0.9.39+939
|
||||
version: 0.9.40+940
|
||||
publish_to: none
|
||||
|
||||
environment:
|
||||
|
||||
Reference in New Issue
Block a user