From 8c450d17a4f94a2528b6b438e39cd128bfbe84ce Mon Sep 17 00:00:00 2001 From: steckbrief Date: Thu, 15 Oct 2015 22:30:47 +0200 Subject: Fixes FS#81 - avoid jumps after loading messages --- .../services/XmppConnectionService.java | 54 +++++++++++++--------- .../ConversationMoreMessagesLoadedListener.java | 42 +++++++++++++---- 2 files changed, 64 insertions(+), 32 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java index 8ff5f0d2..5e529f3c 100644 --- a/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java +++ b/src/main/java/de/thedevstack/conversationsplus/services/XmppConnectionService.java @@ -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 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 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 { diff --git a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java index 6e7d5d6a..cdc60187 100644 --- a/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java +++ b/src/main/java/de/thedevstack/conversationsplus/ui/listeners/ConversationMoreMessagesLoadedListener.java @@ -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 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 { -- cgit v1.2.3