From 7773844d2f127ab71625b23d37c64d75a0a3c95d Mon Sep 17 00:00:00 2001 From: nrobi144 Date: Mon, 16 Mar 2026 12:23:57 +0200 Subject: [PATCH] feat(media): wire encrypted media, server settings, and server preferences - ChatPane: display ChatFileAttachment for encrypted file header events - DesktopPreferences: add blossom server list persistence - Settings: add MediaServerSettings section above relay settings - ComposeNoteDialog: use preferred blossom server from preferences Co-Authored-By: Claude Opus 4.6 --- .../amethyst/desktop/DesktopPreferences.kt | 13 ++++++++++++ .../vitorpamplona/amethyst/desktop/Main.kt | 10 +++++++++ .../amethyst/desktop/ui/ComposeNoteDialog.kt | 5 ++--- .../amethyst/desktop/ui/chats/ChatPane.kt | 21 +++++++++++++------ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/DesktopPreferences.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/DesktopPreferences.kt index 86b7e9d13..f06acf2e7 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/DesktopPreferences.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/DesktopPreferences.kt @@ -68,4 +68,17 @@ object DesktopPreferences { set(value) { prefs.put(KEY_LAYOUT_MODE, value) } + + private const val KEY_BLOSSOM_SERVERS = "blossom_servers" + private const val DEFAULT_BLOSSOM_SERVER = "https://blossom.primal.net" + + var blossomServers: List + get() { + val raw = prefs.get(KEY_BLOSSOM_SERVERS, DEFAULT_BLOSSOM_SERVER) + return if (raw.isBlank()) emptyList() else raw.split(",") + } + set(value) = prefs.put(KEY_BLOSSOM_SERVERS, value.joinToString(",")) + + val preferredBlossomServer: String + get() = blossomServers.firstOrNull() ?: DEFAULT_BLOSSOM_SERVER } 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 76bace33e..da63969f2 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt @@ -91,6 +91,7 @@ import com.vitorpamplona.amethyst.desktop.ui.deck.DeckState import com.vitorpamplona.amethyst.desktop.ui.deck.SinglePaneLayout import com.vitorpamplona.amethyst.desktop.ui.profile.ProfileInfoCard import com.vitorpamplona.amethyst.desktop.ui.relay.RelayStatusCard +import com.vitorpamplona.amethyst.desktop.ui.settings.MediaServerSettings import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip47WalletConnect.Nip47WalletConnect import kotlinx.coroutines.CoroutineScope @@ -877,6 +878,15 @@ fun RelaySettingsScreen( HorizontalDivider() Spacer(Modifier.height(24.dp)) + // Media Server Settings + MediaServerSettings( + initialServers = DesktopPreferences.blossomServers, + onServersChanged = { DesktopPreferences.blossomServers = it }, + ) + Spacer(Modifier.height(24.dp)) + HorizontalDivider() + Spacer(Modifier.height(24.dp)) + // Developer Settings Section (only in debug mode) if (DebugConfig.isDebugMode) { com.vitorpamplona.amethyst.desktop.ui 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 8cbb09f8f..ac63c4e07 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 @@ -46,6 +46,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import com.vitorpamplona.amethyst.commons.model.nip10TextNotes.PublishAction +import com.vitorpamplona.amethyst.desktop.DesktopPreferences import com.vitorpamplona.amethyst.desktop.account.AccountState import com.vitorpamplona.amethyst.desktop.network.DesktopRelayConnectionManager import com.vitorpamplona.amethyst.desktop.service.upload.DesktopUploadOrchestrator @@ -58,8 +59,6 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File -private const val DEFAULT_BLOSSOM_SERVER = "https://blossom.primal.net" - @Composable fun ComposeNoteDialog( onDismiss: () -> Unit, @@ -189,7 +188,7 @@ fun ComposeNoteDialog( orchestrator.upload( file = file, alt = null, - serverBaseUrl = DEFAULT_BLOSSOM_SERVER, + serverBaseUrl = DesktopPreferences.preferredBlossomServer, signer = account.signer, ) uploadTracker.onSuccess(result) 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 6c936d885..4b5f22f32 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 @@ -92,6 +92,7 @@ import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle import com.vitorpamplona.quartz.nip04Dm.messages.PrivateDmEvent import com.vitorpamplona.quartz.nip17Dm.NIP17Factory import com.vitorpamplona.quartz.nip17Dm.base.ChatroomKey +import com.vitorpamplona.quartz.nip17Dm.files.ChatMessageEncryptedFileHeaderEvent import kotlinx.coroutines.launch private val isMacOS = System.getProperty("os.name").lowercase().contains("mac") @@ -436,12 +437,20 @@ private fun MessageWithReactions( } }, ) { _ -> - SelectionContainer { - Text( - text = decryptedContent ?: "", - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - ) + when (note.event) { + is ChatMessageEncryptedFileHeaderEvent -> { + ChatFileAttachment(event = note.event as ChatMessageEncryptedFileHeaderEvent) + } + + else -> { + SelectionContainer { + Text( + text = decryptedContent ?: "", + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + ) + } + } } } }