made scroling smoother + bug fixes for history loading

iNPUTmice created

Change summary

src/main/java/eu/siacs/conversations/services/MessageArchiveService.java | 10 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |  7 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        | 51 
src/main/res/values/strings.xml                                          |  1 
4 files changed, 48 insertions(+), 21 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/MessageArchiveService.java 🔗

@@ -9,6 +9,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import eu.siacs.conversations.Config;
+import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.generator.AbstractGenerator;
@@ -217,7 +218,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 
 	public class Query {
 		private int totalCount = 0;
-		private int count = 0;
+		private int messageCount = 0;
 		private long start;
 		private long end;
 		private Jid with = null;
@@ -295,7 +296,10 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 
 		public void callback() {
 			if (this.callback != null) {
-				this.callback.onMoreMessagesLoaded(count,conversation);
+				this.callback.onMoreMessagesLoaded(messageCount,conversation);
+				if (messageCount==0) {
+					this.callback.informUser(R.string.no_more_history_on_server);
+				}
 			}
 		}
 
@@ -316,7 +320,7 @@ public class MessageArchiveService implements OnAdvancedStreamFeaturesLoaded {
 		}
 
 		public void incrementMessageCount() {
-			this.count++;
+			this.messageCount++;
 		}
 
 		public int getTotalCount() {

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -962,12 +962,13 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 	}
 
 	public void loadMoreMessages(final Conversation conversation, final long timestamp, final OnMoreMessagesLoaded callback) {
+		Log.d(Config.LOGTAG,"load more messages for "+conversation.getName() + " prior to "+MessageGenerator.getTimestamp(timestamp));
+		if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation)) {
+			return;
+		}
 		new Thread(new Runnable() {
 			@Override
 			public void run() {
-				if (XmppConnectionService.this.getMessageArchiveService().queryInProgress(conversation)) {
-					return;
-				}
 				final Account account = conversation.getAccount();
 				List<Message> messages = databaseBackend.getMessages(conversation, 50,timestamp);
 				if (messages.size() > 0) {

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -105,7 +105,7 @@ public class ConversationFragment extends Fragment {
 	private RelativeLayout snackbar;
 	private TextView snackbarMessage;
 	private TextView snackbarAction;
-	private boolean messagesLoaded = false;
+	private boolean messagesLoaded = true;
 	private Toast messageLoaderToast;
 
 	private OnScrollListener mOnScrollListener = new OnScrollListener() {
@@ -120,7 +120,7 @@ public class ConversationFragment extends Fragment {
 		public void onScroll(AbsListView view, int firstVisibleItem,
 							 int visibleItemCount, int totalItemCount) {
 			synchronized (ConversationFragment.this.messageList) {
-				if (firstVisibleItem < 5 && messagesLoaded) {
+				if (firstVisibleItem < 5 && messagesLoaded && messageList.size() > 0) {
 					long timestamp = ConversationFragment.this.messageList.get(0).getTimeSent();
 					messagesLoaded = false;
 					activity.xmppConnectionService.loadMoreMessages(conversation, timestamp, new XmppConnectionService.OnMoreMessagesLoaded() {
@@ -132,19 +132,26 @@ public class ConversationFragment extends Fragment {
 							activity.runOnUiThread(new Runnable() {
 								@Override
 								public void run() {
-									int oldPosition = messagesView.getFirstVisiblePosition();
+									final int oldPosition = messagesView.getFirstVisiblePosition();
+									View v = messagesView.getChildAt(0);
+									final int pxOffset = (v == null) ? 0 : v.getTop();
 									ConversationFragment.this.conversation.populateWithMessages(ConversationFragment.this.messageList);
 									updateStatusMessages();
 									messageListAdapter.notifyDataSetChanged();
 									if (count != 0) {
 										final int newPosition = oldPosition + count;
-										Message tmpMessage = messageList.get(newPosition);
 										int offset = 0;
-										while(tmpMessage.wasMergedIntoPrevious()) {
-											offset++;
-											tmpMessage = tmpMessage.prev();
+										try {
+											Message tmpMessage = messageList.get(newPosition);
+
+											while(tmpMessage.wasMergedIntoPrevious()) {
+												offset++;
+												tmpMessage = tmpMessage.prev();
+											}
+										} catch (final IndexOutOfBoundsException ignored) {
+
 										}
-										messagesView.setSelectionFromTop(newPosition - offset, 0);
+										messagesView.setSelectionFromTop(newPosition - offset, pxOffset);
 										messagesLoaded = true;
 										if (messageLoaderToast != null) {
 											messageLoaderToast.cancel();
@@ -155,12 +162,22 @@ public class ConversationFragment extends Fragment {
 						}
 
 						@Override
-						public void informUser(int resId) {
-							if (messageLoaderToast != null) {
-								messageLoaderToast.cancel();
-							}
-							messageLoaderToast = Toast.makeText(activity,resId,Toast.LENGTH_LONG);
-							messageLoaderToast.show();
+						public void informUser(final int resId) {
+
+							activity.runOnUiThread(new Runnable() {
+								@Override
+								public void run() {
+									if (messageLoaderToast != null) {
+										messageLoaderToast.cancel();
+									}
+									if (ConversationFragment.this.conversation != conversation) {
+										return;
+									}
+									messageLoaderToast = Toast.makeText(activity,resId,Toast.LENGTH_LONG);
+									messageLoaderToast.show();
+								}
+							});
+
 						}
 					});
 
@@ -549,6 +566,11 @@ public class ConversationFragment extends Fragment {
 		this.mEditMessage.append(this.conversation.getNextMessage());
 		this.messagesView.invalidate();
 		updateMessages();
+		this.messagesLoaded = true;
+		int size = this.messageList.size();
+		if (size > 0) {
+			messagesView.setSelection(size - 1);
+		}
 	}
 
 	public void updateMessages() {
@@ -617,7 +639,6 @@ public class ConversationFragment extends Fragment {
 					}
 				}
 				conversation.populateWithMessages(ConversationFragment.this.messageList);
-				this.messagesLoaded = this.messageList.size() > 0;
 				for (Message message : this.messageList) {
 					if (message.getEncryption() == Message.ENCRYPTION_PGP
 							&& (message.getStatus() == Message.STATUS_RECEIVED || message

src/main/res/values/strings.xml 🔗

@@ -367,4 +367,5 @@
     <string name="account_image_description">Account avatar</string>
     <string name="copy_otr_clipboard_description">Copy OTR fingerprint to clipboard</string>
     <string name="fetching_history_from_server">Fetching history from server</string>
+    <string name="no_more_history_on_server">No more history on server</string>
 </resources>