From 1b4bae25fe4c4ff29ab1db532fa3f16e5232c583 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Sun, 22 Apr 2018 17:11:45 +0200 Subject: only mark visible messages as read --- .../de/pixart/messenger/entities/Conversation.java | 21 ++++++------- .../messenger/services/XmppConnectionService.java | 33 ++++++++++++-------- .../pixart/messenger/ui/ConversationFragment.java | 35 ++++++++++++++++++---- .../pixart/messenger/ui/ConversationsActivity.java | 4 +-- .../ui/interfaces/OnConversationRead.java | 2 +- 5 files changed, 64 insertions(+), 31 deletions(-) (limited to 'src/main/java/de') diff --git a/src/main/java/de/pixart/messenger/entities/Conversation.java b/src/main/java/de/pixart/messenger/entities/Conversation.java index 8b3f06711..1e87b7ec5 100644 --- a/src/main/java/de/pixart/messenger/entities/Conversation.java +++ b/src/main/java/de/pixart/messenger/entities/Conversation.java @@ -475,7 +475,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead(); } - public List markRead() { + public List markRead(String upToUuid) { final List unread = new ArrayList<>(); synchronized (this.messages) { for (Message message : this.messages) { @@ -483,20 +483,21 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl message.markRead(); unread.add(message); } + if (message.getUuid().equals(upToUuid)) { + return unread; + } } } return unread; } - public Message getLatestMarkableMessage(boolean isPrivateAndNonAnonymousMuc) { - synchronized (this.messages) { - for (int i = this.messages.size() - 1; i >= 0; --i) { - final Message message = this.messages.get(i); - if (message.getStatus() <= Message.STATUS_RECEIVED - && (message.markable || isPrivateAndNonAnonymousMuc) - && message.getType() != Message.TYPE_PRIVATE) { - return message.isRead() ? null : message; - } + public static Message getLatestMarkableMessage(final List messages, boolean isPrivateAndNonAnonymousMuc) { + for (int i = messages.size() - 1; i >= 0; --i) { + final Message message = messages.get(i); + if (message.getStatus() <= Message.STATUS_RECEIVED + && (message.markable || isPrivateAndNonAnonymousMuc) + && message.getType() != Message.TYPE_PRIVATE) { + return message; } } return null; diff --git a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java index dfd05bbe3..9a9f53589 100644 --- a/src/main/java/de/pixart/messenger/services/XmppConnectionService.java +++ b/src/main/java/de/pixart/messenger/services/XmppConnectionService.java @@ -632,7 +632,7 @@ public class XmppConnectionService extends Service { } try { restoredFromDatabaseLatch.await(); - sendReadMarker(c); + sendReadMarker(c, null); } catch (InterruptedException e) { Log.d(Config.LOGTAG, "unable to process notification read marker for conversation " + c.getName()); } @@ -3444,9 +3444,11 @@ public class XmppConnectionService extends Service { } public void markMessage(Message message, int status, String errorMessage) { - if (status == Message.STATUS_SEND_FAILED - && (message.getStatus() == Message.STATUS_SEND_RECEIVED || message - .getStatus() == Message.STATUS_SEND_DISPLAYED)) { + final int c = message.getStatus(); + if (status == Message.STATUS_SEND_FAILED && (c == Message.STATUS_SEND_RECEIVED || c == Message.STATUS_SEND_DISPLAYED)) { + return; + } + if (status == Message.STATUS_SEND_RECEIVED && c == Message.STATUS_SEND_DISPLAYED) { return; } message.setErrorMessage(errorMessage); @@ -3603,15 +3605,19 @@ public class XmppConnectionService extends Service { return null; } + public boolean markRead(final Conversation conversation, boolean dismiss) { + return markRead(conversation, null, dismiss).size() > 0; + } + public boolean markRead(final Conversation conversation) { - return markRead(conversation, true); + return markRead(conversation, null, true).size() > 0; } - public boolean markRead(final Conversation conversation, boolean clear) { - if (clear) { + public List markRead(final Conversation conversation, String upToUuid, boolean dismiss) { + if (dismiss) { mNotificationService.clear(conversation); } - final List readMessages = conversation.markRead(); + final List readMessages = conversation.markRead(upToUuid); if (readMessages.size() > 0) { Runnable runnable = () -> { for (Message message : readMessages) { @@ -3620,9 +3626,9 @@ public class XmppConnectionService extends Service { }; mDatabaseWriterExecutor.execute(runnable); updateUnreadCountBadge(); - return true; + return readMessages; } else { - return false; + return readMessages; } } @@ -3641,12 +3647,13 @@ public class XmppConnectionService extends Service { }).start(); } - public void sendReadMarker(final Conversation conversation) { + public void sendReadMarker(final Conversation conversation, String upToUuid) { final boolean isPrivateAndNonAnonymousMuc = conversation.getMode() == Conversation.MODE_MULTI && conversation.isPrivateAndNonAnonymous(); - final Message markable = conversation.getLatestMarkableMessage(isPrivateAndNonAnonymousMuc); - if (this.markRead(conversation)) { + final List readMessages = this.markRead(conversation, upToUuid, true); + if (readMessages.size() > 0) { updateConversationUi(); } + final Message markable = Conversation.getLatestMarkableMessage(readMessages, isPrivateAndNonAnonymousMuc); if (confirmMessages() && markable != null && (markable.trusted() || isPrivateAndNonAnonymousMuc) diff --git a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java index 332b62b7b..7bd20f3e5 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationFragment.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationFragment.java @@ -239,8 +239,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke @Override public void onScrollStateChanged(AbsListView view, int scrollState) { - // TODO Auto-generated method stub - + if (AbsListView.OnScrollListener.SCROLL_STATE_IDLE == scrollState) { + fireReadEvent(); + } } @Override @@ -1825,9 +1826,33 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke getActivity().invalidateOptionsMenu(); }); super.onResume(); + binding.messagesView.post(this::fireReadEvent); + } + + private void fireReadEvent() { if (activity != null && this.conversation != null) { - activity.onConversationRead(this.conversation); + String uuid = getLastVisibleMessageUuid(); + if (uuid != null) { + activity.onConversationRead(this.conversation, uuid); + } + } + } + + private String getLastVisibleMessageUuid() { + if (binding == null) { + return null; } + int pos = binding.messagesView.getLastVisiblePosition(); + if (pos >= 0) { + Message message = (Message) binding.messagesView.getItemAtPosition(pos); + if (message != null) { + while (message.next() != null && message.next().wasMergedIntoPrevious()) { + message = message.next(); + } + return message.getUuid(); + } + } + return null; } private void showErrorMessage(final Message message) { @@ -2167,7 +2192,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke } } - activity.onConversationRead(this.conversation); + this.binding.messagesView.post(this::fireReadEvent); //TODO if we only do this when this fragment is running on main it won't *bing* in tablet layout which might be unnecessary since we can *see* it activity.xmppConnectionService.getNotificationService().setOpenConversation(this.conversation); @@ -2434,7 +2459,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke this.messageListAdapter.notifyDataSetChanged(); updateChatMsgHint(); if (notifyConversationRead && activity != null) { - activity.onConversationRead(this.conversation); + binding.messagesView.post(this::fireReadEvent); } updateSendButton(); updateEditablity(); diff --git a/src/main/java/de/pixart/messenger/ui/ConversationsActivity.java b/src/main/java/de/pixart/messenger/ui/ConversationsActivity.java index 89e003e9f..9fb4d26e8 100644 --- a/src/main/java/de/pixart/messenger/ui/ConversationsActivity.java +++ b/src/main/java/de/pixart/messenger/ui/ConversationsActivity.java @@ -863,9 +863,9 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio } @Override - public void onConversationRead(Conversation conversation) { + public void onConversationRead(Conversation conversation, String upToUuid) { if (!mActivityPaused && pendingViewIntent.peek() == null) { - xmppConnectionService.sendReadMarker(conversation); + xmppConnectionService.sendReadMarker(conversation, upToUuid); } else { Log.d(Config.LOGTAG, "ignoring read callback. mActivityPaused=" + Boolean.toString(mActivityPaused)); } diff --git a/src/main/java/de/pixart/messenger/ui/interfaces/OnConversationRead.java b/src/main/java/de/pixart/messenger/ui/interfaces/OnConversationRead.java index ab5cc607d..763d139d3 100644 --- a/src/main/java/de/pixart/messenger/ui/interfaces/OnConversationRead.java +++ b/src/main/java/de/pixart/messenger/ui/interfaces/OnConversationRead.java @@ -32,5 +32,5 @@ package de.pixart.messenger.ui.interfaces; import de.pixart.messenger.entities.Conversation; public interface OnConversationRead { - void onConversationRead(Conversation conversation); + void onConversationRead(Conversation conversation, String upToUuid); } \ No newline at end of file -- cgit v1.2.3