From 338736148967281adcb0111926d82abd640cbd34 Mon Sep 17 00:00:00 2001 From: Prateek Sunal Date: Wed, 23 Jul 2025 15:40:49 +0530 Subject: [PATCH] fix: use smart-album entityType and remove merge logic + better id --- .../photos/lib/models/api/entity/type.dart | 7 +- .../models/collection/smart_album_config.dart | 32 ------- .../photos/lib/services/entity_service.dart | 6 +- .../lib/services/smart_albums_service.dart | 87 +++++-------------- 4 files changed, 27 insertions(+), 105 deletions(-) diff --git a/mobile/apps/photos/lib/models/api/entity/type.dart b/mobile/apps/photos/lib/models/api/entity/type.dart index 7846724786..c6ef47a5b0 100644 --- a/mobile/apps/photos/lib/models/api/entity/type.dart +++ b/mobile/apps/photos/lib/models/api/entity/type.dart @@ -5,7 +5,7 @@ enum EntityType { person, cgroup, unknown, - smartConfig, + smartAlbum, } EntityType typeFromString(String type) { @@ -28,6 +28,7 @@ extension EntityTypeExtn on EntityType { switch (this) { case EntityType.location: case EntityType.person: + case EntityType.smartAlbum: return false; default: return true; @@ -42,8 +43,8 @@ extension EntityTypeExtn on EntityType { return "person"; case EntityType.cgroup: return "cgroup"; - case EntityType.smartConfig: - return "sconfig"; + case EntityType.smartAlbum: + return "smart_album"; case EntityType.unknown: return "unknown"; } diff --git a/mobile/apps/photos/lib/models/collection/smart_album_config.dart b/mobile/apps/photos/lib/models/collection/smart_album_config.dart index 2a90a31fd2..d5a4f74e88 100644 --- a/mobile/apps/photos/lib/models/collection/smart_album_config.dart +++ b/mobile/apps/photos/lib/models/collection/smart_album_config.dart @@ -69,10 +69,8 @@ class SmartAlbumConfig { // toJson and fromJson methods Map toJson() { return { - "remote_id": id, "collection_id": collectionId, "person_ids": personIDs.toList(), - "updated_at": updatedAt, "info_map": infoMap.map( (key, value) => MapEntry( key, @@ -110,34 +108,4 @@ class SmartAlbumConfig { updatedAt: updatedAt ?? DateTime.now().millisecondsSinceEpoch, ); } - - SmartAlbumConfig merge(SmartAlbumConfig b) { - if (id == b.id) { - if (updatedAt >= b.updatedAt) { - return this; - } - return b; - } - return SmartAlbumConfig( - id: b.updatedAt <= updatedAt ? b.id : id, - collectionId: b.collectionId, - personIDs: personIDs.union(b.personIDs), - infoMap: { - ...infoMap, - ...b.infoMap.map( - (key, value) => MapEntry( - key, - ( - updatedAt: infoMap[key]?.updatedAt != null && - infoMap[key]!.updatedAt > value.updatedAt - ? infoMap[key]!.updatedAt - : value.updatedAt, - addedFiles: infoMap[key]?.addedFiles.union(value.addedFiles) ?? - value.addedFiles, - ), - ), - ), - }, - ); - } } diff --git a/mobile/apps/photos/lib/services/entity_service.dart b/mobile/apps/photos/lib/services/entity_service.dart index d8f72cb22c..d03c82bfeb 100644 --- a/mobile/apps/photos/lib/services/entity_service.dart +++ b/mobile/apps/photos/lib/services/entity_service.dart @@ -60,6 +60,7 @@ class EntityService { EntityType type, Map jsonMap, { String? id, + bool addWithCustomID = false, }) async { final String plainText = jsonEncode(jsonMap); final key = await getOrCreateEntityKey(type); @@ -81,7 +82,7 @@ class EntityService { ); late LocalEntityData localData; - final EntityData data = id == null + final EntityData data = id == null || addWithCustomID ? await _gateway.createEntity(type, encryptedData, header) : await _gateway.updateEntity(type, id, encryptedData, header); localData = LocalEntityData( @@ -106,8 +107,7 @@ class EntityService { try { await _remoteToLocalSync(EntityType.location); await _remoteToLocalSync(EntityType.cgroup); - // TODO: Change to smart config - await _remoteToLocalSync(EntityType.person); + await _remoteToLocalSync(EntityType.smartAlbum); } catch (e) { _logger.severe("Failed to sync entities", e); } diff --git a/mobile/apps/photos/lib/services/smart_albums_service.dart b/mobile/apps/photos/lib/services/smart_albums_service.dart index d8b60b4319..15a880c368 100644 --- a/mobile/apps/photos/lib/services/smart_albums_service.dart +++ b/mobile/apps/photos/lib/services/smart_albums_service.dart @@ -2,6 +2,7 @@ import "dart:async"; import "dart:convert"; import "package:logging/logging.dart"; +import "package:photos/core/configuration.dart"; import "package:photos/models/api/entity/type.dart"; import "package:photos/models/collection/smart_album_config.dart"; import "package:photos/models/local_entity_data.dart"; @@ -18,15 +19,13 @@ class SmartAlbumsService { Future>? _cachedConfigsFuture; - static const type = EntityType.person; - void clearCache() { _cachedConfigsFuture = null; _lastCacheRefreshTime = 0; } int lastRemoteSyncTime() { - return entityService.lastSyncTime(type); + return entityService.lastSyncTime(EntityType.smartAlbum); } Future> getSmartConfigs() async { @@ -42,79 +41,28 @@ class SmartAlbumsService { Future> _fetchAndCacheSConfigs() async { _logger.finest("reading all smart configs from local db"); - final entities = await entityService.getEntities(type); + final entities = await entityService.getEntities(EntityType.smartAlbum); - final result = _decodeSConfigEntities( - {"entity": entities}, - ); + final result = _decodeSConfigEntities({"entity": entities}); - final sconfigs = result["sconfigs"] as Map; - - final collectionToUpdate = result["collectionToUpdate"] as Set; - final idToDelete = result["idToDelete"] as Set; - - // update the merged config to remote db - for (final collectionid in collectionToUpdate) { - try { - await saveConfig(sconfigs[collectionid]!); - } catch (error, stackTrace) { - _logger.severe( - "Failed to update smart album config for collection $collectionid", - error, - stackTrace, - ); - } - } - - // delete all remote ids that are merged into the config - for (final remoteId in idToDelete) { - try { - await _deleteEntry(id: remoteId); - } catch (error, stackTrace) { - _logger.severe( - "Failed to delete smart album config for remote id $remoteId", - error, - stackTrace, - ); - } - } - - return sconfigs; + return result; } - Map _decodeSConfigEntities( + Map _decodeSConfigEntities( Map param, ) { final entities = (param["entity"] as List); final Map sconfigs = {}; - final Set collectionToUpdate = {}; - final Set idToDelete = {}; for (final entity in entities) { try { - var config = SmartAlbumConfig.fromJson( + final config = SmartAlbumConfig.fromJson( json.decode(entity.data), entity.id, entity.updatedAt, ); - if (sconfigs.containsKey(config.collectionId)) { - final existingConfig = sconfigs[config.collectionId]!; - final collectionIdToKeep = config.updatedAt < existingConfig.updatedAt - ? config.collectionId - : existingConfig.collectionId; - final remoteIdToDelete = config.updatedAt < existingConfig.updatedAt - ? existingConfig.id - : config.id; - - config = config.merge(sconfigs[config.collectionId]!); - - // Update the config to be updated and deleted list - collectionToUpdate.add(collectionIdToKeep); - idToDelete.add(remoteIdToDelete!); - } - sconfigs[config.collectionId] = config; } catch (error, stackTrace) { _logger.severe( @@ -125,11 +73,7 @@ class SmartAlbumsService { } } - return { - "sconfigs": sconfigs, - "collectionToUpdate": collectionToUpdate, - "idToDelete": idToDelete, - }; + return sconfigs; } Future syncSmartAlbums() async { @@ -191,10 +135,14 @@ class SmartAlbumsService { } Future saveConfig(SmartAlbumConfig config) async { + final userId = Configuration.instance.getUserID(); + await _addOrUpdateEntity( - type, + EntityType.smartAlbum, config.toJson(), - id: config.id, + collectionId: config.collectionId, + addWithCustomID: config.id == null, + userId: userId, ); } @@ -207,13 +155,18 @@ class SmartAlbumsService { Future _addOrUpdateEntity( EntityType type, Map jsonMap, { - String? id, + required int collectionId, + bool addWithCustomID = false, + int? userId, }) async { + final id = "sa_${userId!}_$collectionId"; final result = await entityService.addOrUpdate( type, jsonMap, id: id, + addWithCustomID: addWithCustomID, ); + _lastCacheRefreshTime = 0; // Invalidate cache return result; }