From 94f4b79f94d5bb8eb20444f674bc88a758e435bc Mon Sep 17 00:00:00 2001 From: zhangxiaogang Date: Wed, 17 Nov 2021 23:39:51 +1300 Subject: [PATCH] translation ui changes for message chat view and conversation list view --- .../easeui/modules/chat/EaseChatLayout.java | 63 +++++++++++++++++- .../chat/EaseChatMessageListLayout.java | 61 +++++++++++++++++ .../EaseChatMessagePresenterImpl.java | 13 ++++ .../EaseConversationPresenterImpl.java | 3 + .../modules/menu/EasePopupWindowHelper.java | 6 +- .../widget/chatrow/EaseChatRowText.java | 38 ++++++++++- .../drawable-xhdpi/translation_failure.png | Bin 0 -> 3316 bytes .../drawable-xhdpi/translation_success.png | Bin 0 -> 11561 bytes .../res/layout/ease_row_received_message.xml | 32 +++++++++ .../main/res/layout/ease_row_sent_message.xml | 29 ++++++++ ease-im-kit/src/main/res/values/ease_ids.xml | 6 ++ .../src/main/res/values/ease_strings.xml | 4 ++ 12 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 ease-im-kit/src/main/res/drawable-xhdpi/translation_failure.png create mode 100644 ease-im-kit/src/main/res/drawable-xhdpi/translation_success.png diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatLayout.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatLayout.java index ea08d835..5675095a 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatLayout.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatLayout.java @@ -1,9 +1,11 @@ package com.hyphenate.easeui.modules.chat; import android.app.Activity; +import android.app.AlertDialog; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.content.DialogInterface; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -53,6 +55,9 @@ import com.hyphenate.easeui.modules.menu.EasePopupWindow; import com.hyphenate.easeui.modules.menu.EasePopupWindowHelper; import com.hyphenate.easeui.modules.menu.MenuItemBean; +import com.hyphenate.chat.translator.EMTranslationManager; +import com.hyphenate.chat.translator.EMTranslationMessage; +import com.hyphenate.chat.translator.EMTranslationResult; import com.hyphenate.easeui.utils.EaseCommonUtils; import com.hyphenate.easeui.utils.EaseUserUtils; import com.hyphenate.easeui.widget.EaseAlertDialog; @@ -137,6 +142,12 @@ public class EaseChatLayout extends RelativeLayout implements IChatLayout, IHand */ private boolean isNotFirstSend; + /** + * 翻译目标语言,默认英文 + */ + + private String targetLanguageCode = "en"; + public EaseChatLayout(Context context) { this(context, null); } @@ -252,6 +263,10 @@ public void loadData(String msgId) { messageListLayout.loadData(msgId); } + public void setTargetLanguageCode(String lanugageCode) { + targetLanguageCode = lanugageCode; + } + private void initTypingHandler() { typingHandler = new Handler() { @Override @@ -948,7 +963,21 @@ public boolean onMenuItemClick(MenuItemBean item) { EMLog.i(TAG,"currentMsgId = "+message.getMsgId() + " timestamp = "+message.getMsgTime()); }else if(itemId == R.id.action_chat_recall) { recallMessage(message); + }else if(itemId == R.id.action_chat_translate) { + messageListLayout.translateMessage(message, targetLanguageCode); + }else if(itemId == R.id.action_chat_reTranslate) { + new AlertDialog.Builder(getContext()) + .setTitle("Using Translate") + .setMessage("Each translation can be retranslated only once. The translation provided is for reference only.") + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + messageListLayout.reTranslate(message, targetLanguageCode); + } + }).show(); + }else if(itemId == R.id.action_chat_hide) { + messageListLayout.hideMessage(message); } + return true; } return false; @@ -965,15 +994,45 @@ public void onDismiss(PopupWindow menu) { menuHelper.show(this, v); } + private boolean showTranslation(EMMessage message) { + if(!EMTranslationManager.getInstance().isInitialized()) + return false; + + if(!EMTranslationManager.getInstance().isTranslationPresentForMessage(message.getMsgId())) + return true; + + EMTranslationResult result = EMTranslationManager.getInstance().getTranslationMessage(message.getMsgId()); + if(result.getShowTranslation()) + return false; + + return true; + } + private void setMenuByMsgType(EMMessage message) { EMMessage.Type type = message.getType(); menuHelper.findItemVisible(R.id.action_chat_copy, false); menuHelper.findItemVisible(R.id.action_chat_recall, false); + menuHelper.findItemVisible(R.id.action_chat_translate, false); + menuHelper.findItemVisible(R.id.action_chat_reTranslate, false); + menuHelper.findItemVisible(R.id.action_chat_hide, false); + menuHelper.findItem(R.id.action_chat_delete).setTitle(getContext().getString(R.string.action_delete)); switch (type) { case TXT: - menuHelper.findItemVisible(R.id.action_chat_copy, true); - menuHelper.findItemVisible(R.id.action_chat_recall, true); + if(message instanceof EMTranslationMessage) { + menuHelper.findItemVisible(R.id.action_chat_delete, false); + + if(((EMTranslationMessage) message).isReTranslatable()) + menuHelper.findItemVisible(R.id.action_chat_reTranslate, true); + + menuHelper.findItemVisible(R.id.action_chat_hide, true); + } else { + menuHelper.findItemVisible(R.id.action_chat_copy, true); + menuHelper.findItemVisible(R.id.action_chat_recall, true); + + if (showTranslation(message)) + menuHelper.findItemVisible(R.id.action_chat_translate, true); + } break; case LOCATION: case FILE: diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatMessageListLayout.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatMessageListLayout.java index 82a4cafa..dcd8eaaf 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatMessageListLayout.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/EaseChatMessageListLayout.java @@ -19,10 +19,12 @@ import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import com.hyphenate.EMValueCallBack; import com.hyphenate.chat.EMChatRoom; import com.hyphenate.chat.EMClient; import com.hyphenate.chat.EMConversation; import com.hyphenate.chat.EMMessage; +import com.hyphenate.chat.EMTextMessageBody; import com.hyphenate.easeui.R; import com.hyphenate.easeui.adapter.EaseMessageAdapter; import com.hyphenate.easeui.interfaces.MessageListItemClickListener; @@ -36,6 +38,9 @@ import com.hyphenate.easeui.modules.chat.presenter.EaseChatMessagePresenter; import com.hyphenate.easeui.modules.chat.presenter.EaseChatMessagePresenterImpl; import com.hyphenate.easeui.modules.chat.presenter.IChatMessageListView; +import com.hyphenate.chat.translator.EMTranslationManager; +import com.hyphenate.chat.translator.EMTranslationMessage; +import com.hyphenate.chat.translator.EMTranslationResult; import com.hyphenate.easeui.utils.EaseCommonUtils; import java.util.List; @@ -602,6 +607,7 @@ public void removeMessage(EMMessage message) { return; } conversation.removeMessage(message.getMsgId()); + EMTranslationManager.getInstance().removeTranslationByMsgId(message.getMsgId()); runOnUi(()-> { if(presenter.isActive()) { List messages = messageAdapter.getData(); @@ -746,6 +752,61 @@ public void removeRVItemDecoration(@NonNull RecyclerView.ItemDecoration decor) { rvList.removeItemDecoration(decor); } + public void translateMessage(EMMessage message, String languageCode) { + EMTextMessageBody body = (EMTextMessageBody) message.getBody(); + if(body == null) + return; + + EMTranslationManager.getInstance().translate(message.getMsgId(), + message.conversationId(), + body.getMessage(), + languageCode, + new EMValueCallBack() { + @Override + public void onSuccess(EMTranslationResult result) { + if(message == null || messageAdapter.getData() == null) { + return; + } + runOnUi(()-> { + if(presenter.isActive()) { + List messages = messageAdapter.getData(); + int position = messages.lastIndexOf(message); + if(position != -1) { + EMTranslationMessage translationMessage = EMTranslationMessage.createMessage(message, result); + message.setSubMessage(translationMessage); + messageAdapter.notifyItemChanged(position); + } + } + }); + } + @Override + public void onError(int errorCode, String errorText) { + //not used here + } + }); + } + + public void hideMessage(EMMessage message) { + EMTranslationMessage translationMessage = (EMTranslationMessage) message; + EMMessage parent = translationMessage.getParent(); + translationMessage.hide(); + parent.setSubMessage(null); + + int position = messageAdapter.getData().lastIndexOf(parent); + if(position != -1) { + messageAdapter.notifyItemChanged(position); + } + + } + + public void reTranslate(EMMessage message, String languageCode) { + EMTranslationMessage translationMessage = (EMTranslationMessage) message; + EMMessage parent = translationMessage.getParent(); + translationMessage.clearParent();; + parent.setSubMessage(null); + translateMessage(parent, languageCode); + } + /** * 是否有新的消息 * 判断依据为:数据库中最新的一条数据的时间戳是否大于页面上的最新一条数据的时间戳 diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/presenter/EaseChatMessagePresenterImpl.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/presenter/EaseChatMessagePresenterImpl.java index 3831b1f8..c203574e 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/presenter/EaseChatMessagePresenterImpl.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/chat/presenter/EaseChatMessagePresenterImpl.java @@ -8,6 +8,9 @@ import com.hyphenate.chat.EMConversation; import com.hyphenate.chat.EMCursorResult; import com.hyphenate.chat.EMMessage; +import com.hyphenate.chat.translator.EMTranslationManager; +import com.hyphenate.chat.translator.EMTranslationMessage; +import com.hyphenate.chat.translator.EMTranslationResult; import java.util.List; @@ -215,16 +218,26 @@ public boolean isMessageId(String msgId) { /** * Check message's status, if is not success or fail, set to {@link com.hyphenate.chat.EMMessage.Status#FAIL} + * Also add translation messages if avaliable * @param messages */ private void checkMessageStatus(List messages) { if(messages == null || messages.isEmpty()) { return; } + for (EMMessage message : messages) { if(message.status() != EMMessage.Status.SUCCESS && message.status() != EMMessage.Status.FAIL) { message.setStatus(EMMessage.Status.FAIL); } + + if(EMTranslationManager.getInstance().isTranslationPresentForMessage(message.getMsgId())) { + EMTranslationResult result = EMTranslationManager.getInstance().getTranslationMessage(message.getMsgId()); + if(result.getShowTranslation()) { + EMTranslationMessage translationMessage = EMTranslationMessage.createMessage(message, result); + message.setSubMessage(translationMessage); + } + } } } } diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/conversation/presenter/EaseConversationPresenterImpl.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/conversation/presenter/EaseConversationPresenterImpl.java index adbf9043..4d03a8fe 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/conversation/presenter/EaseConversationPresenterImpl.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/conversation/presenter/EaseConversationPresenterImpl.java @@ -4,6 +4,8 @@ import com.hyphenate.chat.EMClient; import com.hyphenate.chat.EMConversation; +import com.hyphenate.chat.translator.EMTranslationManager; +import com.hyphenate.chat.translator.EMTranslationResult; import com.hyphenate.easeui.constants.EaseConstant; import com.hyphenate.easeui.modules.conversation.model.EaseConversationInfo; import com.hyphenate.easeui.utils.EaseCommonUtils; @@ -170,6 +172,7 @@ public void deleteConversation(int position, EaseConversationInfo info) { if(!isDestroy()) { if(isDelete) { mView.deleteItem(position); + EMTranslationManager.getInstance().removeTranslationByConversationId(((EMConversation) info.getInfo()).conversationId()); }else { mView.deleteItemFail(position, ""); } diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/menu/EasePopupWindowHelper.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/menu/EasePopupWindowHelper.java index b50b35db..d7e78a11 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/menu/EasePopupWindowHelper.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/modules/menu/EasePopupWindowHelper.java @@ -30,9 +30,9 @@ import java.util.Map; public class EasePopupWindowHelper { - private static final int[] itemIds = {R.id.action_chat_copy, R.id.action_chat_delete, R.id.action_chat_recall}; - private static final int[] titles = {R.string.action_copy, R.string.action_delete, R.string.action_recall}; - private static final int[] icons = {R.drawable.ease_chat_item_menu_copy, R.drawable.ease_chat_item_menu_delete, R.drawable.ease_chat_item_menu_recall}; + private static final int[] itemIds = {R.id.action_chat_copy, R.id.action_chat_delete, R.id.action_chat_recall, R.id.action_chat_translate, R.id.action_chat_reTranslate, R.id.action_chat_hide}; + private static final int[] titles = {R.string.action_copy, R.string.action_delete, R.string.action_recall, R.string.action_translate, R.string.action_reTranslate, R.string.action_hide }; + private static final int[] icons = {R.drawable.ease_chat_item_menu_copy, R.drawable.ease_chat_item_menu_delete, R.drawable.ease_chat_item_menu_recall, R.drawable.ease_chat_item_menu_recall, R.drawable.ease_chat_item_menu_recall, R.drawable.ease_chat_item_menu_recall}; private static final int SPAN_COUNT = 5; private EasePopupWindow pMenu; private List menuItems = new ArrayList<>(); diff --git a/ease-im-kit/src/main/java/com/hyphenate/easeui/widget/chatrow/EaseChatRowText.java b/ease-im-kit/src/main/java/com/hyphenate/easeui/widget/chatrow/EaseChatRowText.java index 1780a94f..a62451fd 100644 --- a/ease-im-kit/src/main/java/com/hyphenate/easeui/widget/chatrow/EaseChatRowText.java +++ b/ease-im-kit/src/main/java/com/hyphenate/easeui/widget/chatrow/EaseChatRowText.java @@ -5,6 +5,7 @@ import android.text.Spanned; import android.text.style.URLSpan; import android.view.View; +import android.widget.ImageView; import android.widget.TextView; import android.widget.TextView.BufferType; @@ -12,10 +13,16 @@ import com.hyphenate.chat.EMTextMessageBody; import com.hyphenate.easeui.R; import com.hyphenate.easeui.manager.EaseDingMessageHelper; +import com.hyphenate.chat.translator.EMTranslationMessage; +import com.hyphenate.chat.translator.EMTranslationResult; import com.hyphenate.easeui.utils.EaseSmileUtils; public class EaseChatRowText extends EaseChatRow { private TextView contentView; + private TextView translationContentView; + private ImageView translationStatusView; + private View translationContainer; + public EaseChatRowText(Context context, boolean isSender) { super(context, isSender); @@ -27,13 +34,16 @@ public EaseChatRowText(Context context, EMMessage message, int position, Object @Override protected void onInflateView() { - inflater.inflate(!showSenderType ? R.layout.ease_row_received_message + inflater.inflate(!showSenderType ? R.layout.ease_row_received_message : R.layout.ease_row_sent_message, this); } @Override protected void onFindViewById() { - contentView = (TextView) findViewById(R.id.tv_chatcontent); + contentView = (TextView) findViewById(R.id.tv_chatcontent); + translationContentView = (TextView) findViewById(R.id.tv_subContent); + translationStatusView = (ImageView) findViewById(R.id.translation_status); + translationContainer = (View) findViewById(R.id.subBubble); } @Override @@ -53,7 +63,31 @@ public boolean onLongClick(View v) { return false; } }); + replaceSpan(); + + if(message.subMessage() != null) { + translationContainer.setVisibility(View.VISIBLE); + EMTranslationResult result = ((EMTranslationMessage)message.subMessage()).getTranslationResult(); + translationContentView.setText(result.getTranslatedText()); + translationContentView.setOnLongClickListener(new OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + contentView.setTag(R.id.action_chat_long_click,true); + if (itemClickListener != null) { + return itemClickListener.onBubbleLongClick(v, message.subMessage()); + } + return false; + } + }); + if(result.isSuccess()) + translationStatusView.setImageResource(R.drawable.translation_success); + else + translationStatusView.setImageResource(R.drawable.translation_failure); + } else { + translationContainer.setVisibility(View.GONE); + } + } } diff --git a/ease-im-kit/src/main/res/drawable-xhdpi/translation_failure.png b/ease-im-kit/src/main/res/drawable-xhdpi/translation_failure.png new file mode 100644 index 0000000000000000000000000000000000000000..945deb0e64acd85f7100ad46834b8570f07103b4 GIT binary patch literal 3316 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 Dr1ah6 literal 0 HcmV?d00001 diff --git a/ease-im-kit/src/main/res/drawable-xhdpi/translation_success.png b/ease-im-kit/src/main/res/drawable-xhdpi/translation_success.png new file mode 100644 index 0000000000000000000000000000000000000000..bd6db63307281527c2fb25eb5317fba70245c88a GIT binary patch literal 11561 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 + + + + + + \ No newline at end of file diff --git a/ease-im-kit/src/main/res/layout/ease_row_sent_message.xml b/ease-im-kit/src/main/res/layout/ease_row_sent_message.xml index 217535a0..974d6137 100644 --- a/ease-im-kit/src/main/res/layout/ease_row_sent_message.xml +++ b/ease-im-kit/src/main/res/layout/ease_row_sent_message.xml @@ -108,5 +108,34 @@ android:layout_toLeftOf="@id/iv_userhead" android:visibility="gone" /> + + + + + + \ No newline at end of file diff --git a/ease-im-kit/src/main/res/values/ease_ids.xml b/ease-im-kit/src/main/res/values/ease_ids.xml index ace580aa..93397073 100644 --- a/ease-im-kit/src/main/res/values/ease_ids.xml +++ b/ease-im-kit/src/main/res/values/ease_ids.xml @@ -12,6 +12,12 @@ + + + + + + diff --git a/ease-im-kit/src/main/res/values/ease_strings.xml b/ease-im-kit/src/main/res/values/ease_strings.xml index 67655f8d..545b0800 100644 --- a/ease-im-kit/src/main/res/values/ease_strings.xml +++ b/ease-im-kit/src/main/res/values/ease_strings.xml @@ -155,5 +155,9 @@ 多选 删除语音 删除视频 + 翻译 + 重译 + 隐藏 +