fix: merge old bookmarks into existing new bookmarks during migration

Instead of replacing the new bookmark list, the migration now checks for
an existing kind 10003 event and merges old bookmarks into it, skipping
duplicates that already exist.

https://claude.ai/code/session_01U9sjQHQMVVHxYiesoXjqop
This commit is contained in:
Claude
2026-03-31 02:50:15 +00:00
parent b960a4692a
commit 55a1626159
2 changed files with 32 additions and 9 deletions
@@ -1822,17 +1822,41 @@ class Account(
if (!isWriteable()) return
val oldList = oldBookmarkState.getBookmarkList() ?: return
val publicBookmarks = oldList.publicBookmarks()
val privateBookmarks = oldList.privateBookmarks(signer) ?: emptyList()
val oldPublic = oldList.publicBookmarks()
val oldPrivate = oldList.privateBookmarks(signer) ?: emptyList()
if (publicBookmarks.isEmpty() && privateBookmarks.isEmpty()) return
if (oldPublic.isEmpty() && oldPrivate.isEmpty()) return
val existingNewList = bookmarkState.getBookmarkList()
val newEvent =
BookmarkListEvent.create(
publicBookmarks = publicBookmarks,
privateBookmarks = privateBookmarks,
signer = signer,
)
if (existingNewList != null) {
val existingPublic = existingNewList.publicBookmarks()
val existingPrivate = existingNewList.privateBookmarks(signer) ?: emptyList()
val existingPublicIds = existingPublic.map { it.toTagIdOnly().toList() }.toSet()
val existingPrivateIds = existingPrivate.map { it.toTagIdOnly().toList() }.toSet()
val newPublic = oldPublic.filter { it.toTagIdOnly().toList() !in existingPublicIds }
val newPrivate = oldPrivate.filter { it.toTagIdOnly().toList() !in existingPrivateIds }
if (newPublic.isEmpty() && newPrivate.isEmpty()) return
val mergedPublic = existingPublic + newPublic
val mergedPrivate = existingPrivate + newPrivate
BookmarkListEvent.create(
publicBookmarks = mergedPublic,
privateBookmarks = mergedPrivate,
signer = signer,
)
} else {
BookmarkListEvent.create(
publicBookmarks = oldPublic,
privateBookmarks = oldPrivate,
signer = signer,
)
}
sendMyPublicAndPrivateOutbox(newEvent)
}
@@ -581,7 +581,6 @@ object LocalCache : ILocalCache, ICacheProvider {
return false
}
fun consumeRegularEvent(
event: Event,
relay: NormalizedRelayUrl?,