From 40da451f4e3610a8440ef3a922327f9e0ba2de61 Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Mon, 13 Jul 2026 07:40:02 +0700 Subject: [PATCH] . --- .../su/reya/coop/screens/RelayScreen.kt | 4 +- .../reya/coop/repository/AccountRepository.kt | 69 ++++++++----------- .../reya/coop/viewmodel/AccountViewModel.kt | 11 ++- .../coop/viewmodel/ChatScreenViewModel.kt | 1 - 4 files changed, 33 insertions(+), 52 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/RelayScreen.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/RelayScreen.kt index 4d9f247..036008a 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/RelayScreen.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/RelayScreen.kt @@ -100,8 +100,8 @@ fun RelayScreen(viewModel: AccountViewModel) { viewModel.loadCurrentUserMsgRelayList() } - val loadedRelayList by viewModel.currentUserRelayList.collectAsStateWithLifecycle() - val loadedMsgRelayList by viewModel.currentUserMsgRelayList.collectAsStateWithLifecycle() + val loadedRelayList by viewModel.userRelayList.collectAsStateWithLifecycle() + val loadedMsgRelayList by viewModel.userMsgRelayList.collectAsStateWithLifecycle() LaunchedEffect(loadedRelayList) { if (loadedRelayList.isNotEmpty()) { diff --git a/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt b/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt index f9cbb15..e7562c7 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/repository/AccountRepository.kt @@ -13,7 +13,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterNotNull -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf @@ -84,12 +83,11 @@ class AccountRepository( private val _isRelayListEmpty = MutableStateFlow(false) val isRelayListEmpty: StateFlow = _isRelayListEmpty.asStateFlow() - private val _currentUserRelayList = MutableStateFlow>(emptyMap()) - val currentUserRelayList: StateFlow> = - _currentUserRelayList.asStateFlow() + private val _userRelayList = MutableStateFlow>(emptyMap()) + val userRelayList: StateFlow> = _userRelayList.asStateFlow() - private val _currentUserMsgRelayList = MutableStateFlow>(emptyList()) - val currentUserMsgRelayList: StateFlow> = _currentUserMsgRelayList.asStateFlow() + private val _userMsgRelayList = MutableStateFlow>(emptyList()) + val userMsgRelayList: StateFlow> = _userMsgRelayList.asStateFlow() init { checkNotificationBannerDismissedStatus() @@ -103,9 +101,22 @@ class AccountRepository( nostr.signer.publicKeyFlow .filterNotNull() .distinctUntilChanged() - .collectLatest { - getUserMetadata() - checkRelayList() + .collectLatest { pubkey -> + // Refresh metadata + nostr.profiles.getUserMetadata() + + // Verify messaging relays exist (wait up to 10s for initial fetch) + val relays = withTimeoutOrNull(10.seconds) { + var list = nostr.relays.getMsgRelays(pubkey) + while (list.isEmpty()) { + delay(500.milliseconds) + list = nostr.relays.getMsgRelays(pubkey) + } + list + } ?: emptyList() + + // Automatically update the warning state + _isRelayListEmpty.value = relays.isEmpty() } } } @@ -315,12 +326,6 @@ class AccountRepository( .map { (p, m) -> Profile(p, m) } ) - private fun getUserMetadata() { - scope.launch { - nostr.profiles.getUserMetadata() - } - } - fun updateProfile( name: String? = null, bio: String? = null, @@ -454,24 +459,6 @@ class AccountRepository( } } - @OptIn(ExperimentalCoroutinesApi::class) - private fun checkRelayList() { - scope.launch { - val currentUser = nostr.signer.publicKeyFlow.filterNotNull().first() - - val relays = withTimeoutOrNull(10.seconds) { - var result = nostr.relays.getMsgRelays(currentUser) - while (result.isEmpty()) { - delay(500.milliseconds) - result = nostr.relays.getMsgRelays(currentUser) - } - result - } ?: emptyList() - - if (relays.isEmpty()) _isRelayListEmpty.value = true - } - } - fun dismissRelayWarning() { _isRelayListEmpty.value = false } @@ -499,9 +486,8 @@ class AccountRepository( fun loadCurrentUserRelayList() { scope.launch { try { - val currentUser = - nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found") - _currentUserRelayList.value = nostr.relays.getRelayList(currentUser) + val user = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found") + _userRelayList.value = nostr.relays.getRelayList(user) } catch (e: Exception) { showError("Error: ${e.message}") } @@ -563,16 +549,15 @@ class AccountRepository( fun loadCurrentUserMsgRelayList() { scope.launch { try { - val currentUser = - nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found") - _currentUserMsgRelayList.value = nostr.relays.getMsgRelays(currentUser) + val user = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found") + _userMsgRelayList.value = nostr.relays.getMsgRelays(user) } catch (e: Exception) { showError("Error: ${e.message}") } } } - private suspend fun currentUserMsgRelayListInternal(): List { + private suspend fun userLatestMsgRelayList(): List { try { val currentUser = nostr.signer.getPublicKeyAsync() ?: throw Exception("User not found") return nostr.relays.getMsgRelays(currentUser) @@ -586,7 +571,7 @@ class AccountRepository( scope.launch { try { val relayUrl = RelayUrl.parse(relay) - val relays = currentUserMsgRelayListInternal().toMutableSet() + val relays = userLatestMsgRelayList().toMutableSet() relays.add(relayUrl) nostr.relays.setMsgRelays(relays.toList()) @@ -600,7 +585,7 @@ class AccountRepository( scope.launch { try { val relayUrl = RelayUrl.parse(relay) - val relays = currentUserMsgRelayListInternal().toMutableSet() + val relays = userLatestMsgRelayList().toMutableSet() relays.remove(relayUrl) nostr.relays.setMsgRelays(relays.toList()) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/AccountViewModel.kt b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/AccountViewModel.kt index 999da5e..e25a53e 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/AccountViewModel.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/AccountViewModel.kt @@ -19,9 +19,8 @@ class AccountViewModel( val currentUserProfile: StateFlow = repository.currentUserProfile val contactList: StateFlow> = repository.contactList val isRelayListEmpty: StateFlow = repository.isRelayListEmpty - val currentUserRelayList: StateFlow> = - repository.currentUserRelayList - val currentUserMsgRelayList: StateFlow> = repository.currentUserMsgRelayList + val userRelayList: StateFlow> = repository.userRelayList + val userMsgRelayList: StateFlow> = repository.userMsgRelayList fun logout(onLogout: () -> Unit = {}) = repository.logout(onLogout) fun dismissNotificationBanner() = repository.dismissNotificationBanner() @@ -35,16 +34,14 @@ class AccountViewModel( bio: String?, picture: ByteArray?, contentType: String? = null - ) = - repository.createIdentity(name, bio, picture, contentType) + ) = repository.createIdentity(name, bio, picture, contentType) fun updateProfile( name: String? = null, bio: String? = null, picture: ByteArray? = null, contentType: String? = null - ) = - repository.updateProfile(name, bio, picture, contentType) + ) = repository.updateProfile(name, bio, picture, contentType) fun resetInternalState() = repository.resetInternalState() fun addContact(address: String) = repository.addContact(address) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatScreenViewModel.kt b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatScreenViewModel.kt index 7071a50..376717c 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatScreenViewModel.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatScreenViewModel.kt @@ -29,7 +29,6 @@ class ChatScreenViewModel( var loading by mutableStateOf(true) var newOtherMessages by mutableIntStateOf(0) var requireScreening by mutableStateOf(screening) - val messages = mutableStateListOf() init {