From 74a37320fe8afe4da666d3925a460f1768b046c5 Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Sat, 6 Jun 2026 07:30:47 +0000 Subject: [PATCH] fix: occasional splash screen hang (#15) Reviewed-on: https://git.reya.su/reya/coop-mobile/pulls/15 --- .../kotlin/su/reya/coop/NostrViewModel.kt | 9 ++++++++- .../commonMain/kotlin/su/reya/coop/Signer.kt | 19 +++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/NostrViewModel.kt b/shared/src/commonMain/kotlin/su/reya/coop/NostrViewModel.kt index fcba31b..6a6afd1 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/NostrViewModel.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/NostrViewModel.kt @@ -76,6 +76,11 @@ class NostrViewModel( private val seenPublicKeys = mutableSetOf() init { + // Skip the splash screen if a user is already logged in + if (nostr.signer.currentUser != null) { + _signerRequired.value = false + } + // Check if the notification banner has been dismissed checkNotificationBannerDismissedStatus() @@ -216,7 +221,9 @@ class NostrViewModel( private fun login() { viewModelScope.launch { try { - val secret = secretStore.get("user_signer") + val secret = withTimeoutOrNull(3.seconds) { + secretStore.get("user_signer") + } if (secret == null) { _signerRequired.value = true diff --git a/shared/src/commonMain/kotlin/su/reya/coop/Signer.kt b/shared/src/commonMain/kotlin/su/reya/coop/Signer.kt index 5e87674..dc98991 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/Signer.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/Signer.kt @@ -2,31 +2,42 @@ package su.reya.coop import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import kotlinx.coroutines.withTimeoutOrNull import rust.nostr.sdk.AsyncNostrSigner import rust.nostr.sdk.Event import rust.nostr.sdk.PublicKey import rust.nostr.sdk.UnsignedEvent +import kotlin.concurrent.Volatile +import kotlin.time.Duration.Companion.seconds class UniversalSigner(initialSigner: AsyncNostrSigner) : AsyncNostrSigner { private val mutex = Mutex() + + @Volatile private var signer: AsyncNostrSigner = initialSigner + @Volatile var currentUser: PublicKey? = null private set /** * Get the current signer. */ - suspend fun get(): AsyncNostrSigner = mutex.withLock { - signer - } + fun get(): AsyncNostrSigner = signer /** * Switch to a new signer. */ suspend fun switch(newSigner: AsyncNostrSigner) = mutex.withLock { + val pubkey = try { + withTimeoutOrNull(20.seconds) { + newSigner.getPublicKeyAsync() + } + } catch (e: Exception) { + throw IllegalStateException("Failed to get public key from signer", e) + } signer = newSigner - currentUser = newSigner.getPublicKeyAsync() + currentUser = pubkey } override suspend fun getPublicKeyAsync(): PublicKey? {