From eae28ab943d782591daa00f306b88c4ea6f78405 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 27 Apr 2026 14:04:31 +0000 Subject: [PATCH] feat(audiorooms): prompt to add default server when user has none MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the + FAB is tapped on Audio Rooms and the user's kind:10112 nests-server list is empty (or has no http(s) entries), show an AlertDialog offering to add the built-in default (CreateAudioRoomViewModel.DEFAULT_SERVICE_URL — moq.nostrnests.com) to their list, then continue into the create-room sheet. Wired through the existing Account.sendNestsServersList path used by the Settings screen's NestsServersViewModel.save(), so the resulting kind:10112 propagates to the user's outbox identically. On signer/ network failure surface a toast and keep the dialog dismissed (the user can retry from Settings). If the user already has a usable server, behavior is unchanged — the FAB opens the create-room sheet directly. https://claude.ai/code/session_01RDpuki4t8StSg1CZcXnV5b --- .../loggedIn/audiorooms/AudioRoomsScreen.kt | 61 ++++++++++++++++++- amethyst/src/main/res/values/strings.xml | 5 ++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/audiorooms/AudioRoomsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/audiorooms/AudioRoomsScreen.kt index 8f41daa61..c91515440 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/audiorooms/AudioRoomsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/audiorooms/AudioRoomsScreen.kt @@ -21,7 +21,10 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.audiorooms import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.AlertDialog import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -44,6 +47,7 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.audiorooms.create.CreateAudioRoomSheet +import com.vitorpamplona.amethyst.ui.screen.loggedIn.audiorooms.create.CreateAudioRoomViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.audiorooms.datasource.AudioRoomsFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.stringRes @@ -69,7 +73,10 @@ fun AudioRoomsScreen( WatchAccountForAudioRoomsScreen(audioRoomsFeedState = audioRoomsFeedContentState, accountViewModel = accountViewModel) AudioRoomsFilterAssemblerSubscription(accountViewModel) + val nestsServers by accountViewModel.account.nestsServers.flow + .collectAsStateWithLifecycle() var showCreateSheet by remember { mutableStateOf(false) } + var showSetupDialog by remember { mutableStateOf(false) } DisappearingScaffold( isInvertedLayout = false, @@ -87,7 +94,13 @@ fun AudioRoomsScreen( }, floatingButton = { FloatingActionButton( - onClick = { showCreateSheet = true }, + onClick = { + if (nestsServers.any { it.startsWith("http") }) { + showCreateSheet = true + } else { + showSetupDialog = true + } + }, shape = CircleShape, ) { Icon( @@ -119,6 +132,29 @@ fun AudioRoomsScreen( } } + if (showSetupDialog) { + SetUpAudioServerDialog( + defaultUrl = CreateAudioRoomViewModel.DEFAULT_SERVICE_URL, + onDismiss = { showSetupDialog = false }, + onConfirm = { + showSetupDialog = false + accountViewModel.launchSigner { + try { + accountViewModel.account.sendNestsServersList( + listOf(CreateAudioRoomViewModel.DEFAULT_SERVICE_URL), + ) + showCreateSheet = true + } catch (_: Throwable) { + accountViewModel.toastManager.toast( + R.string.audio_rooms, + R.string.audio_room_no_server_save_failed, + ) + } + } + }, + ) + } + if (showCreateSheet) { CreateAudioRoomSheet( accountViewModel = accountViewModel, @@ -127,6 +163,29 @@ fun AudioRoomsScreen( } } +@Composable +private fun SetUpAudioServerDialog( + defaultUrl: String, + onDismiss: () -> Unit, + onConfirm: () -> Unit, +) { + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(stringRes(R.string.audio_room_no_server_title)) }, + text = { Text(stringRes(R.string.audio_room_no_server_body, defaultUrl)) }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text(stringRes(R.string.audio_room_no_server_use_default)) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text(stringRes(R.string.audio_room_no_server_cancel)) + } + }, + ) +} + @Composable fun WatchAccountForAudioRoomsScreen( audioRoomsFeedState: FeedContentState, diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 5da4e92dc..cd621dc77 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -556,6 +556,11 @@ Unmute Share room Start space + Set up an audio server + You haven\'t picked an audio server yet. Add %1$s to your server list and continue?\n\nYou can change this later in Settings. + Use default + Cancel + Couldn\'t save your audio server list. Try again. Start a new audio room Room name What\'s it about?