diff options
author | wangqi <wangqi@google.com> | 2018-03-22 14:08:28 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-03-26 22:15:30 -0700 |
commit | cdae908f0a3c3754c592996df092722e1a96bde3 (patch) | |
tree | 66314443937066fcaf4a65f305daca342be5eade /java | |
parent | 57fdc2b9ab68bff217d4c9c605ef89cefd66f678 (diff) |
Allow user to delete previous bubbles.
After this change, user will be able to delete text in previous finished bubble. It will also correctly handle deletion from remote.
Bug: 67596257
Test: RttChatMessageTest
PiperOrigin-RevId: 190122728
Change-Id: Ifebcbe874e5f03857d109b58e758e53f408e7e44
Diffstat (limited to 'java')
3 files changed, 131 insertions, 67 deletions
diff --git a/java/com/android/incallui/rtt/impl/RttChatAdapter.java b/java/com/android/incallui/rtt/impl/RttChatAdapter.java index 7e2b571c1..8d924c9f8 100644 --- a/java/com/android/incallui/rtt/impl/RttChatAdapter.java +++ b/java/com/android/incallui/rtt/impl/RttChatAdapter.java @@ -37,13 +37,11 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde } private static final String KEY_MESSAGE_DATA = "key_message_data"; - private static final String KEY_LAST_REMOTE_MESSAGE = "key_last_remote_message"; private static final String KEY_LAST_LOCAL_MESSAGE = "key_last_local_message"; private final Context context; private final List<RttChatMessage> rttMessages; private int lastIndexOfLocalMessage = -1; - private int lastIndexOfRemoteMessage = -1; private final MessageListener messageListener; RttChatAdapter(Context context, MessageListener listener, @Nullable Bundle savedInstanceState) { @@ -53,7 +51,6 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde rttMessages = new ArrayList<>(); } else { rttMessages = savedInstanceState.getParcelableArrayList(KEY_MESSAGE_DATA); - lastIndexOfRemoteMessage = savedInstanceState.getInt(KEY_LAST_REMOTE_MESSAGE); lastIndexOfLocalMessage = savedInstanceState.getInt(KEY_LAST_LOCAL_MESSAGE); } } @@ -84,33 +81,6 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde return rttMessages.size(); } - private void updateCurrentRemoteMessage(String newText) { - RttChatMessage rttChatMessage = null; - if (lastIndexOfRemoteMessage >= 0) { - rttChatMessage = rttMessages.get(lastIndexOfRemoteMessage); - } - List<RttChatMessage> newMessages = - RttChatMessage.getRemoteRttChatMessage(rttChatMessage, newText); - - if (rttChatMessage == null) { - lastIndexOfRemoteMessage = rttMessages.size(); - rttMessages.add(lastIndexOfRemoteMessage, newMessages.get(0)); - rttMessages.addAll(newMessages.subList(1, newMessages.size())); - notifyItemRangeInserted(lastIndexOfRemoteMessage, newMessages.size()); - lastIndexOfRemoteMessage = rttMessages.size() - 1; - } else { - rttMessages.set(lastIndexOfRemoteMessage, newMessages.get(0)); - int lastIndex = rttMessages.size(); - rttMessages.addAll(newMessages.subList(1, newMessages.size())); - - notifyItemChanged(lastIndexOfRemoteMessage); - notifyItemRangeInserted(lastIndex, newMessages.size()); - } - if (rttMessages.get(lastIndexOfRemoteMessage).isFinished()) { - lastIndexOfRemoteMessage = -1; - } - } - private void updateCurrentLocalMessage(String newMessage) { RttChatMessage rttChatMessage = null; if (lastIndexOfLocalMessage >= 0) { @@ -128,9 +98,6 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde if (TextUtils.isEmpty(rttChatMessage.getContent())) { rttMessages.remove(lastIndexOfLocalMessage); notifyItemRemoved(lastIndexOfLocalMessage); - if (lastIndexOfRemoteMessage > lastIndexOfLocalMessage) { - lastIndexOfRemoteMessage -= 1; - } lastIndexOfLocalMessage = -1; } else { notifyItemChanged(lastIndexOfLocalMessage); @@ -138,8 +105,13 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde } } + private void updateCurrentRemoteMessage(String newMessage) { + RttChatMessage.updateRemoteRttChatMessage(rttMessages, newMessage); + lastIndexOfLocalMessage = RttChatMessage.getLastIndexLocalMessage(rttMessages); + notifyDataSetChanged(); + } + void addLocalMessage(String message) { - LogUtil.enterBlock("RttChatAdapater.addLocalMessage"); updateCurrentLocalMessage(message); if (messageListener != null) { messageListener.newMessageAdded(); @@ -166,7 +138,6 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde } void addRemoteMessage(String message) { - LogUtil.enterBlock("RttChatAdapater.addRemoteMessage"); if (TextUtils.isEmpty(message)) { return; } @@ -176,9 +147,24 @@ public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolde } } + /** + * Retrieve last local message and update the index. This is used when deleting to previous + * message bubble. + */ + @Nullable + String retrieveLastLocalMessage() { + lastIndexOfLocalMessage = RttChatMessage.getLastIndexLocalMessage(rttMessages); + if (lastIndexOfLocalMessage >= 0) { + RttChatMessage rttChatMessage = rttMessages.get(lastIndexOfLocalMessage); + rttChatMessage.unfinish(); + return rttChatMessage.getContent(); + } else { + return null; + } + } + void onSaveInstanceState(@NonNull Bundle bundle) { bundle.putParcelableArrayList(KEY_MESSAGE_DATA, (ArrayList<RttChatMessage>) rttMessages); - bundle.putInt(KEY_LAST_REMOTE_MESSAGE, lastIndexOfRemoteMessage); bundle.putInt(KEY_LAST_LOCAL_MESSAGE, lastIndexOfLocalMessage); } } diff --git a/java/com/android/incallui/rtt/impl/RttChatFragment.java b/java/com/android/incallui/rtt/impl/RttChatFragment.java index 90bf199b2..e14ee9b06 100644 --- a/java/com/android/incallui/rtt/impl/RttChatFragment.java +++ b/java/com/android/incallui/rtt/impl/RttChatFragment.java @@ -164,6 +164,26 @@ public class RttChatFragment extends Fragment editText = view.findViewById(R.id.rtt_chat_input); editText.setOnEditorActionListener(this); editText.addTextChangedListener(this); + + editText.setOnKeyListener( + (v, keyCode, event) -> { + // This is only triggered when input method doesn't handle delete key, which means the + // current + // input box is empty. + if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) { + String lastMessage = adapter.retrieveLastLocalMessage(); + if (lastMessage != null) { + isClearingInput = true; + editText.setText(lastMessage); + editText.setSelection(lastMessage.length()); + isClearingInput = false; + rttCallScreenDelegate.onLocalMessage("\b"); + return true; + } + return false; + } + return false; + }); recyclerView = view.findViewById(R.id.rtt_recycler_view); LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); layoutManager.setStackFromEnd(true); @@ -207,7 +227,9 @@ public class RttChatFragment extends Fragment @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEND) { - submitButton.performClick(); + if (!TextUtils.isEmpty(editText.getText())) { + submitButton.performClick(); + } return true; } return false; diff --git a/java/com/android/incallui/rtt/impl/RttChatMessage.java b/java/com/android/incallui/rtt/impl/RttChatMessage.java index fd83fb82f..cbc53ef15 100644 --- a/java/com/android/incallui/rtt/impl/RttChatMessage.java +++ b/java/com/android/incallui/rtt/impl/RttChatMessage.java @@ -19,10 +19,9 @@ package com.android.incallui.rtt.impl; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import com.android.dialer.common.Assert; import com.android.incallui.rtt.protocol.Constants; import com.google.common.base.Splitter; -import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -44,13 +43,17 @@ final class RttChatMessage implements Parcelable { isFinished = true; } + void unfinish() { + isFinished = false; + } + public void append(String text) { for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); - if (c != '\b') { - content.append(c); - } else if (content.length() > 0) { + if (c == '\b' && content.length() > 0 && content.charAt(content.length() - 1) != '\b') { content.deleteCharAt(content.length() - 1); + } else { + content.append(c); } } } @@ -87,39 +90,92 @@ final class RttChatMessage implements Parcelable { return modify.toString(); } - /** Convert remote input text into an array of {@code RttChatMessage}. */ - static List<RttChatMessage> getRemoteRttChatMessage( - @Nullable RttChatMessage currentMessage, @NonNull String text) { + /** Update list of {@code RttChatMessage} based on given remote text. */ + static void updateRemoteRttChatMessage(List<RttChatMessage> messageList, @NonNull String text) { + Assert.isNotNull(messageList); Iterator<String> splitText = SPLITTER.split(text).iterator(); - List<RttChatMessage> messageList = new ArrayList<>(); - - String firstMessageContent = splitText.next(); - RttChatMessage firstMessage = currentMessage; - if (firstMessage == null) { - firstMessage = new RttChatMessage(); - firstMessage.isRemote = true; - } - firstMessage.append(firstMessageContent); - if (splitText.hasNext() || text.endsWith(Constants.BUBBLE_BREAKER)) { - firstMessage.finish(); - } - messageList.add(firstMessage); while (splitText.hasNext()) { String singleMessageContent = splitText.next(); - if (singleMessageContent.isEmpty()) { - continue; + RttChatMessage message; + int index = getLastIndexUnfinishedRemoteMessage(messageList); + if (index < 0) { + message = new RttChatMessage(); + message.append(singleMessageContent); + message.isRemote = true; + if (splitText.hasNext()) { + message.finish(); + } + if (message.content.length() != 0) { + messageList.add(message); + } + } else { + message = messageList.get(index); + message.append(singleMessageContent); + if (splitText.hasNext()) { + message.finish(); + } + if (message.content.length() == 0) { + messageList.remove(index); + } } - RttChatMessage message = new RttChatMessage(); - message.append(singleMessageContent); - message.isRemote = true; - if (splitText.hasNext()) { - message.finish(); + StringBuilder content = message.content; + // Delete previous messages. + while (content.length() > 0 && content.charAt(0) == '\b') { + messageList.remove(message); + content.delete(0, 1); + int previous = getLastIndexRemoteMessage(messageList); + // There are more backspaces than existing characters. + if (previous < 0) { + while (content.length() > 0 && content.charAt(0) == '\b') { + content.deleteCharAt(0); + } + // Add message if there are still characters after backspaces. + if (content.length() > 0) { + message = new RttChatMessage(); + message.append(content.toString()); + message.isRemote = true; + if (splitText.hasNext()) { + message.finish(); + } + messageList.add(message); + } + break; + } + message = messageList.get(previous); + message.unfinish(); + message.append(content.toString()); + content = message.content; } - messageList.add(message); } + if (text.endsWith(Constants.BUBBLE_BREAKER)) { + int lastIndexRemoteMessage = getLastIndexRemoteMessage(messageList); + messageList.get(lastIndexRemoteMessage).finish(); + } + } + + private static int getLastIndexUnfinishedRemoteMessage(List<RttChatMessage> messageList) { + int i = messageList.size() - 1; + while (i >= 0 && (!messageList.get(i).isRemote || messageList.get(i).isFinished)) { + i--; + } + return i; + } - return messageList; + private static int getLastIndexRemoteMessage(List<RttChatMessage> messageList) { + int i = messageList.size() - 1; + while (i >= 0 && !messageList.get(i).isRemote) { + i--; + } + return i; + } + + static int getLastIndexLocalMessage(List<RttChatMessage> messageList) { + int i = messageList.size() - 1; + while (i >= 0 && messageList.get(i).isRemote) { + i--; + } + return i; } @Override |