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);
 	}