diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt index 00d19b06f..b59d57d8a 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/ChatModel.kt @@ -114,7 +114,8 @@ object ChatModel { val clipboardHasText = mutableStateOf(false) - var updatingChatsMutex: Mutex = Mutex() + val updatingChatsMutex: Mutex = Mutex() + val changingActiveUserMutex: Mutex = Mutex() val desktopNoUserNoRemote: Boolean @Composable get() = appPlatform.isDesktop && currentUser.value == null && currentRemoteHost.value == null fun desktopNoUserNoRemote(): Boolean = appPlatform.isDesktop && currentUser.value == null && currentRemoteHost.value == null diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt index 363a3bcdb..d1927e405 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/model/SimpleXAPI.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import chat.simplex.common.model.ChatModel.updatingChatsMutex +import chat.simplex.common.model.ChatModel.changingActiveUserMutex import dev.icerock.moko.resources.compose.painterResource import chat.simplex.common.platform.* import chat.simplex.common.ui.theme.* @@ -335,14 +336,14 @@ object ChatController { var lastMsgReceivedTimestamp: Long = System.currentTimeMillis() private set - private fun currentUserId(funcName: String): Long { + private suspend fun currentUserId(funcName: String): Long = changingActiveUserMutex.withLock { val userId = chatModel.currentUser.value?.userId if (userId == null) { val error = "$funcName: no current user" Log.e(TAG, error) throw Exception(error) } - return userId + userId } suspend fun startChat(user: User) { @@ -408,8 +409,11 @@ object ChatController { } suspend fun changeActiveUser_(rhId: Long?, toUserId: Long, viewPwd: String?) { - val currentUser = apiSetActiveUser(rhId, toUserId, viewPwd) - chatModel.currentUser.value = currentUser + val currentUser = changingActiveUserMutex.withLock { + apiSetActiveUser(rhId, toUserId, viewPwd).also { + chatModel.currentUser.value = it + } + } val users = listUsers(rhId) chatModel.users.clear() chatModel.users.addAll(users) @@ -886,10 +890,7 @@ object ChatController { suspend fun apiAddContact(rh: Long?, incognito: Boolean): Pair?, (() -> Unit)?> { - val userId = chatModel.currentUser.value?.userId ?: run { - Log.e(TAG, "apiAddContact: no current user") - return null to null - } + val userId = try { currentUserId("apiAddContact") } catch (e: Exception) { return null to null } val r = sendCmd(rh, CC.APIAddContact(userId, incognito)) return when (r) { is CR.Invitation -> (r.connReqInvitation to r.connection) to null @@ -918,10 +919,7 @@ object ChatController { } suspend fun apiConnect(rh: Long?, incognito: Boolean, connReq: String): PendingContactConnection? { - val userId = chatModel.currentUser.value?.userId ?: run { - Log.e(TAG, "apiConnect: no current user") - return null - } + val userId = try { currentUserId("apiConnect") } catch (e: Exception) { return null } val r = sendCmd(rh, CC.APIConnect(userId, incognito, connReq)) when { r is CR.SentConfirmation -> return r.connection @@ -960,10 +958,7 @@ object ChatController { } suspend fun apiConnectContactViaAddress(rh: Long?, incognito: Boolean, contactId: Long): Contact? { - val userId = chatModel.currentUser.value?.userId ?: run { - Log.e(TAG, "apiConnectContactViaAddress: no current user") - return null - } + val userId = try { currentUserId("apiConnectContactViaAddress") } catch (e: Exception) { return null } val r = sendCmd(rh, CC.ApiConnectContactViaAddress(userId, incognito, contactId)) when { r is CR.SentInvitationToContact -> return r.contact