Fixes FS#81 - avoid jumps after loading messages

This commit is contained in:
steckbrief 2015-10-15 22:30:47 +02:00
parent 1db6e6d5ea
commit 8c450d17a4
2 changed files with 64 additions and 32 deletions

View file

@ -1050,32 +1050,38 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
Log.d("mam", "Query in progress");
return;
}
//TODO Create a separate class for this runnable to store if messages are getting loaded or not. Not really a good idea to do this in the callback.
Runnable runnable = new Runnable() {
@Override
public void run() {
final Account account = conversation.getAccount();
List<Message> messages = databaseBackend.getMessages(conversation, 50,timestamp);
Log.d("mam", "runnable load more messages");
if (messages.size() > 0) {
Log.d("mam", "At least one message");
conversation.addAll(0, messages);
checkDeletedFiles(conversation);
callback.onMoreMessagesLoaded(messages.size(), conversation);
} else if (conversation.hasMessagesLeftOnServer()
&& account.isOnlineAndConnected()
&& account.getXmppConnection().getFeatures().mam()) {
Log.d("mam", "mam activate, account online and connected and messages left on server");
MessageArchiveService.Query query = getMessageArchiveService().query(conversation,0,timestamp - 1);
if (query != null) {
query.setCallback(callback);
}
callback.informUser(R.string.fetching_history_from_server);
} else {
Log.d("mam", ((!conversation.hasMessagesLeftOnServer()) ? "no" : "") + " more messages left on server, mam " + ((account.getXmppConnection().getFeatures().mam()) ? "" : "not") + " activated, account is " + ((account.isOnlineAndConnected()) ? "" : "not") + " online or connected)");
callback.onMoreMessagesLoaded(0, conversation);
callback.informUser(R.string.no_more_history_on_server);
if (null == callback || !callback.isLoadingInProgress()) { // if a callback is set, ensure that there is no loading in progress
if (null != callback) {
callback.setLoadingInProgress(); // Tell the callback that the loading is in progress
}
final Account account = conversation.getAccount();
List<Message> messages = databaseBackend.getMessages(conversation, 50, timestamp);
Log.d("mam", "runnable load more messages");
if (messages.size() > 0) {
Log.d("mam", "At least one message");
conversation.addAll(0, messages);
checkDeletedFiles(conversation);
callback.onMoreMessagesLoaded(messages.size(), conversation);
} else if (conversation.hasMessagesLeftOnServer()
&& account.isOnlineAndConnected()
&& account.getXmppConnection().getFeatures().mam()) {
Log.d("mam", "mam activate, account online and connected and messages left on server");
MessageArchiveService.Query query = getMessageArchiveService().query(conversation, 0, timestamp - 1);
if (query != null) {
query.setCallback(callback);
}
callback.informUser(R.string.fetching_history_from_server);
} else {
Log.d("mam", ((!conversation.hasMessagesLeftOnServer()) ? "no" : "") + " more messages left on server, mam " + ((account.getXmppConnection().getFeatures().mam()) ? "" : "not") + " activated, account is " + ((account.isOnlineAndConnected()) ? "" : "not") + " online or connected)");
callback.onMoreMessagesLoaded(0, conversation);
callback.informUser(R.string.no_more_history_on_server);
}
}
}
}
};
mDatabaseExecutor.execute(runnable);
}
@ -2553,6 +2559,10 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
public void onMoreMessagesLoaded(int count, Conversation conversation);
public void informUser(int r);
void setLoadingInProgress();
boolean isLoadingInProgress();
}
public interface OnAccountPasswordChanged {

View file

@ -24,18 +24,32 @@ public class ConversationMoreMessagesLoadedListener implements XmppConnectionSer
private ListView messagesView;
private MessageAdapter messageListAdapter;
private Toast messageLoaderToast;
/*
The current loading status
*/
private boolean loadingMessages = false;
public ConversationMoreMessagesLoadedListener(SwipeRefreshLayout swipeLayout, List<Message> messageList, ConversationFragment fragment, ListView messagesView, MessageAdapter messageListAdapter) {
this.swipeLayout = swipeLayout;
this.messageList = messageList;
this.fragment = fragment;
this.messagesView = messagesView;
this.messageListAdapter = messageListAdapter;
}
public void setLoadingInProgress() {
this.loadingMessages = true;
}
public boolean isLoadingInProgress() {
return this.loadingMessages;
}
@Override
public void onMoreMessagesLoaded(final int c, final Conversation conversation) {
ConversationActivity activity = (ConversationActivity) fragment.getActivity();
// Current selected conversation is not the same the messages are loaded - skip updating message view and hide loading graphic
if (activity.getSelectedConversation() != conversation) {
activity.runOnUiThread(new Runnable() {
@Override
@ -45,6 +59,7 @@ public class ConversationMoreMessagesLoadedListener implements XmppConnectionSer
});
return;
}
// No new messages are loaded
if (0 == c) {
activity.runOnUiThread(new Runnable() {
@Override
@ -56,19 +71,26 @@ public class ConversationMoreMessagesLoadedListener implements XmppConnectionSer
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
final int oldPosition = messagesView.getFirstVisiblePosition();
int pos = 0;
View v = messagesView.getChildAt(0);
final int pxOffset = (v == null) ? 0 : v.getTop();
final int oldPosition = messagesView.getFirstVisiblePosition(); // Always 0 - because loading starts always when hitting the top
String uuid = null;
boolean oldMessageListWasEmpty = messageList.isEmpty();
if (-1 < oldPosition && messageList.size() > oldPosition) {
Message message = messageList.get(oldPosition);
String uuid = message != null ? message.getUuid() : null;
pos = getIndexOf(uuid, messageList);
uuid = message != null ? message.getUuid() : null;
}
conversation.populateWithMessages(messageList);
fragment.updateStatusMessages();
View v = messagesView.getChildAt(0);
final int pxOffset = (v == null) ? 0 : v.getTop();
conversation.populateWithMessages(messageList); // This overrides the old message list
fragment.updateStatusMessages(); // This adds "messages" to the list for the status
messageListAdapter.notifyDataSetChanged();
messagesView.setSelectionFromTop(pos, pxOffset);
loadingMessages = false; // Loading of messages is finished - next query can be loaded
int pos = getIndexOf(uuid, messageList);
if (!oldMessageListWasEmpty) {
messagesView.setSelectionFromTop(pos, pxOffset);
}
if (messageLoaderToast != null) {
messageLoaderToast.cancel();
@ -99,7 +121,7 @@ public class ConversationMoreMessagesLoadedListener implements XmppConnectionSer
if (uuid == null) {
return 0;
}
for(int i = 0; i < messages.size(); ++i) {
for (int i = 0; i < messages.size(); ++i) {
if (uuid.equals(messages.get(i).getUuid())) {
return i;
} else {