Improve how the status of messages is indicated.
Remove the Toast that always says 'Message Sent' and show graphical indicators instead that show either: * message is waiting to be sent * message was sent (or requested) * message was delivered
|
Before Width: | Height: | Size: 284 B After Width: | Height: | Size: 479 B |
BIN
briar-android/res/drawable-hdpi/message_sent.png
Normal file
|
After Width: | Height: | Size: 284 B |
BIN
briar-android/res/drawable-hdpi/message_stored.png
Normal file
|
After Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 313 B |
BIN
briar-android/res/drawable-mdpi/message_sent.png
Normal file
|
After Width: | Height: | Size: 238 B |
BIN
briar-android/res/drawable-mdpi/message_stored.png
Normal file
|
After Width: | Height: | Size: 237 B |
|
Before Width: | Height: | Size: 392 B After Width: | Height: | Size: 627 B |
BIN
briar-android/res/drawable-xhdpi/message_sent.png
Normal file
|
After Width: | Height: | Size: 392 B |
BIN
briar-android/res/drawable-xhdpi/message_stored.png
Normal file
|
After Width: | Height: | Size: 443 B |
BIN
briar-android/res/drawable-xxhdpi/message_stored.png
Normal file
|
After Width: | Height: | Size: 683 B |
BIN
briar-android/res/drawable-xxxhdpi/message_stored.png
Normal file
|
After Width: | Height: | Size: 969 B |
@@ -55,6 +55,7 @@ import org.briarproject.api.event.EventListener;
|
|||||||
import org.briarproject.api.event.MessageAddedEvent;
|
import org.briarproject.api.event.MessageAddedEvent;
|
||||||
import org.briarproject.api.event.MessageExpiredEvent;
|
import org.briarproject.api.event.MessageExpiredEvent;
|
||||||
import org.briarproject.api.event.MessagesAckedEvent;
|
import org.briarproject.api.event.MessagesAckedEvent;
|
||||||
|
import org.briarproject.api.event.MessagesSentEvent;
|
||||||
import org.briarproject.api.messaging.Group;
|
import org.briarproject.api.messaging.Group;
|
||||||
import org.briarproject.api.messaging.GroupId;
|
import org.briarproject.api.messaging.GroupId;
|
||||||
import org.briarproject.api.messaging.Message;
|
import org.briarproject.api.messaging.Message;
|
||||||
@@ -384,25 +385,31 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
|||||||
} else if (e instanceof MessageExpiredEvent) {
|
} else if (e instanceof MessageExpiredEvent) {
|
||||||
LOG.info("Message expired, reloading");
|
LOG.info("Message expired, reloading");
|
||||||
loadHeaders();
|
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) {
|
} else if (e instanceof MessagesAckedEvent) {
|
||||||
MessagesAckedEvent m = (MessagesAckedEvent) e;
|
MessagesAckedEvent m = (MessagesAckedEvent) e;
|
||||||
if (m.getContactId().equals(contactId)) {
|
if (m.getContactId().equals(contactId)) {
|
||||||
LOG.info("Messages acked");
|
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() {
|
runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
Set<MessageId> ackedSet = new HashSet<MessageId>(acked);
|
Set<MessageId> messages = new HashSet<MessageId>(messageIds);
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
int count = adapter.getCount();
|
int count = adapter.getCount();
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
ConversationItem item = adapter.getItem(i);
|
ConversationItem item = adapter.getItem(i);
|
||||||
if (ackedSet.contains(item.getHeader().getId())) {
|
if (messages.contains(item.getHeader().getId())) {
|
||||||
item.setDelivered(true);
|
item.setStatus(state);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -417,7 +424,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
|||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
timestamp = Math.max(timestamp, getMinTimestampForNewMessage());
|
||||||
createMessage(StringUtils.toUtf8(message), timestamp);
|
createMessage(StringUtils.toUtf8(message), timestamp);
|
||||||
Toast.makeText(this, R.string.message_sent_toast, LENGTH_SHORT).show();
|
|
||||||
content.setText("");
|
content.setText("");
|
||||||
hideSoftKeyboard();
|
hideSoftKeyboard();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,11 +79,16 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
|
|||||||
|
|
||||||
footer.addView(new ElasticHorizontalSpace(ctx));
|
footer.addView(new ElasticHorizontalSpace(ctx));
|
||||||
|
|
||||||
ImageView delivered = new ImageView(ctx);
|
ImageView status = new ImageView(ctx);
|
||||||
delivered.setPadding(0, 0, pad, 0);
|
status.setPadding(0, 0, pad, 0);
|
||||||
delivered.setImageResource(R.drawable.message_delivered);
|
if (item.getStatus() == ConversationItem.State.DELIVERED) {
|
||||||
if (!item.isDelivered()) delivered.setVisibility(INVISIBLE);
|
status.setImageResource(R.drawable.message_delivered);
|
||||||
footer.addView(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);
|
TextView date = new TextView(ctx);
|
||||||
date.setTextColor(res.getColor(R.color.private_message_date));
|
date.setTextColor(res.getColor(R.color.private_message_date));
|
||||||
|
|||||||
@@ -5,14 +5,16 @@ import org.briarproject.api.db.MessageHeader;
|
|||||||
// This class is not thread-safe
|
// This class is not thread-safe
|
||||||
class ConversationItem {
|
class ConversationItem {
|
||||||
|
|
||||||
|
public enum State { STORED, SENT, DELIVERED };
|
||||||
|
|
||||||
private final MessageHeader header;
|
private final MessageHeader header;
|
||||||
private byte[] body;
|
private byte[] body;
|
||||||
private boolean delivered;
|
private State status;
|
||||||
|
|
||||||
ConversationItem(MessageHeader header) {
|
ConversationItem(MessageHeader header) {
|
||||||
this.header = header;
|
this.header = header;
|
||||||
body = null;
|
body = null;
|
||||||
delivered = header.isDelivered();
|
status = header.isDelivered() ? State.DELIVERED : State.STORED;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageHeader getHeader() {
|
MessageHeader getHeader() {
|
||||||
@@ -27,11 +29,11 @@ class ConversationItem {
|
|||||||
this.body = body;
|
this.body = body;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isDelivered() {
|
State getStatus() {
|
||||||
return delivered;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDelivered(boolean delivered) {
|
void setStatus(State state) {
|
||||||
this.delivered = delivered;
|
this.status = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,6 +52,7 @@ import org.briarproject.api.event.MessageRequestedEvent;
|
|||||||
import org.briarproject.api.event.MessageToAckEvent;
|
import org.briarproject.api.event.MessageToAckEvent;
|
||||||
import org.briarproject.api.event.MessageToRequestEvent;
|
import org.briarproject.api.event.MessageToRequestEvent;
|
||||||
import org.briarproject.api.event.MessagesAckedEvent;
|
import org.briarproject.api.event.MessagesAckedEvent;
|
||||||
|
import org.briarproject.api.event.MessagesSentEvent;
|
||||||
import org.briarproject.api.event.RemoteRetentionTimeUpdatedEvent;
|
import org.briarproject.api.event.RemoteRetentionTimeUpdatedEvent;
|
||||||
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
|
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
|
||||||
import org.briarproject.api.event.RemoteTransportsUpdatedEvent;
|
import org.briarproject.api.event.RemoteTransportsUpdatedEvent;
|
||||||
@@ -380,6 +381,7 @@ DatabaseCleaner.Callback {
|
|||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
if (messages.isEmpty()) return null;
|
if (messages.isEmpty()) return null;
|
||||||
|
if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
|
||||||
return Collections.unmodifiableList(messages);
|
return Collections.unmodifiableList(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,6 +457,7 @@ DatabaseCleaner.Callback {
|
|||||||
lock.writeLock().unlock();
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
if (messages.isEmpty()) return null;
|
if (messages.isEmpty()) return null;
|
||||||
|
if (!ids.isEmpty()) eventBus.broadcast(new MessagesSentEvent(c, ids));
|
||||||
return Collections.unmodifiableList(messages);
|
return Collections.unmodifiableList(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||