Simplify new files notification + avoid redundant compute

This commit is contained in:
Neeraj Gupta
2025-07-07 15:57:47 +05:30
parent 5fec59f0fe
commit e4f9dd6b33
3 changed files with 44 additions and 35 deletions

View File

@@ -597,22 +597,6 @@ class FilesDB with SqlDbBase {
return files;
}
Future<List<EnteFile>> getNewFilesInCollection(
int collectionID,
int addedTime,
) async {
final db = await instance.sqliteAsyncDB;
const String whereClause =
'$columnCollectionID = ? AND $columnAddedTime > ?';
final List<Object> whereArgs = [collectionID, addedTime];
final results = await db.getAll(
'SELECT * FROM $filesTable WHERE $whereClause',
whereArgs,
);
final files = convertToFiles(results);
return files;
}
// Files which user added to a collection manually but they are not
// uploaded yet or files belonging to a collection which is marked for backup
Future<List<EnteFile>> getFilesPendingForUpload() async {

View File

@@ -1,4 +1,5 @@
import "package:photos/db/remote/db.dart";
import "package:photos/models/api/diff/diff.dart";
extension FilesTable on RemoteDB {
// For a given userID, return unique uploadedFileId for the given userID
@@ -39,4 +40,24 @@ extension FilesTable on RemoteDB {
parameterSets,
);
}
Future<Map<int, List<(int, Metadata?)>>> getNotificationCandidate(
List<int> collectionIDs,
int lastAppOpen,
) async {
if (collectionIDs.isEmpty) return {};
final placeholders = List.filled(collectionIDs.length, '?').join(',');
final rows = await sqliteDB.getAll(
"SELECT collection_id, files.owner_id, metadata FROM collection_files join files ON collection_files.file_id = files.id WHERE collection_id IN ($placeholders) AND collection_files.created_at > ?",
[...collectionIDs, lastAppOpen],
);
final result = <int, List<(int, Metadata?)>>{};
for (final row in rows) {
final collectionID = row['collection_id'] as int;
final ownerID = row['owner_id'] as int;
final metadata = Metadata.fromEncodedJson(row['metadata']);
result.putIfAbsent(collectionID, () => []).add((ownerID, metadata));
}
return result;
}
}

View File

@@ -11,6 +11,7 @@ import "package:photos/core/network/network.dart";
import 'package:photos/db/files_db.dart';
import "package:photos/db/local/table/path_config_table.dart";
import "package:photos/db/local/table/upload_queue_table.dart";
import "package:photos/db/remote/table/files_table.dart";
import "package:photos/db/remote/table/mapping_table.dart";
import 'package:photos/events/backup_folders_updated_event.dart';
import 'package:photos/events/collection_updated_event.dart';
@@ -22,6 +23,7 @@ import "package:photos/models/file/extensions/file_props.dart";
import 'package:photos/models/file/file.dart';
import 'package:photos/models/file/file_type.dart';
import "package:photos/models/local/path_config.dart";
import "package:photos/models/metadata/file_magic.dart";
import 'package:photos/models/upload_strategy.dart';
import "package:photos/service_locator.dart";
import 'package:photos/services/app_lifecycle_service.dart';
@@ -590,45 +592,47 @@ class RemoteSyncService {
});
}
bool _shouldShowNotification(int collectionID) {
// TODO: Add option to opt out of notifications for a specific collection
// Screen: https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?type=design&node-id=7689-52943&t=IyWOfh0Gsb0p7yVC-4
bool _shouldShowNotification() {
final isForeground = AppLifecycleService.instance.isForeground;
final bool showNotification =
NotificationService.instance.shouldShowNotificationsForSharedPhotos() &&
isFirstRemoteSyncDone() &&
!isForeground;
_logger.info(
"[Collection-$collectionID] shouldShow notification: $showNotification, "
"isAppInForeground: $isForeground",
" notification: $showNotification isAppInForeground: $isForeground",
);
return showNotification;
}
Future<void> _notifyNewFiles(List<int> collectionIDs) async {
if (!_shouldShowNotification()) {
return;
}
final userID = Configuration.instance.getUserID();
final appOpenTime = AppLifecycleService.instance.getLastAppOpenTime();
final data = await remoteDB.getNotificationCandidate(
collectionIDs,
appOpenTime,
);
for (final collectionID in collectionIDs) {
if (!_shouldShowNotification(collectionID)) {
continue;
}
final files =
await _db.getNewFilesInCollection(collectionID, appOpenTime);
final Set<int> sharedFilesIDs = {};
final Set<int> collectedFilesIDs = {};
for (final file in files) {
if (file.isUploaded && file.ownerID != userID) {
sharedFilesIDs.add(file.uploadedFileID!);
} else if (file.isUploaded && file.isCollect) {
collectedFilesIDs.add(file.uploadedFileID!);
// TODO: Add option to opt out of notifications for a specific collection
// Screen: https://www.figma.com/file/SYtMyLBs5SAOkTbfMMzhqt/ente-Visual-Design?type=design&node-id=7689-52943&t=IyWOfh0Gsb0p7yVC-4
final ownerAndMetadataList = data[collectionID] ?? [];
int sharedFileCount = 0;
int collectedFileCount = 0;
for (final (ownerID, metadata) in ownerAndMetadataList) {
if (ownerID != userID) {
sharedFileCount = sharedFileCount + 1;
} else if (metadata?.data.containsKey(uploaderNameKey) ?? false) {
collectedFileCount = collectedFileCount + 1;
}
}
final totalCount = sharedFilesIDs.length + collectedFilesIDs.length;
final totalCount = sharedFileCount + collectedFileCount;
if (totalCount > 0) {
final collection = _collectionsService.getCollectionByID(collectionID);
_logger.info(
'creating notification for ${collection?.displayName} '
'shared: $sharedFilesIDs, collected: $collectedFilesIDs files',
'shared: $sharedFileCount, collected: $collectedFileCount files',
);
final s = await LanguageService.s;
// ignore: unawaited_futures