summaryrefslogtreecommitdiff
path: root/java/com/android
diff options
context:
space:
mode:
authorwangqi <wangqi@google.com>2018-03-22 14:08:28 -0700
committerCopybara-Service <copybara-piper@google.com>2018-03-26 22:15:30 -0700
commitcdae908f0a3c3754c592996df092722e1a96bde3 (patch)
tree66314443937066fcaf4a65f305daca342be5eade /java/com/android
parent57fdc2b9ab68bff217d4c9c605ef89cefd66f678 (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/com/android')
-rw-r--r--java/com/android/incallui/rtt/impl/RttChatAdapter.java58
-rw-r--r--java/com/android/incallui/rtt/impl/RttChatFragment.java24
-rw-r--r--java/com/android/incallui/rtt/impl/RttChatMessage.java116
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