failed messages get now marked inline

Daniel Gultsch created

Change summary

res/layout/message_error.xml                                   | 54 ----
res/values/strings.xml                                         |  2 
src/eu/siacs/conversations/entities/Message.java               |  3 
src/eu/siacs/conversations/services/XmppConnectionService.java | 40 ++
src/eu/siacs/conversations/ui/ConversationFragment.java        | 46 +-
src/eu/siacs/conversations/utils/MessageParser.java            | 16 
6 files changed, 65 insertions(+), 96 deletions(-)

Detailed changes

res/layout/message_error.xml 🔗

@@ -1,54 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
-    android:padding="8dp">
-
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:background="@drawable/message_border"
-        android:layout_toRightOf="@+id/message_photo"
-     	android:layout_alignParentBottom="true"
-     	android:minHeight="48dp"
-     	>
-<LinearLayout
-    android:layout_width="wrap_content"
-    android:layout_height="fill_parent"
-    android:orientation="vertical"
-    android:background="#ededed"
-    android:padding="5dp">   
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="Username is already in use"
-        android:textSize="16sp"
-        android:id="@+id/message_body"
-        android:textColor="#e92727"
-        android:textStyle="bold"
-        android:typeface="monospace"/>
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:paddingTop="1dp"
-        android:text="@string/sending"
-        android:textColor="#8e8e8e"
-        android:textSize="12sp"
-        android:id="@+id/message_time"/>
-
-	</LinearLayout>
-</LinearLayout>
-    <ImageView
-        android:id="@+id/message_photo"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
-        android:layout_marginRight="-1.5dp"
-        android:padding="0dp"
-        android:src="@drawable/ic_profile"
-        android:scaleType="fitXY"/>
-	
-</RelativeLayout>

res/values/strings.xml 🔗

@@ -50,4 +50,6 @@
     <string name="action_attach_file">Attach file</string>
     <string name="not_in_roster">The contact is not in your roster. Would you like to add it?</string>
     <string name="add_contact">Add contact</string>
+    <string name="send_failed">unsuccessful delivery</string>
+    <string name="send_rejected">rejected</string>
 </resources>

src/eu/siacs/conversations/entities/Message.java 🔗

@@ -12,7 +12,8 @@ public class Message extends AbstractEntity {
 	public static final int STATUS_RECIEVED = 0;
 	public static final int STATUS_UNSEND = 1;
 	public static final int STATUS_SEND = 2;
-	public static final int STATUS_ERROR = 3;
+	public static final int STATUS_SEND_FAILED = 3;
+	public static final int STATUS_SEND_REJECTED = 4;
 
 	public static final int ENCRYPTION_NONE = 0;
 	public static final int ENCRYPTION_PGP = 1;

src/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -174,7 +174,8 @@ public class XmppConnectionService extends Service {
 					}
 				}
 			} else if (packet.getType() == MessagePacket.TYPE_ERROR) {
-				message = MessageParser.parseError(packet, account, service);
+				MessageParser.parseError(packet, account, service);
+				return;
 			} else if (packet.getType() == MessagePacket.TYPE_NORMAL) {
 				if (packet.hasChild("x")) {
 					Element x = packet.findChild("x");
@@ -667,13 +668,14 @@ public class XmppConnectionService extends Service {
 	synchronized public void sendMessage(Message message, String presence) {
 		Account account = message.getConversation().getAccount();
 		Conversation conv = message.getConversation();
+		MessagePacket packet = null;
 		boolean saveInDb = false;
 		boolean addToConversation = false;
+		boolean send = false;
 		if (account.getStatus() == Account.STATUS_ONLINE) {
 			if (message.getType() == Message.TYPE_IMAGE) {
 				mJingleConnectionManager.createNewConnection(message);
 			} else {
-				MessagePacket packet;
 				if (message.getEncryption() == Message.ENCRYPTION_OTR) {
 					if (!conv.hasValidOtrSession()) {
 						// starting otr session. messages will be send later
@@ -683,7 +685,7 @@ public class XmppConnectionService extends Service {
 						// accordingly
 						packet = prepareMessagePacket(account, message,
 								conv.getOtrSession());
-						account.getXmppConnection().sendMessagePacket(packet);
+						send = true;
 						message.setStatus(Message.STATUS_SEND);
 					}
 					saveInDb = true;
@@ -699,11 +701,11 @@ public class XmppConnectionService extends Service {
 					packet.setTo(message.getCounterpart());
 					packet.setBody("This is an XEP-0027 encryted message");
 					packet.addChild("x", "jabber:x:encrypted").setContent(message.getEncryptedBody());
-					account.getXmppConnection().sendMessagePacket(packet);
 					message.setStatus(Message.STATUS_SEND);
 					message.setEncryption(Message.ENCRYPTION_DECRYPTED);
 					saveInDb = true;
 					addToConversation = true;
+					send = true;
 				} else {
 					message.getConversation().endOtrIfNeeded();
 					// don't encrypt
@@ -712,9 +714,8 @@ public class XmppConnectionService extends Service {
 						saveInDb = true;
 						addToConversation = true;
 					}
-	
 					packet = prepareMessagePacket(account, message, null);
-					account.getXmppConnection().sendMessagePacket(packet);
+					send = true;
 				}
 			}
 		} else {
@@ -732,6 +733,9 @@ public class XmppConnectionService extends Service {
 				convChangedListener.onConversationListChanged();
 			}
 		}
+		if ((send)&&(packet!=null)) {
+			account.getXmppConnection().sendMessagePacket(packet);
+		}
 
 	}
 
@@ -786,6 +790,7 @@ public class XmppConnectionService extends Service {
 			packet.setTo(message.getCounterpart().split("/")[0]);
 			packet.setFrom(account.getJid());
 		}
+		packet.setId(message.getUuid());
 		return packet;
 	}
 
@@ -1365,4 +1370,27 @@ public class XmppConnectionService extends Service {
 		}
 
 	}
+	
+	public boolean markMessage(Account account, String recipient, String uuid, int status) {
+		boolean marked = false;
+		for(Conversation conversation : getConversations()) {
+			if (conversation.getContactJid().equals(recipient)&&conversation.getAccount().equals(account)) {
+				for(Message message : conversation.getMessages()) {
+					if (message.getUuid().equals(uuid)) {
+						markMessage(message, status);
+						marked = true;
+						break;
+					}
+				}
+				break;
+			}
+		}
+		return marked;
+	}
+	
+	public void markMessage(Message message, int status) {
+		message.setStatus(status);
+		databaseBackend.updateMessage(message);
+		convChangedListener.onConversationListChanged();
+	}
 }

src/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -179,19 +179,16 @@ public class ConversationFragment extends Fragment {
 
 			private static final int SENT = 0;
 			private static final int RECIEVED = 1;
-			private static final int ERROR = 2;
 
 			@Override
 			public int getViewTypeCount() {
-				return 3;
+				return 2;
 			}
 
 			@Override
 			public int getItemViewType(int position) {
-				if (getItem(position).getStatus() == Message.STATUS_RECIEVED) {
+				if (getItem(position).getStatus() <= Message.STATUS_RECIEVED) {
 					return RECIEVED;
-				} else if (getItem(position).getStatus() == Message.STATUS_ERROR) {
-					return ERROR;
 				} else {
 					return SENT;
 				}
@@ -230,14 +227,6 @@ public class ConversationFragment extends Fragment {
 
 						}
 						break;
-					case ERROR:
-						view = (View) inflater.inflate(R.layout.message_error,
-								null);
-						viewHolder.imageView = (ImageView) view
-								.findViewById(R.id.message_photo);
-						viewHolder.imageView.setImageBitmap(mBitmapCache
-								.getError());
-						break;
 					default:
 						viewHolder = null;
 						break;
@@ -283,30 +272,42 @@ public class ConversationFragment extends Fragment {
 							viewHolder.indicator.setVisibility(View.VISIBLE);
 						} else if ((item.getEncryption() == Message.ENCRYPTION_OTR)||(item.getEncryption() == Message.ENCRYPTION_DECRYPTED)) {
 							viewHolder.messageBody.setText(body.trim());
-							viewHolder.messageBody.setTextColor(0xff000000);
+							viewHolder.messageBody.setTextColor(0xff333333);
 							viewHolder.messageBody.setTypeface(null,
 									Typeface.NORMAL);
 							viewHolder.indicator.setVisibility(View.VISIBLE);
 						} else {
 							viewHolder.messageBody.setText(body.trim());
-							viewHolder.messageBody.setTextColor(0xff000000);
+							viewHolder.messageBody.setTextColor(0xff333333);
 							viewHolder.messageBody.setTypeface(null,
 									Typeface.NORMAL);
-							if (item.getStatus() != Message.STATUS_ERROR) {
-								viewHolder.indicator.setVisibility(View.GONE);
-							}
+							viewHolder.indicator.setVisibility(View.GONE);
 						}
 					} else {
 						viewHolder.indicator.setVisibility(View.GONE);
 					}
 				}
-				if (item.getStatus() == Message.STATUS_UNSEND) {
+				switch (item.getStatus()) {
+				case Message.STATUS_UNSEND:
 					viewHolder.time.setTypeface(null, Typeface.ITALIC);
+					viewHolder.time.setTextColor(0xFF8e8e8e);
 					viewHolder.time.setText("sending\u2026");
-				} else {
+					break;
+				case Message.STATUS_SEND_FAILED:
+					viewHolder.time.setText(getString(R.string.send_failed) + " \u00B7 " + UIHelper.readableTimeDifference(item
+							.getTimeSent()));
+					viewHolder.time.setTextColor(0xFFe92727);
+					viewHolder.time.setTypeface(null,Typeface.NORMAL);
+					break;
+				case Message.STATUS_SEND_REJECTED:
+					viewHolder.time.setText(getString(R.string.send_rejected));
+					viewHolder.time.setTextColor(0xFFe92727);
+					viewHolder.time.setTypeface(null,Typeface.NORMAL);
+					break;
+				default:
 					viewHolder.time.setTypeface(null, Typeface.NORMAL);
-					if ((item.getConversation().getMode() == Conversation.MODE_SINGLE)
-							|| (type != RECIEVED)) {
+					viewHolder.time.setTextColor(0xFF8e8e8e);
+					if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
 						viewHolder.time.setText(UIHelper
 								.readableTimeDifference(item.getTimeSent()));
 					} else {
@@ -315,6 +316,7 @@ public class ConversationFragment extends Fragment {
 								+ UIHelper.readableTimeDifference(item
 										.getTimeSent()));
 					}
+					break;
 				}
 				return view;
 			}

src/eu/siacs/conversations/utils/MessageParser.java 🔗

@@ -149,19 +149,9 @@ public class MessageParser {
 		return new Message(conversation,fullJid, message.findChild("body").getContent(), Message.ENCRYPTION_NONE,status);
 	}
 
-	public static Message parseError(MessagePacket packet, Account account, XmppConnectionService service) {
-		
-			String[] fromParts = packet.getFrom().split("/");
-	Conversation conversation = service.findOrCreateConversation(account, fromParts[0],false);
-	Element error = packet.findChild("error");
-	String errorName = error.getChildren().get(0).getName();
-	String displayError;
-	if (errorName.equals("service-unavailable")) {
-		displayError = "Contact is offline and does not have offline storage";
-	} else {
-		displayError = errorName.replace("-", " ");
-	}
-	return new Message(conversation, packet.getFrom(), displayError, Message.ENCRYPTION_NONE, Message.STATUS_ERROR);
+	public static void parseError(MessagePacket packet, Account account, XmppConnectionService service) {
+		String[] fromParts = packet.getFrom().split("/");
+		service.markMessage(account, fromParts[0], packet.getId(), Message.STATUS_SEND_FAILED);
 	}
 
 	public static String getPgpBody(MessagePacket packet) {