1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.incallui.rtt.impl; 18 19 import android.content.Context; 20 import android.support.v7.widget.RecyclerView; 21 import android.text.TextUtils; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.view.ViewGroup; 25 import com.android.dialer.common.LogUtil; 26 import java.util.ArrayList; 27 import java.util.Arrays; 28 import java.util.List; 29 30 /** Adapter class for holding RTT chat data. */ 31 public class RttChatAdapter extends RecyclerView.Adapter<RttChatMessageViewHolder> { 32 33 interface MessageListener { newMessageAdded()34 void newMessageAdded(); 35 } 36 37 private final Context context; 38 private final List<RttChatMessage> rttMessages = new ArrayList<>(); 39 private int lastIndexOfLocalMessage = -1; 40 private int lastIndexOfRemoteMessage = -1; 41 private final MessageListener messageListener; 42 RttChatAdapter(Context context, MessageListener listener)43 RttChatAdapter(Context context, MessageListener listener) { 44 this.context = context; 45 this.messageListener = listener; 46 } 47 48 @Override onCreateViewHolder(ViewGroup parent, int viewType)49 public RttChatMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 50 LayoutInflater layoutInflater = LayoutInflater.from(context); 51 View view = layoutInflater.inflate(R.layout.rtt_chat_list_item, parent, false); 52 return new RttChatMessageViewHolder(view); 53 } 54 55 @Override getItemViewType(int position)56 public int getItemViewType(int position) { 57 return super.getItemViewType(position); 58 } 59 60 @Override onBindViewHolder(RttChatMessageViewHolder rttChatMessageViewHolder, int i)61 public void onBindViewHolder(RttChatMessageViewHolder rttChatMessageViewHolder, int i) { 62 boolean isSameGroup = false; 63 if (i > 0) { 64 isSameGroup = rttMessages.get(i).isRemote == rttMessages.get(i - 1).isRemote; 65 } 66 rttChatMessageViewHolder.setMessage(rttMessages.get(i), isSameGroup); 67 } 68 69 @Override getItemCount()70 public int getItemCount() { 71 return rttMessages.size(); 72 } 73 updateCurrentRemoteMessage(String newText)74 private void updateCurrentRemoteMessage(String newText) { 75 RttChatMessage rttChatMessage = null; 76 if (lastIndexOfRemoteMessage >= 0) { 77 rttChatMessage = rttMessages.get(lastIndexOfRemoteMessage); 78 } 79 RttChatMessage[] newMessages = RttChatMessage.getRemoteRttChatMessage(rttChatMessage, newText); 80 81 if (rttChatMessage == null) { 82 lastIndexOfRemoteMessage = rttMessages.size(); 83 rttMessages.add(lastIndexOfRemoteMessage, newMessages[0]); 84 rttMessages.addAll(Arrays.asList(newMessages).subList(1, newMessages.length)); 85 notifyItemRangeInserted(lastIndexOfRemoteMessage, newMessages.length); 86 lastIndexOfRemoteMessage = rttMessages.size() - 1; 87 } else { 88 rttMessages.set(lastIndexOfRemoteMessage, newMessages[0]); 89 int lastIndex = rttMessages.size(); 90 rttMessages.addAll(Arrays.asList(newMessages).subList(1, newMessages.length)); 91 92 notifyItemChanged(lastIndexOfRemoteMessage); 93 notifyItemRangeInserted(lastIndex, newMessages.length); 94 } 95 if (rttMessages.get(lastIndexOfRemoteMessage).isFinished()) { 96 lastIndexOfRemoteMessage = -1; 97 } 98 } 99 updateCurrentLocalMessage(String newMessage)100 private void updateCurrentLocalMessage(String newMessage) { 101 RttChatMessage rttChatMessage = null; 102 if (lastIndexOfLocalMessage >= 0) { 103 rttChatMessage = rttMessages.get(lastIndexOfLocalMessage); 104 } 105 if (rttChatMessage == null || rttChatMessage.isFinished()) { 106 rttChatMessage = new RttChatMessage(); 107 rttChatMessage.append(newMessage); 108 rttMessages.add(rttChatMessage); 109 lastIndexOfLocalMessage = rttMessages.size() - 1; 110 notifyItemInserted(lastIndexOfLocalMessage); 111 } else { 112 rttChatMessage.append(newMessage); 113 // Clear empty message bubble. 114 if (TextUtils.isEmpty(rttChatMessage.getContent())) { 115 rttMessages.remove(lastIndexOfLocalMessage); 116 notifyItemRemoved(lastIndexOfLocalMessage); 117 if (lastIndexOfRemoteMessage > lastIndexOfLocalMessage) { 118 lastIndexOfRemoteMessage -= 1; 119 } 120 lastIndexOfLocalMessage = -1; 121 } else { 122 notifyItemChanged(lastIndexOfLocalMessage); 123 } 124 } 125 } 126 addLocalMessage(String message)127 void addLocalMessage(String message) { 128 LogUtil.enterBlock("RttChatAdapater.addLocalMessage"); 129 updateCurrentLocalMessage(message); 130 if (messageListener != null) { 131 messageListener.newMessageAdded(); 132 } 133 } 134 submitLocalMessage()135 void submitLocalMessage() { 136 LogUtil.enterBlock("RttChatAdapater.submitLocalMessage"); 137 rttMessages.get(lastIndexOfLocalMessage).finish(); 138 notifyItemChanged(lastIndexOfLocalMessage); 139 lastIndexOfLocalMessage = -1; 140 } 141 addRemoteMessage(String message)142 void addRemoteMessage(String message) { 143 LogUtil.enterBlock("RttChatAdapater.addRemoteMessage"); 144 if (TextUtils.isEmpty(message)) { 145 return; 146 } 147 updateCurrentRemoteMessage(message); 148 if (messageListener != null) { 149 messageListener.newMessageAdded(); 150 } 151 } 152 } 153