only mark visible messages as read
This commit is contained in:
parent
e1a6ceb49b
commit
aeaa58071c
|
@ -443,7 +443,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
return (this.messages.size() == 0) || this.messages.get(this.messages.size() - 1).isRead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Message> markRead() {
|
public List<Message> markRead(String upToUuid) {
|
||||||
final List<Message> unread = new ArrayList<>();
|
final List<Message> unread = new ArrayList<>();
|
||||||
synchronized (this.messages) {
|
synchronized (this.messages) {
|
||||||
for (Message message : this.messages) {
|
for (Message message : this.messages) {
|
||||||
|
@ -451,22 +451,23 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
|
||||||
message.markRead();
|
message.markRead();
|
||||||
unread.add(message);
|
unread.add(message);
|
||||||
}
|
}
|
||||||
|
if (message.getUuid().equals(upToUuid)) {
|
||||||
|
return unread;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return unread;
|
return unread;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message getLatestMarkableMessage(boolean isPrivateAndNonAnonymousMuc) {
|
public static Message getLatestMarkableMessage(final List<Message> messages, boolean isPrivateAndNonAnonymousMuc) {
|
||||||
synchronized (this.messages) {
|
for (int i = messages.size() - 1; i >= 0; --i) {
|
||||||
for (int i = this.messages.size() - 1; i >= 0; --i) {
|
final Message message = messages.get(i);
|
||||||
final Message message = this.messages.get(i);
|
|
||||||
if (message.getStatus() <= Message.STATUS_RECEIVED
|
if (message.getStatus() <= Message.STATUS_RECEIVED
|
||||||
&& (message.markable || isPrivateAndNonAnonymousMuc)
|
&& (message.markable || isPrivateAndNonAnonymousMuc)
|
||||||
&& message.getType() != Message.TYPE_PRIVATE) {
|
&& message.getType() != Message.TYPE_PRIVATE) {
|
||||||
return message.isRead() ? null : message;
|
return message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -607,7 +607,7 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
restoredFromDatabaseLatch.await();
|
restoredFromDatabaseLatch.await();
|
||||||
sendReadMarker(c);
|
sendReadMarker(c,null);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Log.d(Config.LOGTAG, "unable to process notification read marker for conversation " + c.getName());
|
Log.d(Config.LOGTAG, "unable to process notification read marker for conversation " + c.getName());
|
||||||
}
|
}
|
||||||
|
@ -3116,9 +3116,11 @@ public class XmppConnectionService extends Service {
|
||||||
|
|
||||||
|
|
||||||
public void markMessage(Message message, int status, String errorMessage) {
|
public void markMessage(Message message, int status, String errorMessage) {
|
||||||
if (status == Message.STATUS_SEND_FAILED
|
final int c = message.getStatus();
|
||||||
&& (message.getStatus() == Message.STATUS_SEND_RECEIVED || message
|
if (status == Message.STATUS_SEND_FAILED && (c == Message.STATUS_SEND_RECEIVED || c == Message.STATUS_SEND_DISPLAYED)) {
|
||||||
.getStatus() == Message.STATUS_SEND_DISPLAYED)) {
|
return;
|
||||||
|
}
|
||||||
|
if (status == Message.STATUS_SEND_RECEIVED && c == Message.STATUS_SEND_DISPLAYED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
message.setErrorMessage(errorMessage);
|
message.setErrorMessage(errorMessage);
|
||||||
|
@ -3262,15 +3264,19 @@ public class XmppConnectionService extends Service {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean markRead(final Conversation conversation) {
|
public boolean markRead(final Conversation conversation, boolean dismiss) {
|
||||||
return markRead(conversation, true);
|
return markRead(conversation,null,dismiss).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean markRead(final Conversation conversation, boolean clear) {
|
public boolean markRead(final Conversation conversation) {
|
||||||
if (clear) {
|
return markRead(conversation, null, true).size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Message> markRead(final Conversation conversation, String upToUuid, boolean dismiss) {
|
||||||
|
if (dismiss) {
|
||||||
mNotificationService.clear(conversation);
|
mNotificationService.clear(conversation);
|
||||||
}
|
}
|
||||||
final List<Message> readMessages = conversation.markRead();
|
final List<Message> readMessages = conversation.markRead(upToUuid);
|
||||||
if (readMessages.size() > 0) {
|
if (readMessages.size() > 0) {
|
||||||
Runnable runnable = () -> {
|
Runnable runnable = () -> {
|
||||||
for (Message message : readMessages) {
|
for (Message message : readMessages) {
|
||||||
|
@ -3279,9 +3285,9 @@ public class XmppConnectionService extends Service {
|
||||||
};
|
};
|
||||||
mDatabaseWriterExecutor.execute(runnable);
|
mDatabaseWriterExecutor.execute(runnable);
|
||||||
updateUnreadCountBadge();
|
updateUnreadCountBadge();
|
||||||
return true;
|
return readMessages;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return readMessages;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3298,12 +3304,13 @@ public class XmppConnectionService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 boolean isPrivateAndNonAnonymousMuc = conversation.getMode() == Conversation.MODE_MULTI && conversation.isPrivateAndNonAnonymous();
|
||||||
final Message markable = conversation.getLatestMarkableMessage(isPrivateAndNonAnonymousMuc);
|
final List<Message> readMessages = this.markRead(conversation,upToUuid,true);
|
||||||
if (this.markRead(conversation)) {
|
if (readMessages.size() > 0) {
|
||||||
updateConversationUi();
|
updateConversationUi();
|
||||||
}
|
}
|
||||||
|
final Message markable = Conversation.getLatestMarkableMessage(readMessages, isPrivateAndNonAnonymousMuc);
|
||||||
if (confirmMessages()
|
if (confirmMessages()
|
||||||
&& markable != null
|
&& markable != null
|
||||||
&& (markable.trusted() || isPrivateAndNonAnonymousMuc)
|
&& (markable.trusted() || isPrivateAndNonAnonymousMuc)
|
||||||
|
|
|
@ -213,7 +213,9 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
public void onScrollStateChanged(AbsListView view, int scrollState) {
|
||||||
|
if (AbsListView.OnScrollListener.SCROLL_STATE_IDLE == scrollState) {
|
||||||
|
fireReadEvent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1547,11 +1549,35 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
getActivity().invalidateOptionsMenu();
|
getActivity().invalidateOptionsMenu();
|
||||||
});
|
});
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
binding.messagesView.post(this::fireReadEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fireReadEvent() {
|
||||||
if (activity != null && this.conversation != null) {
|
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) {
|
private void showErrorMessage(final Message message) {
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||||
builder.setTitle(R.string.error_message);
|
builder.setTitle(R.string.error_message);
|
||||||
|
@ -1884,7 +1910,8 @@ 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
|
//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);
|
activity.xmppConnectionService.getNotificationService().setOpenConversation(this.conversation);
|
||||||
return true;
|
return true;
|
||||||
|
@ -2076,7 +2103,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
this.messageListAdapter.notifyDataSetChanged();
|
this.messageListAdapter.notifyDataSetChanged();
|
||||||
updateChatMsgHint();
|
updateChatMsgHint();
|
||||||
if (notifyConversationRead && activity != null) {
|
if (notifyConversationRead && activity != null) {
|
||||||
activity.onConversationRead(this.conversation);
|
binding.messagesView.post(this::fireReadEvent);
|
||||||
}
|
}
|
||||||
updateSendButton();
|
updateSendButton();
|
||||||
updateEditablity();
|
updateEditablity();
|
||||||
|
|
|
@ -592,9 +592,9 @@ public class ConversationsActivity extends XmppActivity implements OnConversatio
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConversationRead(Conversation conversation) {
|
public void onConversationRead(Conversation conversation, String upToUuid) {
|
||||||
if (!mActivityPaused && pendingViewIntent.peek() == null) {
|
if (!mActivityPaused && pendingViewIntent.peek() == null) {
|
||||||
xmppConnectionService.sendReadMarker(conversation);
|
xmppConnectionService.sendReadMarker(conversation, upToUuid);
|
||||||
} else {
|
} else {
|
||||||
Log.d(Config.LOGTAG, "ignoring read callback. mActivityPaused=" + Boolean.toString(mActivityPaused));
|
Log.d(Config.LOGTAG, "ignoring read callback. mActivityPaused=" + Boolean.toString(mActivityPaused));
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,5 +32,5 @@ package eu.siacs.conversations.ui.interfaces;
|
||||||
import eu.siacs.conversations.entities.Conversation;
|
import eu.siacs.conversations.entities.Conversation;
|
||||||
|
|
||||||
public interface OnConversationRead {
|
public interface OnConversationRead {
|
||||||
void onConversationRead(Conversation conversation);
|
void onConversationRead(Conversation conversation, String upToUuid);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue