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 b531a2a0d4..d1548c194e 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/Main.kt @@ -32,6 +32,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.rememberScrollState @@ -864,6 +865,7 @@ fun App( } is AccountState.ConnectingRelays -> {} + is AccountState.Loading -> {} } } @@ -924,8 +926,10 @@ fun App( if (current != null) { accountManager.loadNwcConnection(current.npub) } + } else { + // No saved account found → show login screen + accountManager.setLoggedOut() } - // If failure: state remains LoggedOut → login screen shows automatically } onDispose { @@ -956,6 +960,28 @@ fun App( com.vitorpamplona.amethyst.desktop.ui.deck.LocalLocalRelayStore provides localRelayStore, ) { when (accountState) { + is AccountState.Loading -> { + // Branded loading screen while accounts load from storage + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + androidx.compose.material3.CircularProgressIndicator( + modifier = Modifier.size(32.dp), + color = MaterialTheme.colorScheme.primary, + strokeWidth = 3.dp, + ) + Spacer(Modifier.height(16.dp)) + Text( + "Amethyst", + style = MaterialTheme.typography.headlineMedium, + color = MaterialTheme.colorScheme.onBackground, + ) + } + } + } + is AccountState.LoggedOut -> { LoginScreen( accountManager = accountManager, diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt index 9b580b467a..4c4ef4ebc8 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManager.kt @@ -69,6 +69,8 @@ import kotlinx.coroutines.withTimeout import java.io.File sealed class AccountState { + data object Loading : AccountState() + data object LoggedOut : AccountState() data object ConnectingRelays : AccountState() @@ -123,7 +125,7 @@ class AccountManager internal constructor( private val _allAccounts = MutableStateFlow>(persistentListOf()) val allAccounts: StateFlow> = _allAccounts.asStateFlow() - private val _accountState = MutableStateFlow(AccountState.LoggedOut) + private val _accountState = MutableStateFlow(AccountState.Loading) val accountState: StateFlow = _accountState.asStateFlow() private val _nwcConnection = MutableStateFlow(null) @@ -463,6 +465,10 @@ class AccountManager internal constructor( accountStorage.setCurrentAccount(npub) } + fun setLoggedOut() { + _accountState.value = AccountState.LoggedOut + } + fun setConnectingRelays() { _accountState.value = AccountState.ConnectingRelays } diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManagerStateTransitionTest.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManagerStateTransitionTest.kt index f9adf3bff9..6734d49793 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManagerStateTransitionTest.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/account/AccountManagerStateTransitionTest.kt @@ -94,12 +94,12 @@ class AccountManagerStateTransitionTest { advanceUntilIdle() - // Should see: LoggedOut → ConnectingRelays → LoggedIn + // Should see: Loading → ConnectingRelays → LoggedIn assertTrue( states.size >= 3, "Expected at least 3 state transitions, got ${states.size}: $states", ) - assertIs(states[0]) + assertIs(states[0]) assertIs(states[1]) assertIs(states[2]) @@ -125,12 +125,12 @@ class AccountManagerStateTransitionTest { advanceUntilIdle() - // Should see: LoggedOut → ConnectingRelays → LoggedOut + // Should see: Loading → ConnectingRelays → LoggedOut assertTrue( states.size >= 3, "Expected at least 3 state transitions, got ${states.size}: $states", ) - assertIs(states[0]) + assertIs(states[0]) assertIs(states[1]) assertIs(states[2])