From 5db1b40552713fcca03b7bec2cde2a2ec29cee4c Mon Sep 17 00:00:00 2001 From: Rune Olsen Date: Tue, 21 Jul 2026 14:06:05 +0200 Subject: [PATCH] Union favorites on tied timestamps instead of dropping one side Two machines that already had favorites before this sync feature shipped will both have an empty favoriteModelsUpdatedAt, so the first sync between them ties. Previously that meant the second machine silently kept only its own set; now tied timestamps merge via union and re-push, so no pre-existing favorites are lost. --- oAI/Services/BackupService.swift | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/oAI/Services/BackupService.swift b/oAI/Services/BackupService.swift index 522a862..e65b89a 100644 --- a/oAI/Services/BackupService.swift +++ b/oAI/Services/BackupService.swift @@ -220,14 +220,23 @@ final class BackupService { } let localUpdatedAt = settings.favoriteModelsUpdatedAt + let localIds = settings.favoriteModelIds if remote.updatedAt > localUpdatedAt { settings.favoriteModelIds = Set(remote.ids) settings.favoriteModelsUpdatedAt = remote.updatedAt log.info("Applied \(remote.ids.count) favorite model(s) from iCloud (remote was newer)") } else if localUpdatedAt > remote.updatedAt { await pushFavorites() + } else if Set(remote.ids) != localIds { + // Tied timestamps (both empty is the common case: two machines that already had + // favorites before this sync feature existed, neither ever bumped the timestamp). + // Union rather than silently dropping one side's favorites. + settings.favoriteModelIds = localIds.union(remote.ids) + settings.favoriteModelsUpdatedAt = ISO8601DateFormatter().string(from: Date()) + await pushFavorites() + log.info("Merged favorites from iCloud (tied timestamps) — union of \(localIds.count) local + \(remote.ids.count) remote") } - // Equal timestamps: already in sync, nothing to do. + // Equal timestamps and identical sets: already in sync, nothing to do. } // MARK: - Automatic Backup