From a76c8d117b4f1d390856619aa0b39fbf92836e21 Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Tue, 7 Jul 2026 08:27:25 +0700 Subject: [PATCH 1/3] fix syncing state --- shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt | 1 + .../commonMain/kotlin/su/reya/coop/viewmodel/ChatViewModel.kt | 2 +- .../kotlin/su/reya/coop/viewmodel/NostrViewModel.kt | 4 +--- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt index 4483ba0..be4f84a 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt @@ -219,6 +219,7 @@ class Nostr { KindStandard.INBOX_RELAYS -> { // Get all gift wrap events for the current user if (isSignedByUser(event = event)) { + messages.updateSyncState { it.copy(isSyncing = true) } messages.getUserMessages(msgRelayList = event) } } diff --git a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatViewModel.kt b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatViewModel.kt index e848f5f..baee6b6 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatViewModel.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/ChatViewModel.kt @@ -65,7 +65,7 @@ class ChatViewModel(private val nostr: Nostr) : BaseViewModel() { launch { nostr.messages.messageSyncState.collect { syncState -> // When at least some messages are processed, allow UI to show the list - if (syncState.processedCount > 0) { + if (syncState.processedCount > 0 || !syncState.isSyncing) { _state.update { it.copy(isPartialProcessedGiftWrap = true) } } diff --git a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/NostrViewModel.kt b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/NostrViewModel.kt index 5fb8c89..4c02d66 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/NostrViewModel.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/viewmodel/NostrViewModel.kt @@ -71,9 +71,7 @@ class NostrViewModel(private val nostr: Nostr) : BaseViewModel() { private val profiles = mutableMapOf>() private val metadataRequestChannel = Channel(Channel.UNLIMITED) private val seenPublicKeys = mutableSetOf() - - val isBusy = appState.map { it.isBusy } - .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false) + val isRelayListEmpty = appState.map { it.isRelayListEmpty } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), false) From ea7e3fd3edddab18e1e8e5a48dbdda2710dd9a4f Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Tue, 7 Jul 2026 10:59:09 +0700 Subject: [PATCH 2/3] . --- shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt | 2 +- .../src/commonMain/kotlin/su/reya/coop/nostr/ProfileManager.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt index be4f84a..330fd31 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/Nostr.kt @@ -155,7 +155,7 @@ class Nostr { val processedEvent = mutableSetOf() val notifications = client?.notifications() ?: return@supervisorScope - val giftWrapQueue = Channel(Channel.UNLIMITED) + val giftWrapQueue = Channel(1024) var processedCount = 0 var eoseReceived = false diff --git a/shared/src/commonMain/kotlin/su/reya/coop/nostr/ProfileManager.kt b/shared/src/commonMain/kotlin/su/reya/coop/nostr/ProfileManager.kt index 889e79b..c276df9 100644 --- a/shared/src/commonMain/kotlin/su/reya/coop/nostr/ProfileManager.kt +++ b/shared/src/commonMain/kotlin/su/reya/coop/nostr/ProfileManager.kt @@ -82,7 +82,7 @@ class ProfileManager(private val nostr: Nostr) { client?.sync(filter, relays) } catch (e: Exception) { - throw IllegalStateException("Failed to fetch mutual contacts: ${e.message}", e) + println("Failed to sync mutual contacts: ${e.message}") } } From 9df4789b62d4a52d8c3c81b217f17ae7536736cd Mon Sep 17 00:00:00 2001 From: Ren Amamiya Date: Tue, 7 Jul 2026 11:09:06 +0700 Subject: [PATCH 3/3] update --- .../kotlin/su/reya/coop/screens/NewIdentityScreen.kt | 9 ++------- .../kotlin/su/reya/coop/screens/UpdateProfileScreen.kt | 9 ++------- .../kotlin/su/reya/coop/shared/ProfileEditor.kt | 2 +- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/NewIdentityScreen.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/NewIdentityScreen.kt index 80a3393..b54064e 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/NewIdentityScreen.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/NewIdentityScreen.kt @@ -1,8 +1,6 @@ package su.reya.coop.screens import androidx.compose.runtime.Composable -import androidx.compose.runtime.rememberCoroutineScope -import kotlinx.coroutines.launch import su.reya.coop.LocalAuthViewModel import su.reya.coop.LocalNavigator import su.reya.coop.Screen @@ -12,17 +10,14 @@ import su.reya.coop.shared.ProfileEditor fun NewIdentityScreen() { val authViewModel = LocalAuthViewModel.current val navigator = LocalNavigator.current - val scope = rememberCoroutineScope() ProfileEditor( title = "Create a new identity", buttonLabel = "Continue", onBack = { navigator.goBack() }, onConfirm = { name, bio, bytes, type -> - scope.launch { - authViewModel.createIdentity(name, bio, bytes, type) - navigator.navigate(Screen.Home) - } + authViewModel.createIdentity(name, bio, bytes, type) + navigator.navigate(Screen.Home) } ) } diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/UpdateProfileScreen.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/UpdateProfileScreen.kt index efa531a..c044f0e 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/screens/UpdateProfileScreen.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/screens/UpdateProfileScreen.kt @@ -2,9 +2,7 @@ package su.reya.coop.screens import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberCoroutineScope import androidx.lifecycle.compose.collectAsStateWithLifecycle -import kotlinx.coroutines.launch import su.reya.coop.LocalNavigator import su.reya.coop.LocalNostrViewModel import su.reya.coop.shared.ProfileEditor @@ -13,7 +11,6 @@ import su.reya.coop.shared.ProfileEditor fun UpdateProfileScreen() { val nostrViewModel = LocalNostrViewModel.current val navigator = LocalNavigator.current - val scope = rememberCoroutineScope() val currentUser by nostrViewModel.currentUserProfile.collectAsStateWithLifecycle() val profile = currentUser?.metadata?.asRecord() @@ -26,10 +23,8 @@ fun UpdateProfileScreen() { initialPicture = profile?.picture, onBack = { navigator.goBack() }, onConfirm = { name, bio, bytes, type -> - scope.launch { - nostrViewModel.updateProfile(name, bio, bytes, type) - navigator.goBack() - } + nostrViewModel.updateProfile(name, bio, bytes, type) + navigator.goBack() } ) } diff --git a/composeApp/src/androidMain/kotlin/su/reya/coop/shared/ProfileEditor.kt b/composeApp/src/androidMain/kotlin/su/reya/coop/shared/ProfileEditor.kt index e975f85..b3827fb 100644 --- a/composeApp/src/androidMain/kotlin/su/reya/coop/shared/ProfileEditor.kt +++ b/composeApp/src/androidMain/kotlin/su/reya/coop/shared/ProfileEditor.kt @@ -69,7 +69,7 @@ fun ProfileEditor( initialBio: String = "", initialPicture: Any? = null, // Accepts Uri (picked) or String (current URL) onBack: () -> Unit, - onConfirm: (name: String, bio: String, pictureBytes: ByteArray?, contentType: String?) -> Unit + onConfirm: suspend (name: String, bio: String, pictureBytes: ByteArray?, contentType: String?) -> Unit ) { val context = LocalContext.current val snackbarHostState = LocalSnackbarHostState.current