From 2eaaa270c3b738080d1bfcf15dd93eab07b82bdd Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Jul 2026 22:51:57 +0000 Subject: [PATCH] refactor(desktop): read blossom servers from the account, not the cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the ICacheProvider.blossomServers(pubKey) cache helper with reads straight from the account's own state holder — iAccount.blossomServerList.flow (the shared BlossomServerListState) — threaded to each upload site. This is the reactive, per-account source of truth and drops the cache+pubkey indirection entirely. - Hoist iAccount (with dmSendTracker + accountRelays) out of MainContent into the LoggedIn branch so the top-level compose dialog can read the account's blossom flow too; pass them into MainContent as params. - Thread iAccount.blossomServerList.flow into ComposeNoteDialog (reactive: the server picker updates if the list loads after the dialog opens), EditProfileDialog (via UserProfileScreen), and ChatPane (via DesktopMessagesScreen). - Reduce BlossomServers.kt to just the DEFAULT_BLOSSOM_SERVER fallback used when the account has published no kind-10063 list yet. Known gap: quote-compose opened from a feed row (NoteActionsRow) still defaults to DEFAULT_BLOSSOM_SERVER — the per-note card composables don't carry the account handle, and threading it through the whole note-render tree isn't worth it for that secondary path. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_011dkzkEY6cUsRfqEb7giHi2 --- .../vitorpamplona/amethyst/desktop/Main.kt | 51 ++++++++++--------- .../amethyst/desktop/model/BlossomServers.kt | 23 ++------- .../amethyst/desktop/ui/ComposeNoteDialog.kt | 22 ++++---- .../amethyst/desktop/ui/FeedScreen.kt | 1 + .../amethyst/desktop/ui/NoteActions.kt | 2 + .../amethyst/desktop/ui/UserProfileScreen.kt | 3 +- .../amethyst/desktop/ui/chats/ChatPane.kt | 8 ++- .../desktop/ui/chats/DesktopMessagesScreen.kt | 2 + .../desktop/ui/deck/DeckColumnContainer.kt | 3 ++ .../desktop/ui/profile/EditProfileScreen.kt | 8 +-- .../cache/DesktopBlossomServerListTest.kt | 21 -------- 11 files changed, 64 insertions(+), 80 deletions(-) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt index 35692db5fe..b31735110f 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt @@ -1341,6 +1341,25 @@ private fun AppInner( val account = accountState as AccountState.LoggedIn val nwcConnection by accountManager.nwcConnection.collectAsState() + // Account state holders (relay lists, blossom servers, DMs, WoT). + // Hoisted above MainContent so the top-level compose dialog can also + // read the account's blossom server list from iAccount directly. + val dmSendTracker = remember(relayManager) { DmSendTracker(relayManager.client) } + // Created before iAccount so NIP-65 backup can be loaded. + val accountRelays = + remember(account, relayManager, scope) { + DesktopAccountRelays(account.pubKeyHex, relayManager, scope) + } + val iAccount = + remember(account, localCache, relayManager, dmSendTracker, accountRelays, dmInboxResolver) { + DesktopIAccount(account, localCache, relayManager, dmSendTracker, scope, accountRelays, dmInboxResolver) + } + // When iAccount is replaced (account switch), close the previous + // WoTService so its writer coroutine + ops Channel don't leak. + DisposableEffect(iAccount) { + onDispose { iAccount.wotService.close() } + } + // Lazy-load Namecoin services. The Core RPC HTTP // client is sourced from the Tor-aware DesktopHttpClient // singleton so .onion RPC URLs route through the @@ -1414,6 +1433,9 @@ private fun AppInner( localCache = localCache, accountManager = accountManager, account = account, + iAccount = iAccount, + accountRelays = accountRelays, + dmSendTracker = dmSendTracker, nwcConnection = nwcConnection, subscriptionsCoordinator = subscriptionsCoordinator, indexRelaysStore = indexRelaysStore, @@ -1456,6 +1478,7 @@ private fun AppInner( relayManager = relayManager, account = account, localCache = localCache, + blossomServers = iAccount.blossomServerList.flow, replyTo = replyToNote, draftDTag = composeEditDraftTag, draftInitialContent = composeEditContent, @@ -1544,6 +1567,9 @@ fun MainContent( localCache: DesktopLocalCache, accountManager: AccountManager, account: AccountState.LoggedIn, + iAccount: DesktopIAccount, + accountRelays: DesktopAccountRelays, + dmSendTracker: DmSendTracker, nwcConnection: Nip47WalletConnect.Nip47URINorm?, subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator, indexRelaysStore: com.vitorpamplona.amethyst.commons.relays.index.PreferencesIndexRelays, @@ -1563,31 +1589,6 @@ fun MainContent( val signerConnectionState by accountManager.signerConnectionState.collectAsState() val lastPingTimeSec by accountManager.lastPingTimeSec.collectAsState() - // DM infrastructure — hoisted here so it survives screen navigation - val dmSendTracker = - remember(relayManager) { - DmSendTracker(relayManager.client) - } - // Centralized relay state for all categories (DM, search, blocked, NIP-65 persistence) - // Created before iAccount so NIP-65 backup can be loaded - val accountRelays = - remember(account, relayManager, scope) { - DesktopAccountRelays(account.pubKeyHex, relayManager, scope) - } - - val iAccount = - remember(account, localCache, relayManager, dmSendTracker, accountRelays, dmInboxResolver) { - DesktopIAccount(account, localCache, relayManager, dmSendTracker, scope, accountRelays, dmInboxResolver) - } - - // When iAccount is replaced (account switch), the previous WoTService's - // internal writer coroutine + ops Channel would otherwise leak — the - // outer `scope` lives for the whole session. Close the previous - // instance on dispose so account-switch is a clean teardown. - DisposableEffect(iAccount) { - onDispose { iAccount.wotService.close() } - } - // Follow Packs state — single per-account holder for Discover + sidebar + naddr cards val followPacksState = remember(iAccount, localCache, relayManager, scope) { diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/BlossomServers.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/BlossomServers.kt index 348ef66cff..d3a319be66 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/BlossomServers.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/model/BlossomServers.kt @@ -20,23 +20,10 @@ */ package com.vitorpamplona.amethyst.desktop.model -import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent - -/** Fallback media server used when the account has published no kind-10063 list yet. */ -const val DEFAULT_BLOSSOM_SERVER = "https://blossom.primal.net" - /** - * The account's Blossom media servers (NIP-B7 / kind 10063), read straight from - * the cache. This is the per-account source of truth — the same event the - * account-config subscription loads and the mobile app uses — so upload sites - * read it here instead of a process-global preference. + * Fallback media server used when the account has published no kind-10063 + * Blossom server list yet. The list itself is read reactively from the account's + * [com.vitorpamplona.amethyst.commons.model.nipB7Blossom.BlossomServerListState] + * (`iAccount.blossomServerList.flow`); this is only the empty-list default. */ -fun ICacheProvider.blossomServers(pubKeyHex: HexKey): List = - (getOrCreateAddressableNote(BlossomServersEvent.createAddress(pubKeyHex)).event as? BlossomServersEvent) - ?.servers() - .orEmpty() - -/** First declared Blossom server for [pubKeyHex], or [DEFAULT_BLOSSOM_SERVER] when none is set. */ -fun ICacheProvider.preferredBlossomServer(pubKeyHex: HexKey): String = blossomServers(pubKeyHex).firstOrNull() ?: DEFAULT_BLOSSOM_SERVER +const val DEFAULT_BLOSSOM_SERVER = "https://blossom.primal.net" diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt index 4c38c8f4fe..189437556e 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/ComposeNoteDialog.kt @@ -78,7 +78,6 @@ import com.vitorpamplona.amethyst.desktop.ImageCompressionStore import com.vitorpamplona.amethyst.desktop.account.AccountState import com.vitorpamplona.amethyst.desktop.model.DEFAULT_BLOSSOM_SERVER import com.vitorpamplona.amethyst.desktop.model.DesktopIAccount -import com.vitorpamplona.amethyst.desktop.model.blossomServers import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.service.drafts.LocalNoteDraftStore import com.vitorpamplona.amethyst.desktop.service.drafts.NoteDraft @@ -119,6 +118,7 @@ import com.vitorpamplona.quartz.nip89AppHandlers.clientTag.isClient import com.vitorpamplona.quartz.nip92IMeta.IMetaTag import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.awt.datatransfer.DataFlavor @@ -140,6 +140,7 @@ fun ComposeNoteDialog( relayManager: DesktopRelayConnectionManager, account: AccountState.LoggedIn, localCache: com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache? = null, + blossomServers: StateFlow>? = null, replyTo: Event? = null, quoteOf: Event? = null, draftDTag: String? = null, @@ -206,13 +207,16 @@ fun ComposeNoteDialog( val uploadTracker = remember { DesktopUploadTracker() } val uploadState by uploadTracker.state.collectAsState() val orchestrator = remember { UploadOrchestrator() } - // Media servers come from the account's kind-10063 list (per-account, loaded - // by the account-config subscription), not a process-global preference. - val blossomServers = - remember(localCache, account) { - localCache?.blossomServers(account.pubKeyHex).orEmpty().ifEmpty { listOf(DEFAULT_BLOSSOM_SERVER) } - } - var selectedServer by remember { mutableStateOf(blossomServers.first()) } + // Media servers come straight from the account's kind-10063 list holder + // (account.blossomServerList.flow), reactively — no cache-poking, no prefs. + val serverList by (blossomServers?.collectAsState() ?: remember { mutableStateOf(emptyList()) }) + val effectiveServers = serverList.ifEmpty { listOf(DEFAULT_BLOSSOM_SERVER) } + var selectedServer by remember { mutableStateOf(effectiveServers.first()) } + // If the list loads (or changes) after the dialog opens and the current pick + // is no longer in it, snap to the first available server. + LaunchedEffect(effectiveServers) { + if (selectedServer !in effectiveServers) selectedServer = effectiveServers.first() + } var postAsPicture by remember { mutableStateOf(false) } // Scheduling — when non-null the note is stored for later publication instead of @@ -583,7 +587,7 @@ fun ComposeNoteDialog( verticalAlignment = androidx.compose.ui.Alignment.CenterVertically, ) { ServerSelector( - servers = blossomServers, + servers = effectiveServers, selectedServer = selectedServer, onServerSelected = { selectedServer = it }, ) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/FeedScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/FeedScreen.kt index 1eace52ec5..096bf03a59 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/FeedScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/FeedScreen.kt @@ -1043,6 +1043,7 @@ fun FeedScreen( relayManager = relayManager, account = account, localCache = localCache, + blossomServers = iAccount?.blossomServerList?.flow, replyTo = replyToEvent, ) } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt index 7a52fb1d08..1c51828dd5 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/NoteActions.kt @@ -1376,6 +1376,8 @@ fun NoteActionsRow( relayManager = relayManager, account = account, localCache = localCache, + // Quote-compose from a feed row falls back to the default media server: + // the per-note card composables don't carry the account's blossom flow. quoteOf = quoteEvent, ) } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/UserProfileScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/UserProfileScreen.kt index 2ccec9a7c9..50274077bb 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/UserProfileScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/UserProfileScreen.kt @@ -122,6 +122,7 @@ fun UserProfileScreen( relayManager: DesktopRelayConnectionManager, localCache: DesktopLocalCache, account: AccountState.LoggedIn?, + blossomServers: kotlinx.coroutines.flow.StateFlow>? = null, nwcConnection: com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect.Nip47URINorm? = null, subscriptionsCoordinator: DesktopRelaySubscriptionsCoordinator? = null, onBack: () -> Unit, @@ -1189,7 +1190,7 @@ fun UserProfileScreen( EditProfileDialog( account = account, relayManager = relayManager, - localCache = localCache, + blossomServers = blossomServers, latestMetadata = latestMetadataEvent, latestIdentities = latestIdentitiesEvent, onDismiss = { showEditProfile = false }, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatPane.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatPane.kt index 08ace28d94..091ef90023 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatPane.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/ChatPane.kt @@ -88,7 +88,7 @@ import com.vitorpamplona.amethyst.commons.ui.components.LoadingState import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState import com.vitorpamplona.amethyst.commons.viewmodels.ChatNewMessageState import com.vitorpamplona.amethyst.commons.viewmodels.ChatroomFeedViewModel -import com.vitorpamplona.amethyst.desktop.model.preferredBlossomServer +import com.vitorpamplona.amethyst.desktop.model.DEFAULT_BLOSSOM_SERVER import com.vitorpamplona.amethyst.desktop.ui.components.ToggleableTimeAgoText import com.vitorpamplona.amethyst.desktop.ui.media.DesktopFilePicker import com.vitorpamplona.amethyst.desktop.ui.media.MediaAttachmentRow @@ -101,6 +101,7 @@ import com.vitorpamplona.quartz.nip17Dm.messages.ChatMessageEvent import com.vitorpamplona.quartz.nip17Dm.messages.changeSubject import com.vitorpamplona.quartz.nip94FileMetadata.tags.DimensionTag import com.vitorpamplona.quartz.utils.ciphers.AESGCM +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import java.awt.datatransfer.DataFlavor import java.awt.dnd.DnDConstants @@ -135,6 +136,7 @@ fun ChatPane( cacheProvider: ICacheProvider, feedViewModel: ChatroomFeedViewModel, messageState: ChatNewMessageState, + blossomServers: StateFlow>? = null, dmBroadcastStatus: DmBroadcastStatus = DmBroadcastStatus.Idle, onNavigateToProfile: (String) -> Unit = {}, onBack: (() -> Unit)? = null, @@ -379,6 +381,7 @@ fun ChatPane( roomKey = roomKey, account = account, cacheProvider = cacheProvider, + blossomServers = blossomServers, ) attachedFiles.clear() } catch (e: Exception) { @@ -880,9 +883,10 @@ private suspend fun sendEncryptedFiles( roomKey: ChatroomKey, account: IAccount, cacheProvider: ICacheProvider, + blossomServers: StateFlow>?, ) { val orchestrator = UploadOrchestrator() - val server = cacheProvider.preferredBlossomServer(account.pubKey) + val server = blossomServers?.value?.firstOrNull() ?: DEFAULT_BLOSSOM_SERVER val recipients = roomKey.users.mapNotNull { cacheProvider.getUserIfExists(it) }.map { it.toPTag() } for (file in files) { diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/DesktopMessagesScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/DesktopMessagesScreen.kt index 8823c6197f..c5cd49e850 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/DesktopMessagesScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/chats/DesktopMessagesScreen.kt @@ -271,6 +271,7 @@ private fun CompactMessagesContent( cacheProvider = cacheProvider, feedViewModel = feedViewModel, messageState = messageState, + blossomServers = (account as? DesktopIAccount)?.blossomServerList?.flow, dmBroadcastStatus = broadcastStatus, onNavigateToProfile = onNavigateToProfile, onBack = { listState.clearSelection() }, @@ -375,6 +376,7 @@ private fun SplitMessagesContent( cacheProvider = cacheProvider, feedViewModel = feedViewModel, messageState = messageState, + blossomServers = (account as? DesktopIAccount)?.blossomServerList?.flow, dmBroadcastStatus = broadcastStatus, onNavigateToProfile = onNavigateToProfile, ) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/deck/DeckColumnContainer.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/deck/DeckColumnContainer.kt index ac1d8b27fd..44f61806af 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/deck/DeckColumnContainer.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/deck/DeckColumnContainer.kt @@ -472,6 +472,7 @@ internal fun RootContent( relayManager = relayManager, localCache = localCache, account = account, + blossomServers = iAccount.blossomServerList.flow, nwcConnection = nwcConnection, subscriptionsCoordinator = subscriptionsCoordinator, onBack = {}, @@ -553,6 +554,7 @@ internal fun RootContent( relayManager = relayManager, localCache = localCache, account = account, + blossomServers = iAccount.blossomServerList.flow, nwcConnection = nwcConnection, subscriptionsCoordinator = subscriptionsCoordinator, onBack = {}, @@ -705,6 +707,7 @@ internal fun OverlayContent( relayManager = relayManager, localCache = localCache, account = account, + blossomServers = iAccount?.blossomServerList?.flow, nwcConnection = nwcConnection, subscriptionsCoordinator = subscriptionsCoordinator, onBack = onBack, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/profile/EditProfileScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/profile/EditProfileScreen.kt index 5aba2eb7f4..affca46175 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/profile/EditProfileScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/profile/EditProfileScreen.kt @@ -80,8 +80,7 @@ import com.vitorpamplona.amethyst.commons.profile.ProfileBroadcastStatus import com.vitorpamplona.amethyst.commons.profile.ui.ProfileBroadcastBanner import com.vitorpamplona.amethyst.commons.service.upload.UploadOrchestrator import com.vitorpamplona.amethyst.desktop.account.AccountState -import com.vitorpamplona.amethyst.desktop.cache.DesktopLocalCache -import com.vitorpamplona.amethyst.desktop.model.preferredBlossomServer +import com.vitorpamplona.amethyst.desktop.model.DEFAULT_BLOSSOM_SERVER import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.ui.media.DesktopFilePicker import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent @@ -93,6 +92,7 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.mapNotNull @@ -125,7 +125,7 @@ sealed class Nip05Status { fun EditProfileDialog( account: AccountState.LoggedIn, relayManager: DesktopRelayConnectionManager, - localCache: DesktopLocalCache, + blossomServers: StateFlow>? = null, latestMetadata: MetadataEvent?, latestIdentities: ExternalIdentitiesEvent?, onDismiss: () -> Unit, @@ -173,7 +173,7 @@ fun EditProfileDialog( } val orchestrator = remember { UploadOrchestrator() } - val serverBaseUrl = localCache.preferredBlossomServer(account.pubKeyHex) + val serverBaseUrl = blossomServers?.value?.firstOrNull() ?: DEFAULT_BLOSSOM_SERVER fun uploadFile( file: File, diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopBlossomServerListTest.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopBlossomServerListTest.kt index fbdb45791d..6cdb574b23 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopBlossomServerListTest.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopBlossomServerListTest.kt @@ -21,8 +21,6 @@ package com.vitorpamplona.amethyst.desktop.cache import com.vitorpamplona.amethyst.commons.model.nipB7Blossom.BlossomServerListState -import com.vitorpamplona.amethyst.desktop.model.DEFAULT_BLOSSOM_SERVER -import com.vitorpamplona.amethyst.desktop.model.preferredBlossomServer import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal @@ -98,23 +96,4 @@ class DesktopBlossomServerListTest { assertEquals(servers, state.getBlossomServersList()?.servers()) assertEquals(servers, state.flow.first { it.isNotEmpty() }) } - - @Test - fun `preferredBlossomServer reads the account's first server from cache`() = - runTest { - val cache = DesktopLocalCache() - val signer = NostrSignerInternal(KeyPair()) - val servers = listOf("https://first.example.com", "https://second.example.com") - cache.consume(signedServerList(servers, signer), relayUrl) - - assertEquals("https://first.example.com", cache.preferredBlossomServer(signer.pubKey)) - } - - @Test - fun `preferredBlossomServer falls back to the default when the account has no list`() { - val cache = DesktopLocalCache() - val signer = NostrSignerInternal(KeyPair()) - - assertEquals(DEFAULT_BLOSSOM_SERVER, cache.preferredBlossomServer(signer.pubKey)) - } }