android, desktop: preserving long message when failed to send (#5297)

* android, desktop: preserving long message when failed to send

* forwarding

* unused code

* strings

---------

Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
Stanislav Dmitrenko
2024-12-03 06:36:48 +07:00
committed by GitHub
parent c04e952620
commit e61babdc8f
3 changed files with 71 additions and 12 deletions
@@ -894,8 +894,27 @@ object ChatController {
private suspend fun processSendMessageCmd(rh: Long?, cmd: CC): List<AChatItem>? {
val r = sendCmd(rh, cmd)
return when (r) {
is CR.NewChatItems -> r.chatItems
return when {
r is CR.NewChatItems -> r.chatItems
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore && r.chatError.storeError is StoreError.LargeMsg && cmd is CC.ApiSendMessages -> {
val mc = cmd.composedMessages.last().msgContent
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.maximum_message_size_title),
if (mc is MsgContent.MCImage || mc is MsgContent.MCVideo || mc is MsgContent.MCLink) {
generalGetString(MR.strings.maximum_message_size_reached_non_text)
} else {
generalGetString(MR.strings.maximum_message_size_reached_text)
}
)
null
}
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore && r.chatError.storeError is StoreError.LargeMsg && cmd is CC.ApiForwardChatItems -> {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.maximum_message_size_title),
generalGetString(MR.strings.maximum_message_size_reached_forwarding)
)
null
}
else -> {
if (!(networkErrorAlert(r))) {
apiErrorAlert("processSendMessageCmd", generalGetString(MR.strings.error_sending_message), r)
@@ -943,7 +962,21 @@ object ChatController {
suspend fun apiUpdateChatItem(rh: Long?, type: ChatType, id: Long, itemId: Long, mc: MsgContent, live: Boolean = false): AChatItem? {
val r = sendCmd(rh, CC.ApiUpdateChatItem(type, id, itemId, mc, live))
if (r is CR.ChatItemUpdated) return r.chatItem
when {
r is CR.ChatItemUpdated -> return r.chatItem
r is CR.ChatCmdError && r.chatError is ChatError.ChatErrorStore && r.chatError.storeError is StoreError.LargeMsg -> {
AlertManager.shared.showAlertMsg(
generalGetString(MR.strings.maximum_message_size_title),
if (mc is MsgContent.MCImage || mc is MsgContent.MCVideo || mc is MsgContent.MCLink) {
generalGetString(MR.strings.maximum_message_size_reached_non_text)
} else {
generalGetString(MR.strings.maximum_message_size_reached_text)
}
)
return null
}
}
Log.e(TAG, "apiUpdateChatItem bad response: ${r.responseType} ${r.details}")
return null
}
@@ -6357,6 +6390,7 @@ sealed class StoreError {
is HostMemberIdNotFound -> "hostMemberIdNotFound"
is ContactNotFoundByFileId -> "contactNotFoundByFileId"
is NoGroupSndStatus -> "noGroupSndStatus"
is LargeMsg -> "largeMsg"
}
@Serializable @SerialName("duplicateName") object DuplicateName: StoreError()
@@ -6416,6 +6450,7 @@ sealed class StoreError {
@Serializable @SerialName("hostMemberIdNotFound") class HostMemberIdNotFound(val groupId: Long): StoreError()
@Serializable @SerialName("contactNotFoundByFileId") class ContactNotFoundByFileId(val fileId: Long): StoreError()
@Serializable @SerialName("noGroupSndStatus") class NoGroupSndStatus(val itemId: Long, val groupMemberId: Long): StoreError()
@Serializable @SerialName("largeMsg") object LargeMsg: StoreError()
}
@Serializable
@@ -412,6 +412,7 @@ fun ComposeView(
val cInfo = chat.chatInfo
val cs = composeState.value
var sent: List<ChatItem>?
var lastMessageFailedToSend: ComposeState? = null
val msgText = text ?: cs.message
fun sending() {
@@ -461,6 +462,19 @@ fun ComposeView(
}
}
fun constructFailedMessage(cs: ComposeState): ComposeState {
val preview = when (cs.preview) {
is ComposePreview.MediaPreview -> {
ComposePreview.MediaPreview(
if (cs.preview.images.isNotEmpty()) listOf(cs.preview.images.last()) else emptyList(),
if (cs.preview.content.isNotEmpty()) listOf(cs.preview.content.last()) else emptyList()
)
}
else -> cs.preview
}
return cs.copy(inProgress = false, preview = preview)
}
fun updateMsgContent(msgContent: MsgContent): MsgContent {
return when (msgContent) {
is MsgContent.MCText -> checkLinkPreview()
@@ -517,6 +531,9 @@ fun ComposeView(
sent = null
} else if (cs.contextItem is ComposeContextItem.ForwardingItems) {
sent = forwardItem(chat.remoteHostId, cs.contextItem.chatItems, cs.contextItem.fromChatInfo, ttl = ttl)
if (sent == null) {
lastMessageFailedToSend = constructFailedMessage(cs)
}
if (cs.message.isNotEmpty()) {
sent?.mapIndexed { index, message ->
if (index == sent!!.lastIndex) {
@@ -531,6 +548,7 @@ fun ComposeView(
val ei = cs.contextItem.chatItem
val updatedMessage = updateMessage(ei, chat, live)
sent = if (updatedMessage != null) listOf(updatedMessage) else null
lastMessageFailedToSend = if (updatedMessage == null) constructFailedMessage(cs) else null
} else if (liveMessage != null && liveMessage.sent) {
val updatedMessage = updateMessage(liveMessage.chatItem, chat, live)
sent = if (updatedMessage != null) listOf(updatedMessage) else null
@@ -631,19 +649,21 @@ fun ComposeView(
ttl = ttl
)
sent = if (sendResult != null) listOf(sendResult) else null
}
if (sent == null &&
(cs.preview is ComposePreview.MediaPreview ||
cs.preview is ComposePreview.FilePreview ||
cs.preview is ComposePreview.VoicePreview)
) {
val sendResult = send(chat, MsgContent.MCText(msgText), quotedItemId, null, live, ttl)
sent = if (sendResult != null) listOf(sendResult) else null
if (sent == null && index == msgs.lastIndex && cs.liveMessage == null) {
constructFailedMessage(cs)
// it's the last message in the series so if it fails, restore it in ComposeView for editing
lastMessageFailedToSend = constructFailedMessage(cs)
}
}
}
val wasForwarding = cs.forwarding
val forwardingFromChatId = (cs.contextItem as? ComposeContextItem.ForwardingItems)?.fromChatInfo?.id
clearState(live)
val lastFailed = lastMessageFailedToSend
if (lastFailed == null) {
clearState(live)
} else {
composeState.value = lastFailed
}
val draft = chatModel.draft.value
if (wasForwarding && chatModel.draftChatId.value == chat.chatInfo.id && forwardingFromChatId != chat.chatInfo.id && draft != null) {
composeState.value = draft
@@ -441,6 +441,10 @@
<string name="files_and_media_not_allowed">Files and media not allowed</string>
<string name="voice_messages_not_allowed">Voice messages not allowed</string>
<string name="compose_message_placeholder">Message</string>
<string name="maximum_message_size_title">Message is too large!</string>
<string name="maximum_message_size_reached_text">Please reduce the message size and send again.</string>
<string name="maximum_message_size_reached_non_text">Please reduce the message size or remove media and send again.</string>
<string name="maximum_message_size_reached_forwarding">You can copy and reduce the message size to send it.</string>
<!-- Images - chat.simplex.app.views.chat.item.CIImageView.kt -->
<string name="image_descr">Image</string>