diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index 4b79ce4389c2e29951ba8b05f10b055fcab7c2f7..0e1678edbe89c3eef6ace473e53846628cff41bc 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -331,11 +331,21 @@ public class ConversationActivity extends BriarActivity finishOnUiThread(); } } else if (e instanceof MessageAddedEvent) { - GroupId g = ((MessageAddedEvent) e).getGroupId(); + MessageAddedEvent mEvent = (MessageAddedEvent) e; + GroupId g = mEvent.getGroupId(); if (g.equals(groupId)) { + // mark new incoming messages as read directly + if (mEvent.getContactId() != null) { + ConversationItem item = adapter.getLastItem(); + if (item != null) { + markIncomingMessageRead(mEvent.getMessage(), + item.getHeader().getTimestamp()); + } + } + LOG.info("Message added, reloading"); - // TODO: find a way of not needing to reload the entire - // conversation just because one message was added + // TODO: get and add the ConversationItem here to prevent + // reloading the entire conversation loadHeaders(); } } else if (e instanceof MessagesSentEvent) { @@ -384,7 +394,41 @@ public class ConversationActivity extends BriarActivity }); } + private void markIncomingMessageRead(final Message m, + final long lastMsgTime) { + + // stop here if message is older than latest message we have + long newMsgTime = m.getTimestamp(); + if (newMsgTime < lastMsgTime) return; + + runOnDbThread(new Runnable() { + public void run() { + try { + // mark messages as read, because is latest + messagingManager.setReadFlag(m.getId(), true); + showIncomingMessageRead(); + } catch (DbException e) { + if (LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } + } + // TODO else: smooth-scroll up to unread messages if out of view + }); + } + + private void showIncomingMessageRead() { + runOnUiThread(new Runnable() { + public void run() { + // this is only called from markIncomingMessageRead() + // so we can assume that it was the last message that changed + adapter.notifyItemChanged(adapter.getItemCount() - 1); + } + }); + } + public void onClick(View view) { + markMessagesRead(); + String message = content.getText().toString(); if (message.equals("")) return; long timestamp = System.currentTimeMillis(); @@ -397,10 +441,9 @@ public class ConversationActivity extends BriarActivity private long getMinTimestampForNewMessage() { // Don't use an earlier timestamp than the newest message long timestamp = 0; - int count = adapter.getItemCount(); - for (int i = 0; i < count; i++) { - long t = adapter.getItem(i).getHeader().getTimestamp(); - if (t > timestamp) timestamp = t; + ConversationItem item = adapter.getLastItem(); + if (item != null) { + timestamp = item.getHeader().getTimestamp(); } return timestamp + 1; } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 0e183a63b571f706e403cf2b81d6ae9cc9c9f158..6b0c1aac62fd50392a13840f824b10edc6ccb768 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -159,6 +159,14 @@ class ConversationAdapter extends return messages.get(position); } + public ConversationItem getLastItem() { + if (messages.size() > 0) { + return messages.get(messages.size() - 1); + } else { + return null; + } + } + public void add(final ConversationItem message) { this.messages.add(message); } diff --git a/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java b/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java index a557d008570563ba25d8ea228ce107e391eb12d0..5e08c9b20b9f7930383ee829aeca306015405524 100644 --- a/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java +++ b/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java @@ -2,21 +2,27 @@ package org.briarproject.api.event; import org.briarproject.api.contact.ContactId; import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.Message; /** An event that is broadcast when a message is added to the database. */ public class MessageAddedEvent extends Event { - private final GroupId groupId; + private final Message message; private final ContactId contactId; - public MessageAddedEvent(GroupId groupId, ContactId contactId) { - this.groupId = groupId; + public MessageAddedEvent(Message message, ContactId contactId) { + this.message = message; this.contactId = contactId; } + /** Returns the message that was added. */ + public Message getMessage() { + return message; + } + /** Returns the ID of the group to which the message belongs. */ public GroupId getGroupId() { - return groupId; + return message.getGroup().getId(); } /** diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java index 2447b3844c43e80db1e592724a312e90852aae66..795fb41365d64f92b11fbdd2173e050ee5a51565 100644 --- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java +++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java @@ -223,8 +223,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { lock.writeLock().unlock(); } if (!duplicate && subscribed) { - GroupId g = m.getGroup().getId(); - eventBus.broadcast(new MessageAddedEvent(g, null)); + eventBus.broadcast(new MessageAddedEvent(m, null)); } } @@ -1053,8 +1052,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent { } if (visible) { if (!duplicate) { - GroupId g = m.getGroup().getId(); - eventBus.broadcast(new MessageAddedEvent(g, c)); + eventBus.broadcast(new MessageAddedEvent(m, c)); } eventBus.broadcast(new MessageToAckEvent(c)); }