Reorganize
This commit is contained in:
@@ -76,13 +76,6 @@ class MemoriesCacheService {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _resetLastMemoriesCacheUpdateTime() async {
|
||||
await _prefs.setInt(
|
||||
_lastMemoriesCacheUpdateTimeKey,
|
||||
DateTime.now().microsecondsSinceEpoch,
|
||||
);
|
||||
}
|
||||
|
||||
int get lastMemoriesCacheUpdateTime {
|
||||
return _prefs.getInt(_lastMemoriesCacheUpdateTimeKey) ?? 0;
|
||||
}
|
||||
@@ -96,28 +89,6 @@ class MemoriesCacheService {
|
||||
Bus.instance.fire(MemoriesSettingChanged());
|
||||
}
|
||||
|
||||
Future<void> toggleOnThisDayNotifications() async {
|
||||
final oldValue = localSettings.isOnThisDayNotificationsEnabled;
|
||||
await localSettings.setOnThisDayNotificationsEnabled(!oldValue);
|
||||
_logger.info("Turning onThisDayNotifications ${oldValue ? "off" : "on"}");
|
||||
if (oldValue) {
|
||||
await _clearAllScheduledOnThisDayNotifications();
|
||||
} else {
|
||||
queueUpdateCache();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> toggleBirthdayNotifications() async {
|
||||
final oldValue = localSettings.birthdayNotificationsEnabled;
|
||||
await localSettings.setBirthdayNotificationsEnabled(!oldValue);
|
||||
_logger.info("Turning birhtdayNotifications ${oldValue ? "off" : "on"}");
|
||||
if (oldValue) {
|
||||
await _clearAllScheduledBirthdayNotifications();
|
||||
} else {
|
||||
queueUpdateCache();
|
||||
}
|
||||
}
|
||||
|
||||
bool get enableSmartMemories =>
|
||||
flagService.hasGrantedMLConsent &&
|
||||
localSettings.isMLLocalIndexingEnabled &&
|
||||
@@ -145,11 +116,6 @@ class MemoriesCacheService {
|
||||
.microsecondsSinceEpoch;
|
||||
}
|
||||
|
||||
Future<String> _getCachePath() async {
|
||||
return (await getApplicationSupportDirectory()).path +
|
||||
"/cache/memories_cache";
|
||||
}
|
||||
|
||||
Future markMemoryAsSeen(Memory memory, bool lastInList) async {
|
||||
memory.markSeen();
|
||||
await _memoriesDB.markMemoryAsSeen(
|
||||
@@ -174,11 +140,130 @@ class MemoriesCacheService {
|
||||
unawaited(_prefs.setBool(_shouldUpdateCacheKey, true));
|
||||
}
|
||||
|
||||
Future<void> _cacheUpdated() async {
|
||||
_shouldUpdate = false;
|
||||
unawaited(_prefs.setBool(_shouldUpdateCacheKey, false));
|
||||
await _resetLastMemoriesCacheUpdateTime();
|
||||
Bus.instance.fire(MemoriesChangedEvent());
|
||||
Future<List<SmartMemory>> getMemories() async {
|
||||
if (!showAnyMemories) {
|
||||
_logger.info('Showing memories is disabled in settings, showing none');
|
||||
return [];
|
||||
}
|
||||
if (_cachedMemories != null && _cachedMemories!.isNotEmpty) {
|
||||
return _cachedMemories!;
|
||||
}
|
||||
try {
|
||||
if (!enableSmartMemories) {
|
||||
await _calculateRegularFillers();
|
||||
return _cachedMemories!;
|
||||
}
|
||||
_cachedMemories = await _getMemoriesFromCache();
|
||||
if (_cachedMemories == null || _cachedMemories!.isEmpty) {
|
||||
_logger.warning(
|
||||
"No memories found in cache, force updating cache. Possible severe caching issue",
|
||||
);
|
||||
await updateCache(forced: true);
|
||||
} else {
|
||||
_logger.info("Found memories in cache");
|
||||
}
|
||||
if (_cachedMemories == null || _cachedMemories!.isEmpty) {
|
||||
_logger
|
||||
.severe("No memories found in (computed) cache, getting fillers");
|
||||
await _calculateRegularFillers();
|
||||
}
|
||||
return _cachedMemories!;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error in getMemories", e, s);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _calculateRegularFillers() async {
|
||||
if (_cachedMemories == null) {
|
||||
_cachedMemories = await smartMemoriesService.calcSimpleMemories();
|
||||
Bus.instance.fire(MemoriesChangedEvent());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>?> _getMemoriesFromCache() async {
|
||||
final cache = await _readCacheFromDisk();
|
||||
if (cache == null) {
|
||||
return null;
|
||||
}
|
||||
final result = await _fromCacheToMemories(cache);
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<MemoriesCache?> _readCacheFromDisk() async {
|
||||
_logger.info("Reading memories cache result from disk");
|
||||
final file = File(await _getCachePath());
|
||||
if (!file.existsSync()) {
|
||||
_logger.info("No memories cache found");
|
||||
return null;
|
||||
}
|
||||
final allFiles = Set<EnteFile>.from(
|
||||
await SearchService.instance.getAllFilesForSearch(),
|
||||
);
|
||||
final allFileIdsToFile = <int, EnteFile>{};
|
||||
for (final file in allFiles) {
|
||||
if (file.uploadedFileID != null) {
|
||||
allFileIdsToFile[file.uploadedFileID!] = file;
|
||||
}
|
||||
}
|
||||
try {
|
||||
final bytes = await file.readAsBytes();
|
||||
final jsonString = String.fromCharCodes(bytes);
|
||||
final cache =
|
||||
MemoriesCache.decodeFromJsonString(jsonString, allFileIdsToFile);
|
||||
_logger.info("Reading memories cache result from disk done");
|
||||
return cache;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error reading or decoding cache file", e, s);
|
||||
await file.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>> _fromCacheToMemories(MemoriesCache cache) async {
|
||||
try {
|
||||
_logger.info('Processing disk cache memories to smart memories');
|
||||
final List<SmartMemory> memories = [];
|
||||
final allFiles = Set<EnteFile>.from(
|
||||
await SearchService.instance.getAllFilesForSearch(),
|
||||
);
|
||||
final allFileIdsToFile = <int, EnteFile>{};
|
||||
for (final file in allFiles) {
|
||||
if (file.uploadedFileID != null) {
|
||||
allFileIdsToFile[file.uploadedFileID!] = file;
|
||||
}
|
||||
}
|
||||
final seenTimes = await _memoriesDB.getSeenTimes();
|
||||
|
||||
for (final ToShowMemory memory in cache.toShowMemories) {
|
||||
if (memory.shouldShowNow()) {
|
||||
final smartMemory = SmartMemory(
|
||||
memory.fileUploadedIDs
|
||||
.where((fileID) => allFileIdsToFile.containsKey(fileID))
|
||||
.map(
|
||||
(fileID) =>
|
||||
Memory.fromFile(allFileIdsToFile[fileID]!, seenTimes),
|
||||
)
|
||||
.toList(),
|
||||
memory.type,
|
||||
memory.title,
|
||||
memory.firstTimeToShow,
|
||||
memory.lastTimeToShow,
|
||||
id: memory.id,
|
||||
);
|
||||
if (smartMemory.memories.isNotEmpty) {
|
||||
memories.add(smartMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
locationService.baseLocations = cache.baseLocations;
|
||||
_logger.info('Processing of disk cache memories done');
|
||||
return memories;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error converting cache to memories", e, s);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateCache({bool forced = false}) async {
|
||||
@@ -260,6 +345,21 @@ class MemoriesCacheService {
|
||||
});
|
||||
}
|
||||
|
||||
Future<String> _getCachePath() async {
|
||||
return (await getApplicationSupportDirectory()).path +
|
||||
"/cache/memories_cache";
|
||||
}
|
||||
|
||||
Future<void> _cacheUpdated() async {
|
||||
_shouldUpdate = false;
|
||||
unawaited(_prefs.setBool(_shouldUpdateCacheKey, false));
|
||||
await _prefs.setInt(
|
||||
_lastMemoriesCacheUpdateTimeKey,
|
||||
DateTime.now().microsecondsSinceEpoch,
|
||||
);
|
||||
Bus.instance.fire(MemoriesChangedEvent());
|
||||
}
|
||||
|
||||
/// WARNING: Use for testing only, TODO: lau: remove later
|
||||
Future<MemoriesCache> debugCacheForTesting() async {
|
||||
final oldCache = await _readCacheFromDisk();
|
||||
@@ -267,16 +367,185 @@ class MemoriesCacheService {
|
||||
return newCache;
|
||||
}
|
||||
|
||||
Future<void> _clearAllScheduledOnThisDayNotifications() async {
|
||||
_logger.info('Clearing all scheduled On This Day notifications');
|
||||
await NotificationService.instance
|
||||
.clearAllScheduledNotifications(containingPayload: "onThisDay");
|
||||
MemoriesCache _processOldCache(MemoriesCache? oldCache) {
|
||||
final List<PeopleShownLog> peopleShownLogs = [];
|
||||
final List<ClipShownLog> clipShownLogs = [];
|
||||
final List<TripsShownLog> tripsShownLogs = [];
|
||||
if (oldCache != null) {
|
||||
final now = DateTime.now();
|
||||
for (final peopleLog in oldCache.peopleShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(peopleLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
peopleShownLogs.add(peopleLog);
|
||||
}
|
||||
}
|
||||
for (final tripsLog in oldCache.tripsShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(tripsLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
tripsShownLogs.add(tripsLog);
|
||||
}
|
||||
}
|
||||
for (final clipLog in oldCache.clipShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(clipLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
clipShownLogs.add(clipLog);
|
||||
}
|
||||
}
|
||||
for (final oldMemory in oldCache.toShowMemories) {
|
||||
if (oldMemory.isOld) {
|
||||
if (oldMemory.type == MemoryType.people) {
|
||||
peopleShownLogs.add(PeopleShownLog.fromOldCacheMemory(oldMemory));
|
||||
} else if (oldMemory.type == MemoryType.clip) {
|
||||
clipShownLogs.add(ClipShownLog.fromOldCacheMemory(oldMemory));
|
||||
} else if (oldMemory.type == MemoryType.trips) {
|
||||
tripsShownLogs.add(TripsShownLog.fromOldCacheMemory(oldMemory));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return MemoriesCache(
|
||||
toShowMemories: [],
|
||||
peopleShownLogs: peopleShownLogs,
|
||||
clipShownLogs: clipShownLogs,
|
||||
tripsShownLogs: tripsShownLogs,
|
||||
baseLocations: [],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _clearAllScheduledBirthdayNotifications() async {
|
||||
_logger.info('Clearing all scheduled birthday notifications');
|
||||
await NotificationService.instance
|
||||
.clearAllScheduledNotifications(containingPayload: "birthday");
|
||||
Future<void> clearMemoriesCache({bool fromDisk = true}) async {
|
||||
if (fromDisk) {
|
||||
final file = File(await _getCachePath());
|
||||
if (file.existsSync()) {
|
||||
await file.delete();
|
||||
}
|
||||
}
|
||||
_cachedMemories = null;
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>> getMemoriesForWidget({
|
||||
required bool onThisDay,
|
||||
required bool pastYears,
|
||||
required bool smart,
|
||||
}) async {
|
||||
if (!onThisDay && !pastYears && !smart) {
|
||||
_logger.info(
|
||||
'No memories requested, returning empty list',
|
||||
);
|
||||
return [];
|
||||
}
|
||||
final allMemories = await getMemories();
|
||||
if (onThisDay && pastYears && smart) {
|
||||
return allMemories;
|
||||
}
|
||||
final filteredMemories = <SmartMemory>[];
|
||||
for (final memory in allMemories) {
|
||||
if (!memory.shouldShowNow()) continue;
|
||||
if (memory.type == MemoryType.onThisDay) {
|
||||
if (!onThisDay) continue;
|
||||
} else if (memory.type == MemoryType.filler) {
|
||||
if (!pastYears) continue;
|
||||
} else {
|
||||
if (!smart) continue;
|
||||
}
|
||||
filteredMemories.add(memory);
|
||||
}
|
||||
return filteredMemories;
|
||||
}
|
||||
|
||||
Future<void> goToMemoryFromGeneratedFileID(
|
||||
BuildContext context,
|
||||
int generatedFileID,
|
||||
) async {
|
||||
final allMemories = await getMemories();
|
||||
if (allMemories.isEmpty) return;
|
||||
int memoryIdx = 0;
|
||||
int fileIdx = 0;
|
||||
bool found = false;
|
||||
memoryLoop:
|
||||
for (final memory in _cachedMemories!) {
|
||||
for (final mem in memory.memories) {
|
||||
if (mem.file.generatedID == generatedFileID) {
|
||||
found = true;
|
||||
break memoryLoop;
|
||||
}
|
||||
fileIdx++;
|
||||
}
|
||||
memoryIdx++;
|
||||
fileIdx = 0;
|
||||
}
|
||||
if (!found) {
|
||||
_logger.warning(
|
||||
"Could not find memory with generatedFileID: $generatedFileID",
|
||||
);
|
||||
return;
|
||||
}
|
||||
await routeToPage(
|
||||
context,
|
||||
FullScreenMemoryDataUpdater(
|
||||
initialIndex: fileIdx,
|
||||
memories: allMemories[memoryIdx].memories,
|
||||
child: FullScreenMemory(allMemories[memoryIdx].title, fileIdx),
|
||||
),
|
||||
forceCustomPageRoute: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> goToOnThisDayMemory(BuildContext context) async {
|
||||
final allMemories = await getMemories();
|
||||
if (allMemories.isEmpty) return;
|
||||
int memoryIdx = 0;
|
||||
bool found = false;
|
||||
memoryLoop:
|
||||
for (final memory in allMemories) {
|
||||
if (memory.type == MemoryType.onThisDay) {
|
||||
found = true;
|
||||
break memoryLoop;
|
||||
}
|
||||
memoryIdx++;
|
||||
}
|
||||
if (!found) {
|
||||
_logger.warning(
|
||||
"Could not find onThisDay memory",
|
||||
);
|
||||
return;
|
||||
}
|
||||
await routeToPage(
|
||||
context,
|
||||
FullScreenMemoryDataUpdater(
|
||||
initialIndex: 0,
|
||||
memories: allMemories[memoryIdx].memories,
|
||||
child: FullScreenMemory(allMemories[memoryIdx].title, 0),
|
||||
),
|
||||
forceCustomPageRoute: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> toggleOnThisDayNotifications() async {
|
||||
final oldValue = localSettings.isOnThisDayNotificationsEnabled;
|
||||
await localSettings.setOnThisDayNotificationsEnabled(!oldValue);
|
||||
_logger.info("Turning onThisDayNotifications ${oldValue ? "off" : "on"}");
|
||||
if (oldValue) {
|
||||
await _clearAllScheduledOnThisDayNotifications();
|
||||
} else {
|
||||
queueUpdateCache();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> toggleBirthdayNotifications() async {
|
||||
final oldValue = localSettings.birthdayNotificationsEnabled;
|
||||
await localSettings.setBirthdayNotificationsEnabled(!oldValue);
|
||||
_logger.info("Turning birhtdayNotifications ${oldValue ? "off" : "on"}");
|
||||
if (oldValue) {
|
||||
await _clearAllScheduledBirthdayNotifications();
|
||||
} else {
|
||||
queueUpdateCache();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _scheduleMemoryNotifications(
|
||||
@@ -414,292 +683,15 @@ class MemoriesCacheService {
|
||||
}
|
||||
}
|
||||
|
||||
MemoriesCache _processOldCache(MemoriesCache? oldCache) {
|
||||
final List<PeopleShownLog> peopleShownLogs = [];
|
||||
final List<ClipShownLog> clipShownLogs = [];
|
||||
final List<TripsShownLog> tripsShownLogs = [];
|
||||
if (oldCache != null) {
|
||||
final now = DateTime.now();
|
||||
for (final peopleLog in oldCache.peopleShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(peopleLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
peopleShownLogs.add(peopleLog);
|
||||
}
|
||||
}
|
||||
for (final tripsLog in oldCache.tripsShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(tripsLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
tripsShownLogs.add(tripsLog);
|
||||
}
|
||||
}
|
||||
for (final clipLog in oldCache.clipShownLogs) {
|
||||
if (now.difference(
|
||||
DateTime.fromMicrosecondsSinceEpoch(clipLog.lastTimeShown),
|
||||
) <
|
||||
maxShowTimeout) {
|
||||
clipShownLogs.add(clipLog);
|
||||
}
|
||||
}
|
||||
for (final oldMemory in oldCache.toShowMemories) {
|
||||
if (oldMemory.isOld) {
|
||||
if (oldMemory.type == MemoryType.people) {
|
||||
peopleShownLogs.add(PeopleShownLog.fromOldCacheMemory(oldMemory));
|
||||
} else if (oldMemory.type == MemoryType.clip) {
|
||||
clipShownLogs.add(ClipShownLog.fromOldCacheMemory(oldMemory));
|
||||
} else if (oldMemory.type == MemoryType.trips) {
|
||||
tripsShownLogs.add(TripsShownLog.fromOldCacheMemory(oldMemory));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return MemoriesCache(
|
||||
toShowMemories: [],
|
||||
peopleShownLogs: peopleShownLogs,
|
||||
clipShownLogs: clipShownLogs,
|
||||
tripsShownLogs: tripsShownLogs,
|
||||
baseLocations: [],
|
||||
);
|
||||
Future<void> _clearAllScheduledOnThisDayNotifications() async {
|
||||
_logger.info('Clearing all scheduled On This Day notifications');
|
||||
await NotificationService.instance
|
||||
.clearAllScheduledNotifications(containingPayload: "onThisDay");
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>> _fromCacheToMemories(MemoriesCache cache) async {
|
||||
try {
|
||||
_logger.info('Processing disk cache memories to smart memories');
|
||||
final List<SmartMemory> memories = [];
|
||||
final allFiles = Set<EnteFile>.from(
|
||||
await SearchService.instance.getAllFilesForSearch(),
|
||||
);
|
||||
final allFileIdsToFile = <int, EnteFile>{};
|
||||
for (final file in allFiles) {
|
||||
if (file.uploadedFileID != null) {
|
||||
allFileIdsToFile[file.uploadedFileID!] = file;
|
||||
}
|
||||
}
|
||||
final seenTimes = await _memoriesDB.getSeenTimes();
|
||||
|
||||
for (final ToShowMemory memory in cache.toShowMemories) {
|
||||
if (memory.shouldShowNow()) {
|
||||
final smartMemory = SmartMemory(
|
||||
memory.fileUploadedIDs
|
||||
.where((fileID) => allFileIdsToFile.containsKey(fileID))
|
||||
.map(
|
||||
(fileID) =>
|
||||
Memory.fromFile(allFileIdsToFile[fileID]!, seenTimes),
|
||||
)
|
||||
.toList(),
|
||||
memory.type,
|
||||
memory.title,
|
||||
memory.firstTimeToShow,
|
||||
memory.lastTimeToShow,
|
||||
id: memory.id,
|
||||
);
|
||||
if (smartMemory.memories.isNotEmpty) {
|
||||
memories.add(smartMemory);
|
||||
}
|
||||
}
|
||||
}
|
||||
locationService.baseLocations = cache.baseLocations;
|
||||
_logger.info('Processing of disk cache memories done');
|
||||
return memories;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error converting cache to memories", e, s);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>?> _getMemoriesFromCache() async {
|
||||
final cache = await _readCacheFromDisk();
|
||||
if (cache == null) {
|
||||
return null;
|
||||
}
|
||||
final result = await _fromCacheToMemories(cache);
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<void> _calculateRegularFillers() async {
|
||||
if (_cachedMemories == null) {
|
||||
_cachedMemories = await smartMemoriesService.calcSimpleMemories();
|
||||
Bus.instance.fire(MemoriesChangedEvent());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>> getMemoriesForWidget({
|
||||
required bool onThisDay,
|
||||
required bool pastYears,
|
||||
required bool smart,
|
||||
}) async {
|
||||
if (!onThisDay && !pastYears && !smart) {
|
||||
_logger.info(
|
||||
'No memories requested, returning empty list',
|
||||
);
|
||||
return [];
|
||||
}
|
||||
final allMemories = await getMemories();
|
||||
if (onThisDay && pastYears && smart) {
|
||||
return allMemories;
|
||||
}
|
||||
final filteredMemories = <SmartMemory>[];
|
||||
for (final memory in allMemories) {
|
||||
if (!memory.shouldShowNow()) continue;
|
||||
if (memory.type == MemoryType.onThisDay) {
|
||||
if (!onThisDay) continue;
|
||||
} else if (memory.type == MemoryType.filler) {
|
||||
if (!pastYears) continue;
|
||||
} else {
|
||||
if (!smart) continue;
|
||||
}
|
||||
filteredMemories.add(memory);
|
||||
}
|
||||
return filteredMemories;
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>> getMemories() async {
|
||||
if (!showAnyMemories) {
|
||||
_logger.info('Showing memories is disabled in settings, showing none');
|
||||
return [];
|
||||
}
|
||||
if (_cachedMemories != null && _cachedMemories!.isNotEmpty) {
|
||||
return _cachedMemories!;
|
||||
}
|
||||
try {
|
||||
if (!enableSmartMemories) {
|
||||
await _calculateRegularFillers();
|
||||
return _cachedMemories!;
|
||||
}
|
||||
_cachedMemories = await _getMemoriesFromCache();
|
||||
if (_cachedMemories == null || _cachedMemories!.isEmpty) {
|
||||
_logger.warning(
|
||||
"No memories found in cache, force updating cache. Possible severe caching issue",
|
||||
);
|
||||
await updateCache(forced: true);
|
||||
} else {
|
||||
_logger.info("Found memories in cache");
|
||||
}
|
||||
if (_cachedMemories == null || _cachedMemories!.isEmpty) {
|
||||
_logger
|
||||
.severe("No memories found in (computed) cache, getting fillers");
|
||||
await _calculateRegularFillers();
|
||||
}
|
||||
return _cachedMemories!;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error in getMemories", e, s);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<SmartMemory>?> getCachedMemories() async {
|
||||
return _cachedMemories;
|
||||
}
|
||||
|
||||
Future<void> goToMemoryFromGeneratedFileID(
|
||||
BuildContext context,
|
||||
int generatedFileID,
|
||||
) async {
|
||||
final allMemories = await getMemories();
|
||||
if (allMemories.isEmpty) return;
|
||||
int memoryIdx = 0;
|
||||
int fileIdx = 0;
|
||||
bool found = false;
|
||||
memoryLoop:
|
||||
for (final memory in _cachedMemories!) {
|
||||
for (final mem in memory.memories) {
|
||||
if (mem.file.generatedID == generatedFileID) {
|
||||
found = true;
|
||||
break memoryLoop;
|
||||
}
|
||||
fileIdx++;
|
||||
}
|
||||
memoryIdx++;
|
||||
fileIdx = 0;
|
||||
}
|
||||
if (!found) {
|
||||
_logger.warning(
|
||||
"Could not find memory with generatedFileID: $generatedFileID",
|
||||
);
|
||||
return;
|
||||
}
|
||||
await routeToPage(
|
||||
context,
|
||||
FullScreenMemoryDataUpdater(
|
||||
initialIndex: fileIdx,
|
||||
memories: allMemories[memoryIdx].memories,
|
||||
child: FullScreenMemory(allMemories[memoryIdx].title, fileIdx),
|
||||
),
|
||||
forceCustomPageRoute: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> goToOnThisDayMemory(BuildContext context) async {
|
||||
final allMemories = await getMemories();
|
||||
if (allMemories.isEmpty) return;
|
||||
int memoryIdx = 0;
|
||||
bool found = false;
|
||||
memoryLoop:
|
||||
for (final memory in allMemories) {
|
||||
if (memory.type == MemoryType.onThisDay) {
|
||||
found = true;
|
||||
break memoryLoop;
|
||||
}
|
||||
memoryIdx++;
|
||||
}
|
||||
if (!found) {
|
||||
_logger.warning(
|
||||
"Could not find onThisDay memory",
|
||||
);
|
||||
return;
|
||||
}
|
||||
await routeToPage(
|
||||
context,
|
||||
FullScreenMemoryDataUpdater(
|
||||
initialIndex: 0,
|
||||
memories: allMemories[memoryIdx].memories,
|
||||
child: FullScreenMemory(allMemories[memoryIdx].title, 0),
|
||||
),
|
||||
forceCustomPageRoute: true,
|
||||
);
|
||||
}
|
||||
|
||||
Future<MemoriesCache?> _readCacheFromDisk() async {
|
||||
_logger.info("Reading memories cache result from disk");
|
||||
final file = File(await _getCachePath());
|
||||
if (!file.existsSync()) {
|
||||
_logger.info("No memories cache found");
|
||||
return null;
|
||||
}
|
||||
final allFiles = Set<EnteFile>.from(
|
||||
await SearchService.instance.getAllFilesForSearch(),
|
||||
);
|
||||
final allFileIdsToFile = <int, EnteFile>{};
|
||||
for (final file in allFiles) {
|
||||
if (file.uploadedFileID != null) {
|
||||
allFileIdsToFile[file.uploadedFileID!] = file;
|
||||
}
|
||||
}
|
||||
try {
|
||||
final bytes = await file.readAsBytes();
|
||||
final jsonString = String.fromCharCodes(bytes);
|
||||
final cache =
|
||||
MemoriesCache.decodeFromJsonString(jsonString, allFileIdsToFile);
|
||||
_logger.info("Reading memories cache result from disk done");
|
||||
return cache;
|
||||
} catch (e, s) {
|
||||
_logger.severe("Error reading or decoding cache file", e, s);
|
||||
await file.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> clearMemoriesCache({bool fromDisk = true}) async {
|
||||
if (fromDisk) {
|
||||
final file = File(await _getCachePath());
|
||||
if (file.existsSync()) {
|
||||
await file.delete();
|
||||
}
|
||||
}
|
||||
_cachedMemories = null;
|
||||
Future<void> _clearAllScheduledBirthdayNotifications() async {
|
||||
_logger.info('Clearing all scheduled birthday notifications');
|
||||
await NotificationService.instance
|
||||
.clearAllScheduledNotifications(containingPayload: "birthday");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user