-Invest in SimpleX Chat. [Register now](https://simplexchat.typeform.com/crowdfunding).
+Invest in SimpleX Chat. [Learn more on Wefunder](https://wefunder.com/simplexchat).
# SimpleX - the first messaging platform that has no user identifiers of any kind - 100% private by design!
diff --git a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.android.kt b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.android.kt
index 83677f3318..1826b2114e 100644
--- a/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.android.kt
+++ b/apps/multiplatform/common/src/androidMain/kotlin/chat/simplex/common/views/database/DatabaseEncryptionView.android.kt
@@ -42,10 +42,9 @@ actual fun SavePassphraseSetting(
}
Text(
stringResource(MR.strings.save_passphrase_in_keychain),
- Modifier.padding(end = 24.dp),
+ Modifier.weight(1f).padding(end = 24.dp),
color = Color.Unspecified
)
- Spacer(Modifier.fillMaxWidth().weight(1f))
DefaultSwitch(
checked = useKeychain,
onCheckedChange = onCheckedChange,
diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt
index 40d7927264..ff393a3c30 100644
--- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt
+++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeView.kt
@@ -497,8 +497,8 @@ fun ComposeView(
}
}
- fun clearCurrentDraft() {
- if (chatModel.draftChatId.value == draftChatId(chat.id, chatScope)) {
+ fun clearCurrentDraft(forChat: Chat = chat) {
+ if (chatModel.draftChatId.value == draftChatId(forChat.id, chatScope)) {
chatModel.draft.value = null
chatModel.draftChatId.value = null
}
@@ -575,9 +575,10 @@ fun ComposeView(
}
// TODO [short links] connectCheckLinkPreview
- fun checkLinkPreview(): MsgContent {
- val msgText = composeState.value.message.text
- return when (val composePreview = composeState.value.preview) {
+ // the state is passed in by a send that must not read the current one - see sendMessageAsync
+ fun checkLinkPreview(cs: ComposeState = composeState.value): MsgContent {
+ val msgText = cs.message.text
+ return when (val composePreview = cs.preview) {
is ComposePreview.CLinkPreview -> {
val parsedMsg = parseToMarkdown(msgText)
val url = getMessageLinks(parsedMsg).first
@@ -597,6 +598,10 @@ fun ComposeView(
composeState.value = composeState.value.copy(inProgress = true)
}
+ // composeState and its inProgress flag are shared between the chats opened in this view, and sending is not cancelled
+ // when the chat is switched - a send may only clear or reset the state while it still holds the message that was sent
+ fun composeHasSentMessage(): Boolean = chatModel.chatId.value == chat.id && composeState.value.inProgress
+
suspend fun sendMemberContactInvitation() {
val mc = checkLinkPreview()
sending()
@@ -604,10 +609,10 @@ fun ComposeView(
if (contact != null) {
withContext(Dispatchers.Main) {
chatsCtx.updateContact(chat.remoteHostId, contact)
- clearState()
+ if (composeHasSentMessage()) clearState()
}
- } else {
- composeState.value = composeState.value.copy(inProgress = false)
+ } else withContext(Dispatchers.Main) {
+ if (composeHasSentMessage()) composeState.value = composeState.value.copy(inProgress = false)
}
}
@@ -624,10 +629,10 @@ fun ComposeView(
if (contact != null) {
withContext(Dispatchers.Main) {
chatsCtx.updateContact(chat.remoteHostId, contact)
- clearState()
+ if (composeHasSentMessage()) clearState()
}
- } else {
- composeState.value = composeState.value.copy(inProgress = false)
+ } else withContext(Dispatchers.Main) {
+ if (composeHasSentMessage()) composeState.value = composeState.value.copy(inProgress = false)
}
}
@@ -669,15 +674,19 @@ fun ComposeView(
chatModel.channelRelayHostnames.remove(groupInfo.groupId)
chatModel.groupMembers.value = relayResults.map { it.relayMember }
chatModel.populateGroupMembersIndexes()
- clearState()
+ if (composeHasSentMessage()) clearState()
}
- } else {
- composeState.value = composeState.value.copy(inProgress = false)
+ } else withContext(Dispatchers.Main) {
+ if (composeHasSentMessage()) composeState.value = composeState.value.copy(inProgress = false)
}
}
- suspend fun sendMessageAsync(text: String?, live: Boolean, ttl: Int?, sign: Boolean = false): List{{ "index-hero-p1" | i18n({}, lang) | safe }}
+{{ "index-hero-invest" | i18n({}, lang) | safe }} {{ "index-hero-invest-cta" | i18n({}, lang) | safe }}