diff --git a/briar-android/res/drawable-hdpi/message_delivered.png b/briar-android/res/drawable-hdpi/message_delivered.png index 6edef05a95505d6e4605621b5975f179b331c04e..efade63916a2f36a74400bf378d587a763b690a6 100644 Binary files a/briar-android/res/drawable-hdpi/message_delivered.png and b/briar-android/res/drawable-hdpi/message_delivered.png differ diff --git a/briar-android/res/drawable-hdpi/message_sent.png b/briar-android/res/drawable-hdpi/message_sent.png new file mode 100644 index 0000000000000000000000000000000000000000..6edef05a95505d6e4605621b5975f179b331c04e Binary files /dev/null and b/briar-android/res/drawable-hdpi/message_sent.png differ diff --git a/briar-android/res/drawable-hdpi/message_stored.png b/briar-android/res/drawable-hdpi/message_stored.png new file mode 100644 index 0000000000000000000000000000000000000000..8bf1ee459425236b46f96cc10c1912fec981d739 Binary files /dev/null and b/briar-android/res/drawable-hdpi/message_stored.png differ diff --git a/briar-android/res/drawable-mdpi/message_delivered.png b/briar-android/res/drawable-mdpi/message_delivered.png index 1f3807209e1db00dc0b3f07fa5f2fd0e2bd813ad..938c50d909e9dfbf0e931632a4a6282f6fe922b4 100644 Binary files a/briar-android/res/drawable-mdpi/message_delivered.png and b/briar-android/res/drawable-mdpi/message_delivered.png differ diff --git a/briar-android/res/drawable-mdpi/message_sent.png b/briar-android/res/drawable-mdpi/message_sent.png new file mode 100644 index 0000000000000000000000000000000000000000..1f3807209e1db00dc0b3f07fa5f2fd0e2bd813ad Binary files /dev/null and b/briar-android/res/drawable-mdpi/message_sent.png differ diff --git a/briar-android/res/drawable-mdpi/message_stored.png b/briar-android/res/drawable-mdpi/message_stored.png new file mode 100644 index 0000000000000000000000000000000000000000..01858ffc64ddf763b244d301acaa33657a5ea3d5 Binary files /dev/null and b/briar-android/res/drawable-mdpi/message_stored.png differ diff --git a/briar-android/res/drawable-xhdpi/message_delivered.png b/briar-android/res/drawable-xhdpi/message_delivered.png index a40d4d94c0fca5e85e08ce21f3ce99f8c74ceeea..99109113666357edda634c9bbcb9ebd2048e68a8 100644 Binary files a/briar-android/res/drawable-xhdpi/message_delivered.png and b/briar-android/res/drawable-xhdpi/message_delivered.png differ diff --git a/briar-android/res/drawable-xhdpi/message_sent.png b/briar-android/res/drawable-xhdpi/message_sent.png new file mode 100644 index 0000000000000000000000000000000000000000..a40d4d94c0fca5e85e08ce21f3ce99f8c74ceeea Binary files /dev/null and b/briar-android/res/drawable-xhdpi/message_sent.png differ diff --git a/briar-android/res/drawable-xhdpi/message_stored.png b/briar-android/res/drawable-xhdpi/message_stored.png new file mode 100644 index 0000000000000000000000000000000000000000..b8eb1384a23a5819bde40bf9679643dd477604d6 Binary files /dev/null and b/briar-android/res/drawable-xhdpi/message_stored.png differ diff --git a/briar-android/res/drawable-xxhdpi/message_stored.png b/briar-android/res/drawable-xxhdpi/message_stored.png new file mode 100644 index 0000000000000000000000000000000000000000..153650a1f50238963f883cfeb8990d51d9ac57a0 Binary files /dev/null and b/briar-android/res/drawable-xxhdpi/message_stored.png differ diff --git a/briar-android/res/drawable-xxxhdpi/message_stored.png b/briar-android/res/drawable-xxxhdpi/message_stored.png new file mode 100644 index 0000000000000000000000000000000000000000..b3833bc3e76f11b4abe7f1a487bb87025f003075 Binary files /dev/null and b/briar-android/res/drawable-xxxhdpi/message_stored.png differ diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index 2375da4a8f0f5d9014862d0d3f705eee69d805ab..9281d1d572dc84b39986765aa337d2911ace2004 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -55,6 +55,7 @@ import org.briarproject.api.event.EventListener; import org.briarproject.api.event.MessageAddedEvent; import org.briarproject.api.event.MessageExpiredEvent; import org.briarproject.api.event.MessagesAckedEvent; +import org.briarproject.api.event.MessagesSentEvent; import org.briarproject.api.messaging.Group; import org.briarproject.api.messaging.GroupId; import org.briarproject.api.messaging.Message; @@ -384,25 +385,31 @@ implements EventListener, OnClickListener, OnItemClickListener { } else if (e instanceof MessageExpiredEvent) { LOG.info("Message expired, reloading"); loadHeaders(); + } else if (e instanceof MessagesSentEvent) { + MessagesSentEvent m = (MessagesSentEvent) e; + if (m.getContactId().equals(contactId)) { + LOG.info("Messages sent"); + markMessages(m.getMessageIds(), ConversationItem.State.SENT); + } } else if (e instanceof MessagesAckedEvent) { MessagesAckedEvent m = (MessagesAckedEvent) e; if (m.getContactId().equals(contactId)) { LOG.info("Messages acked"); - markMessagesDelivered(m.getMessageIds()); + markMessages(m.getMessageIds(), ConversationItem.State.DELIVERED); } } } - private void markMessagesDelivered(final Collection<MessageId> acked) { + private void markMessages(final Collection<MessageId> messageIds, final ConversationItem.State state) { runOnUiThread(new Runnable() { public void run() { - Set<MessageId> ackedSet = new HashSet<MessageId>(acked); + Set<MessageId> messages = new HashSet<MessageId>(messageIds); boolean changed = false; int count = adapter.getCount(); for (int i = 0; i < count; i++) { ConversationItem item = adapter.getItem(i); - if (ackedSet.contains(item.getHeader().getId())) { - item.setDelivered(true); + if (messages.contains(item.getHeader().getId())) { + item.setStatus(state); changed = true; } } @@ -417,7 +424,6 @@ implements EventListener, OnClickListener, OnItemClickListener { long timestamp = System.currentTimeMillis(); timestamp = Math.max(timestamp, getMinTimestampForNewMessage()); createMessage(StringUtils.toUtf8(message), timestamp); - Toast.makeText(this, R.string.message_sent_toast, LENGTH_SHORT).show(); content.setText(""); hideSoftKeyboard(); } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 14699ab724f78a0950ced38d204150faa5a5eaac..ca85ac94432267a9a8d76cf38c508432ca9fb947 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -79,11 +79,16 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> { footer.addView(new ElasticHorizontalSpace(ctx)); - ImageView delivered = new ImageView(ctx); - delivered.setPadding(0, 0, pad, 0); - delivered.setImageResource(R.drawable.message_delivered); - if (!item.isDelivered()) delivered.setVisibility(INVISIBLE); - footer.addView(delivered); + ImageView status = new ImageView(ctx); + status.setPadding(0, 0, pad, 0); + if (item.getStatus() == ConversationItem.State.DELIVERED) { + status.setImageResource(R.drawable.message_delivered); + } else if (item.getStatus() == ConversationItem.State.SENT) { + status.setImageResource(R.drawable.message_sent); + } else { + status.setImageResource(R.drawable.message_stored); + } + footer.addView(status); TextView date = new TextView(ctx); date.setTextColor(res.getColor(R.color.private_message_date)); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationItem.java b/briar-android/src/org/briarproject/android/contact/ConversationItem.java index c1959f0c5d17f96c2c635134de9ba6b68f074b35..abf29ba7abec725c0c5516c0ed78a57e72c8c779 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationItem.java @@ -5,14 +5,16 @@ import org.briarproject.api.db.MessageHeader; // This class is not thread-safe class ConversationItem { + public enum State { STORED, SENT, DELIVERED }; + private final MessageHeader header; private byte[] body; - private boolean delivered; + private State status; ConversationItem(MessageHeader header) { this.header = header; body = null; - delivered = header.isDelivered(); + status = header.isDelivered() ? State.DELIVERED : State.STORED; } MessageHeader getHeader() { @@ -27,11 +29,11 @@ class ConversationItem { this.body = body; } - boolean isDelivered() { - return delivered; + State getStatus() { + return status; } - void setDelivered(boolean delivered) { - this.delivered = delivered; + void setStatus(State state) { + this.status = state; } } diff --git a/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java b/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java new file mode 100644 index 0000000000000000000000000000000000000000..9444ada5a1516937032152efbab9a7cab1916ddc --- /dev/null +++ b/briar-api/src/org/briarproject/api/event/MessagesSentEvent.java @@ -0,0 +1,27 @@ +package org.briarproject.api.event; + +import java.util.Collection; + +import org.briarproject.api.ContactId; +import org.briarproject.api.messaging.MessageId; + +/** An event that is broadcast when messages are sent to a contact. */ +public class MessagesSentEvent extends Event { + + private final ContactId contactId; + private final Collection<MessageId> acked; + + public MessagesSentEvent(ContactId contactId, + Collection<MessageId> acked) { + this.contactId = contactId; + this.acked = acked; + } + + public ContactId getContactId() { + return contactId; + } + + public Collection<MessageId> getMessageIds() { + return acked; + } +} diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java index 32467764eb715f458a6b312278604e6b4b56a3f7..fbf81fe6b18324027519f63c87f45b2e4635444f 100644 --- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java +++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java @@ -52,6 +52,7 @@ import org.briarproject.api.event.MessageRequestedEvent; import org.briarproject.api.event.MessageToAckEvent; import org.briarproject.api.event.MessageToRequestEvent; import org.briarproject.api.event.MessagesAckedEvent; +import org.briarproject.api.event.MessagesSentEvent; import org.briarproject.api.event.RemoteRetentionTimeUpdatedEvent; import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent; import org.briarproject.api.event.RemoteTransportsUpdatedEvent; @@ -380,6 +381,7 @@ DatabaseCleaner.Callback { lock.writeLock().unlock(); } if (messages.isEmpty()) return null; + if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids)); return Collections.unmodifiableList(messages); } @@ -455,6 +457,7 @@ DatabaseCleaner.Callback { lock.writeLock().unlock(); } if (messages.isEmpty()) return null; + if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids)); return Collections.unmodifiableList(messages); }