Improved chat messages performances
This commit is contained in:
parent
389d3177ec
commit
5ed2e63ca0
5 changed files with 111 additions and 78 deletions
|
@ -116,8 +116,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
private BubbleChat lastSentMessageBubble;
|
||||
private HashMap<Integer, String> latestImageMessages;
|
||||
private int messagesFilterLimit = 0;
|
||||
private List<ChatMessage> messagesList;
|
||||
private boolean useLinphoneMessageStorage;
|
||||
private boolean messagesArePresentButHidden = false;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
private int bytesSent;
|
||||
|
@ -239,10 +239,6 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
return view;
|
||||
}
|
||||
|
||||
private void refreshMessages() {
|
||||
messagesList = LinphoneActivity.instance().getChatMessages(sipUri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
outState.putString("fileToUploadPath", fileToUploadPath);
|
||||
|
@ -286,52 +282,46 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
private void invalidate() {
|
||||
refreshMessages();
|
||||
messagesFilterLimit += MESSAGES_STEP;
|
||||
|
||||
if (messagesFilterLimit == 0) {
|
||||
if (messagesList.size() > MESSAGES_STEP)
|
||||
messagesFilterLimit = MESSAGES_STEP;
|
||||
else
|
||||
messagesFilterLimit = messagesList.size();
|
||||
} else {
|
||||
if (messagesFilterLimit + MESSAGES_STEP <= messagesList.size())
|
||||
messagesFilterLimit += MESSAGES_STEP;
|
||||
else
|
||||
messagesFilterLimit = messagesList.size();
|
||||
if (!messagesArePresentButHidden) {
|
||||
LinphoneChatMessage[] history = chatRoom.getHistory();
|
||||
for (int i = 0; i < history.length; i++) {
|
||||
LinphoneChatMessage msg = history[i];
|
||||
if (msg.getExternalBodyUrl() != null) {
|
||||
Bitmap bm = BitmapFactory.decodeFile(msg.getExternalBodyUrl());
|
||||
displayImageMessage(msg.getStorageId(), bm, msg.getTime(), !msg.isOutgoing(), msg.getStatus(), messagesLayout, msg.getExternalBodyUrl(), i >= history.length - messagesFilterLimit);
|
||||
} else {
|
||||
displayMessage(msg.getStorageId(), msg.getText(), msg.getTime(), !msg.isOutgoing(), msg.getStatus(), messagesLayout, i >= history.length - messagesFilterLimit);
|
||||
}
|
||||
}
|
||||
messagesArePresentButHidden = true;
|
||||
}
|
||||
|
||||
invalidate(messagesFilterLimit);
|
||||
}
|
||||
|
||||
private void invalidate(final int limit) {
|
||||
messagesLayout.removeAllViews();
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
previousMessageID = -1;
|
||||
ChatStorage chatStorage = LinphoneActivity.instance().getChatStorage();
|
||||
int start = messagesLayout.getChildCount() - messagesFilterLimit;
|
||||
if (start < 0)
|
||||
start = 0;
|
||||
|
||||
for (int i = messagesList.size() - limit; i < messagesList.size(); i++) {
|
||||
ChatMessage msg = messagesList.get(i);
|
||||
if (msg.getMessage() != null && msg.getMessage().length() > 0) {
|
||||
displayMessage(msg.getId(), msg.getMessage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout);
|
||||
} else {
|
||||
displayImageMessage(msg.getId(), msg.getImage(), msg.getTimestamp(), msg.isIncoming(), msg.getStatus(), messagesLayout, msg.getUrl());
|
||||
}
|
||||
|
||||
if (!msg.isRead()) {
|
||||
// Only works if not using liblinphone storage
|
||||
chatStorage.markMessageAsRead(msg.getId());
|
||||
}
|
||||
}
|
||||
LinphoneActivity.instance().updateMissedChatCount();
|
||||
for (int i = start; i < messagesLayout.getChildCount(); i++) {
|
||||
messagesLayout.getChildAt(i).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
LinphoneActivity.instance().updateMissedChatCount();
|
||||
|
||||
if (limit < messagesList.size()) {
|
||||
messagesScrollView.setScrollViewListener(new ScrollViewListener() {
|
||||
@Override
|
||||
if (start != 0) {
|
||||
messagesScrollView.setScrollViewListener(new ScrollViewListener() {
|
||||
@Override
|
||||
public void OnScrollToTop(final int previousHeight) {
|
||||
invalidate();mHandler.postDelayed(new Runnable() {
|
||||
invalidate();
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//Scroll to latest saw message
|
||||
|
@ -341,9 +331,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}, 300);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
messagesScrollView.setScrollViewListener(null);
|
||||
}
|
||||
} else {
|
||||
messagesScrollView.setScrollViewListener(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -379,7 +369,11 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
return id;
|
||||
}
|
||||
|
||||
private void displayMessage(int id, String message, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout) {
|
||||
private void displayMessage(int id, String message, long time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout) {
|
||||
displayMessage(id, message, time, isIncoming, status, layout, true);
|
||||
}
|
||||
|
||||
private void displayMessage(int id, String message, long time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout, boolean show) {
|
||||
id = checkId(id);
|
||||
BubbleChat bubble = new BubbleChat(layout.getContext(), id, message, null, time, isIncoming, status, previousMessageID);
|
||||
if (!isIncoming) {
|
||||
|
@ -387,12 +381,19 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
View v = bubble.getView();
|
||||
|
||||
if (!show)
|
||||
v.setVisibility(View.GONE);
|
||||
|
||||
previousMessageID = id;
|
||||
layout.addView(v);
|
||||
registerForContextMenu(v);
|
||||
}
|
||||
private void displayImageMessage(int id, Bitmap image, long time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout, final String url) {
|
||||
displayImageMessage(id, image, time, isIncoming, status, layout, url, true);
|
||||
}
|
||||
|
||||
private void displayImageMessage(int id, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout, final String url) {
|
||||
private void displayImageMessage(int id, Bitmap image, long time, boolean isIncoming, LinphoneChatMessage.State status, RelativeLayout layout, final String url, boolean show) {
|
||||
id = checkId(id);
|
||||
BubbleChat bubble = new BubbleChat(layout.getContext(), id, null, image, time, isIncoming, status, previousMessageID);
|
||||
if (!isIncoming) {
|
||||
|
@ -435,6 +436,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
});
|
||||
|
||||
if (!show)
|
||||
v.setVisibility(View.GONE);
|
||||
|
||||
previousMessageID = id;
|
||||
layout.addView(v);
|
||||
registerForContextMenu(v);
|
||||
|
@ -489,7 +493,13 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
switch (item.getItemId()) {
|
||||
case MENU_DELETE_MESSAGE:
|
||||
LinphoneActivity.instance().getChatStorage().deleteMessage(chatRoom, item.getGroupId());
|
||||
invalidate();
|
||||
for (int i = 0; i < messagesLayout.getChildCount(); i++) {
|
||||
View v = messagesLayout.getChildAt(i);
|
||||
if (v.getId() == item.getGroupId()) {
|
||||
v.setVisibility(View.GONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MENU_SAVE_PICTURE:
|
||||
saveImage(item.getGroupId());
|
||||
|
@ -576,7 +586,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
newId = LinphoneActivity.instance().onMessageSent(sipUri, messageToSend);
|
||||
}
|
||||
|
||||
displayMessage(newId, messageToSend, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout);
|
||||
displayMessage(newId, messageToSend, System.currentTimeMillis(), false, State.InProgress, messagesLayout);
|
||||
scrollToEnd();
|
||||
} else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().displayCustomToast(getString(R.string.error_network_unreachable), Toast.LENGTH_LONG);
|
||||
|
@ -602,7 +612,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
if (useLinphoneMessageStorage)
|
||||
saveImage(bitmap, newId, chatMessage);
|
||||
|
||||
displayImageMessage(newId, bitmap, String.valueOf(System.currentTimeMillis()), false, State.InProgress, messagesLayout, url);
|
||||
displayImageMessage(newId, bitmap, System.currentTimeMillis(), false, State.InProgress, messagesLayout, url);
|
||||
scrollToEnd();
|
||||
} else if (!isNetworkReachable && LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().displayCustomToast(getString(R.string.error_network_unreachable), Toast.LENGTH_LONG);
|
||||
|
@ -632,7 +642,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
displayMessage(id, message.getText(), String.valueOf(message.getTime()), true, null, messagesLayout);
|
||||
displayMessage(id, message.getText(), message.getTime(), true, null, messagesLayout);
|
||||
}
|
||||
});
|
||||
} else if (message.getExternalBodyUrl() != null) {
|
||||
|
@ -647,7 +657,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
displayImageMessage(id, fbm, String.valueOf(message.getTime()), true, null, messagesLayout, fbm == null ? "" : message.getExternalBodyUrl());
|
||||
displayImageMessage(id, fbm, message.getTime(), true, null, messagesLayout, fbm == null ? "" : message.getExternalBodyUrl());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
private ImageView clearFastChat;
|
||||
private EditText fastNewChat;
|
||||
private boolean isEditMode = false;
|
||||
private boolean useLinphoneStorage;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
|
@ -104,7 +105,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
} else {
|
||||
noChatHistory.setVisibility(View.GONE);
|
||||
chatList.setVisibility(View.VISIBLE);
|
||||
chatList.setAdapter(new ChatListAdapter());
|
||||
chatList.setAdapter(new ChatListAdapter(useLinphoneStorage));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +126,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
super.onResume();
|
||||
|
||||
//Check if the is the first time we show the chat view since we use liblinphone chat storage
|
||||
boolean useLinphoneStorage = getResources().getBoolean(R.bool.use_linphone_chat_storage);
|
||||
useLinphoneStorage = getResources().getBoolean(R.bool.use_linphone_chat_storage);
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(LinphoneActivity.instance());
|
||||
boolean updateNeeded = prefs.getBoolean(getString(R.string.pref_first_time_linphone_chat_storage), true);
|
||||
if (useLinphoneStorage && updateNeeded) {
|
||||
|
@ -256,7 +257,7 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
String correspondent = conversations.get(j);
|
||||
LinphoneChatRoom room = LinphoneManager.getLc().getOrCreateChatRoom(correspondent);
|
||||
for (ChatMessage message : db.getMessages(correspondent)) {
|
||||
LinphoneChatMessage msg = room.createLinphoneChatMessage(message.getMessage(), message.getUrl(), message.getStatus(), Long.parseLong(message.getTimestamp()), message.isRead(), message.isIncoming());
|
||||
LinphoneChatMessage msg = room.createLinphoneChatMessage(message.getMessage(), message.getUrl(), message.getStatus(), Long.parseLong(message.getTimestamp()), true, message.isIncoming());
|
||||
if (message.getImage() != null) {
|
||||
String path = saveImageAsFile(message.getId(), message.getImage());
|
||||
if (path != null)
|
||||
|
@ -301,7 +302,10 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
}
|
||||
|
||||
class ChatListAdapter extends BaseAdapter {
|
||||
ChatListAdapter() {
|
||||
private boolean useNativeAPI;
|
||||
|
||||
ChatListAdapter(boolean useNativeAPI) {
|
||||
this.useNativeAPI = useNativeAPI;
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
|
@ -345,25 +349,38 @@ public class ChatListFragment extends Fragment implements OnClickListener, OnIte
|
|||
}
|
||||
LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, view.getContext().getContentResolver());
|
||||
|
||||
List<ChatMessage> messages = LinphoneActivity.instance().getChatMessages(contact);
|
||||
if (messages != null && messages.size() > 0) {
|
||||
int iterator = messages.size() - 1;
|
||||
ChatMessage lastMessage = null;
|
||||
|
||||
while (iterator >= 0) {
|
||||
lastMessage = messages.get(iterator);
|
||||
if (lastMessage.getMessage() == null) {
|
||||
iterator--;
|
||||
} else {
|
||||
iterator = -1;
|
||||
String message = "";
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatRoom chatRoom = LinphoneManager.getLc().getOrCreateChatRoom(contact);
|
||||
LinphoneChatMessage[] history = chatRoom.getHistory(20);
|
||||
if (history != null && history.length > 0) {
|
||||
for (int i = history.length - 1; i >= 0; i--) {
|
||||
LinphoneChatMessage msg = history[i];
|
||||
if (msg.getText() != null && msg.getText().length() > 0) {
|
||||
message = msg.getText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String message = "";
|
||||
message = (lastMessage == null || lastMessage.getMessage() == null) ? "" : lastMessage.getMessage();
|
||||
TextView lastMessageView = (TextView) view.findViewById(R.id.lastMessage);
|
||||
lastMessageView.setText(message);
|
||||
} else {
|
||||
List<ChatMessage> messages = LinphoneActivity.instance().getChatMessages(contact);
|
||||
if (messages != null && messages.size() > 0) {
|
||||
int iterator = messages.size() - 1;
|
||||
ChatMessage lastMessage = null;
|
||||
|
||||
while (iterator >= 0) {
|
||||
lastMessage = messages.get(iterator);
|
||||
if (lastMessage.getMessage() == null) {
|
||||
iterator--;
|
||||
} else {
|
||||
iterator = -1;
|
||||
}
|
||||
}
|
||||
message = (lastMessage == null || lastMessage.getMessage() == null) ? "" : lastMessage.getMessage();
|
||||
}
|
||||
}
|
||||
TextView lastMessageView = (TextView) view.findViewById(R.id.lastMessage);
|
||||
lastMessageView.setText(message);
|
||||
|
||||
TextView sipUri = (TextView) view.findViewById(R.id.sipUri);
|
||||
sipUri.setSelected(true); // For animation
|
||||
|
|
|
@ -320,9 +320,11 @@ public class ChatStorage {
|
|||
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatMessage[] history = chatroom.getHistory();
|
||||
if (history.length > id-1) {
|
||||
LinphoneChatMessage msg = history[id-1];
|
||||
message = msg.getText();
|
||||
for (LinphoneChatMessage msg : history) {
|
||||
if (msg.getStorageId() == id) {
|
||||
message = msg.getText();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Cursor c = db.query(TABLE_NAME, null, "id LIKE " + id, null, null, null, null);
|
||||
|
@ -377,8 +379,12 @@ public class ChatStorage {
|
|||
public void deleteMessage(LinphoneChatRoom chatroom, int id) {
|
||||
if (useNativeAPI) {
|
||||
LinphoneChatMessage[] history = chatroom.getHistory();
|
||||
LinphoneChatMessage message = history[id-1];
|
||||
chatroom.deleteMessage(message);
|
||||
for (LinphoneChatMessage message : history) {
|
||||
if (message.getStorageId() == id) {
|
||||
chatroom.deleteMessage(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
db.delete(TABLE_NAME, "id LIKE " + id, null);
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public class BubbleChat {
|
|||
private ImageView statusView;
|
||||
private Button download;
|
||||
|
||||
public BubbleChat(Context context, int id, String message, Bitmap image, String time, boolean isIncoming, LinphoneChatMessage.State status, int previousID) {
|
||||
public BubbleChat(Context context, int id, String message, Bitmap image, long time, boolean isIncoming, LinphoneChatMessage.State status, int previousID) {
|
||||
view = new RelativeLayout(context);
|
||||
|
||||
LayoutParams layoutParams = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||
|
@ -201,10 +201,10 @@ public class BubbleChat {
|
|||
return view;
|
||||
}
|
||||
|
||||
private String timestampToHumanDate(Context context, String timestamp) {
|
||||
private String timestampToHumanDate(Context context, long timestamp) {
|
||||
try {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(Long.parseLong(timestamp));
|
||||
cal.setTimeInMillis(timestamp);
|
||||
|
||||
SimpleDateFormat dateFormat;
|
||||
if (isToday(cal)) {
|
||||
|
@ -215,7 +215,7 @@ public class BubbleChat {
|
|||
|
||||
return dateFormat.format(cal.getTime());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return timestamp;
|
||||
return String.valueOf(timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e033f0ed6991a28bce4309b4480a50a38d52f79c
|
||||
Subproject commit 34f405894cca981328688eb435d414552b2b345c
|
Loading…
Reference in a new issue