From 90a9de7d0111038f3186dafb9cb7b515b0a4274f Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 14 May 2021 17:47:33 +0200 Subject: [PATCH] Show a temporary messages when sending and keep it on error Signed-off-by: Joas Schilling --- .../MagicOutcomingTextMessageViewHolder.kt | 4 + .../talk/controllers/ChatController.kt | 75 ++++++++++++++++--- .../talk/models/json/chat/ReadStatus.java | 6 +- app/src/main/res/drawable/ic_sending.xml | 10 +++ app/src/main/res/values/strings.xml | 2 + 5 files changed, 87 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/drawable/ic_sending.xml diff --git a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt index 852985ebe3..787c46f143 100644 --- a/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt +++ b/app/src/main/java/com/nextcloud/talk/adapters/messages/MagicOutcomingTextMessageViewHolder.kt @@ -191,12 +191,16 @@ class MagicOutcomingTextMessageViewHolder(itemView: View) : OutcomingTextMessage val readStatusDrawableInt = when (message.readStatus) { ReadStatus.READ -> R.drawable.ic_check_all ReadStatus.SENT -> R.drawable.ic_check + ReadStatus.SENDING -> R.drawable.ic_sending + ReadStatus.FAILED -> R.drawable.ic_warning_white else -> null } val readStatusContentDescriptionString = when (message.readStatus) { ReadStatus.READ -> context?.resources?.getString(R.string.nc_message_read) ReadStatus.SENT -> context?.resources?.getString(R.string.nc_message_sent) + ReadStatus.SENDING -> context?.resources?.getString(R.string.nc_message_sending) + ReadStatus.FAILED -> context?.resources?.getString(R.string.nc_message_send_error) else -> null } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index a5ec23a8b8..06efffef7d 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -152,6 +152,7 @@ import org.parceler.Parcels import retrofit2.HttpException import retrofit2.Response import java.net.HttpURLConnection +import java.security.MessageDigest import java.util.ArrayList import java.util.Date import java.util.HashMap @@ -547,7 +548,7 @@ class ChatController(args: Bundle) : override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { if (s.length >= lengthFilter) { messageInput?.error = String.format( - Objects.requireNonNull (resources).getString(R.string.nc_limit_hit), + Objects.requireNonNull(resources).getString(R.string.nc_limit_hit), Integer.toString(lengthFilter) ) } else { @@ -1091,6 +1092,46 @@ class ChatController(args: Bundle) : } private fun sendMessage(message: CharSequence, replyTo: Int?) { + val messObj = ChatMessage() + messObj.setMessage(message.toString()) + messObj.setActiveUser(conversationUser) + val tsLong = System.currentTimeMillis() / 1000 + messObj.setTimestamp(tsLong) + messObj.setJsonMessageId(0 - tsLong.toInt()) + + + messObj.setReadStatus(ReadStatus.SENDING) + + if (conversationUser!!.userId != "?") { + // Logged in user + messObj.setActorType("users") + messObj.setActorId(conversationUser.userId) + messObj.setActorDisplayName(conversationUser.username) + } else if (currentConversation!!.actorType != null) { + // API v3 or later + messObj.setActorType(currentConversation!!.actorType) + messObj.setActorId(currentConversation!!.actorId) + messObj.setActorDisplayName("") + } else { + // API v1 or v2 as a guest + messObj.setActorType("guests") + + val messageDigest: MessageDigest = MessageDigest.getInstance("SHA-1") + val digest: ByteArray = messageDigest.digest(currentConversation!!.sessionId.toByteArray()) + val sha1: StringBuilder = StringBuilder() + val i = digest.iterator() + while (i.hasNext()) { + sha1.append(String.format("%02X", i.next())) + } + + messObj.setActorId(sha1.toString()) + messObj.setActorDisplayName("") + } + + adapter!!.addToStart( + messObj, + true + ) if (conversationUser != null) { val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) @@ -1109,6 +1150,8 @@ class ChatController(args: Bundle) : } override fun onNext(genericOverall: GenericOverall) { + adapter!!.delete(messObj) + myFirstMessage = message if (popupBubble?.isShown ?: false) { @@ -1119,6 +1162,11 @@ class ChatController(args: Bundle) : } override fun onError(e: Throwable) { + Log.e(TAG, "An error occured while sending the chat message: " + e.message) + + messObj.setReadStatus(ReadStatus.FAILED) + adapter!!.updateAndMoveToStart(messObj) + if (e is HttpException) { val code = e.code() if (Integer.toString(code).startsWith("2")) { @@ -1307,9 +1355,9 @@ class ChatController(args: Bundle) : TextUtils.isEmpty(chatMessageList[i + 1].systemMessage) && chatMessageList[i + 1].actorId == chatMessageList[i].actorId && countGroupedMessages < 4 && DateFormatter.isSameDay( - chatMessageList[i].createdAt, - chatMessageList[i + 1].createdAt - ) + chatMessageList[i].createdAt, + chatMessageList[i + 1].createdAt + ) ) { chatMessageList[i].isGrouped = true countGroupedMessages++ @@ -1393,10 +1441,12 @@ class ChatController(args: Bundle) : if (message.item is ChatMessage) { val chatMessage = message.item as ChatMessage - if (chatMessage.jsonMessageId <= it) { - chatMessage.readStatus = ReadStatus.READ - } else { - chatMessage.readStatus = ReadStatus.SENT + if (chatMessage.jsonMessageId > 0) { + if (chatMessage.jsonMessageId <= it) { + chatMessage.readStatus = ReadStatus.READ + } else { + chatMessage.readStatus = ReadStatus.SENT + } } } } @@ -1620,7 +1670,12 @@ class ChatController(args: Bundle) : true } R.id.action_reply_privately -> { - val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1)) + val apiVersion = ApiUtils.getConversationApiVersion( + conversationUser, intArrayOf( + ApiUtils.APIv4, + 1 + ) + ) val retrofitBucket = ApiUtils.getRetrofitBucketForCreateRoom( apiVersion, conversationUser?.baseUrl, @@ -1668,6 +1723,7 @@ class ChatController(args: Bundle) : override fun onError(e: Throwable) { Log.e(TAG, e.message, e) } + override fun onComplete() {} }) } @@ -1675,6 +1731,7 @@ class ChatController(args: Bundle) : override fun onError(e: Throwable) { Log.e(TAG, e.message, e) } + override fun onComplete() {} }) true diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ReadStatus.java b/app/src/main/java/com/nextcloud/talk/models/json/chat/ReadStatus.java index 03442f3d12..cbac57e103 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ReadStatus.java +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ReadStatus.java @@ -21,5 +21,9 @@ package com.nextcloud.talk.models.json.chat; public enum ReadStatus { - NONE, SENT, READ + NONE, + SENT, + READ, + SENDING, + FAILED } diff --git a/app/src/main/res/drawable/ic_sending.xml b/app/src/main/res/drawable/ic_sending.xml new file mode 100644 index 0000000000..5893394f43 --- /dev/null +++ b/app/src/main/res/drawable/ic_sending.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9d93e797c8..8fe73263f9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -287,6 +287,8 @@ You: %1$s Message read Message sent + Message sending + Error while sending Remote audio off Add attachment