experimental gui to display read status

iNPUTmice created

Change summary

res/layout/message_status.xml                           | 49 +++++++
src/eu/siacs/conversations/entities/Message.java        | 12 +
src/eu/siacs/conversations/ui/ConversationFragment.java | 72 +++++++++-
3 files changed, 122 insertions(+), 11 deletions(-)

Detailed changes

res/layout/message_status.xml 🔗

@@ -0,0 +1,49 @@
+<?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:paddingTop="6dp"
+    android:paddingBottom="6dp"
+    android:paddingRight="6dp"
+    android:paddingLeft="24dp">
+
+    <LinearLayout
+        android:id="@+id/linearLayout1"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_toRightOf="@+id/message_photo"
+        android:background="@drawable/message_border"
+        android:minHeight="dp"
+        android:visibility="gone">
+
+        <LinearLayout
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:background="#ededed"
+            android:orientation="vertical">
+            
+            <TextView
+                android:layout_gravity="center_vertical"
+                android:id="@+id/message_body"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:textColor="#333333"
+                android:textSize="14sp"
+                android:text="your contact has read up to this point"/>
+        </LinearLayout>
+    </LinearLayout>
+
+    <ImageView
+        android:id="@+id/message_photo"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginRight="-1.5dp"
+        android:padding="0dp"
+        android:scaleType="fitXY"
+        android:src="@drawable/ic_profile" />
+
+</RelativeLayout>

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

@@ -32,6 +32,7 @@ public class Message extends AbstractEntity {
 	public static final int TYPE_TEXT = 0;
 	public static final int TYPE_IMAGE = 1;
 	public static final int TYPE_AUDIO = 2;
+	public static final int TYPE_STATUS = 3;
 
 	public static String CONVERSATION = "conversationUuid";
 	public static String COUNTERPART = "counterpart";
@@ -54,6 +55,10 @@ public class Message extends AbstractEntity {
 	protected transient Conversation conversation = null;
 	
 	protected transient JingleConnection jingleConnection = null;
+	
+	private Message() {
+		
+	}
 
 	public Message(Conversation conversation, String body, int encryption) {
 		this(java.util.UUID.randomUUID().toString(), conversation.getUuid(),
@@ -205,4 +210,11 @@ public class Message extends AbstractEntity {
 	public JingleConnection getJingleConnection() {
 		return this.jingleConnection;
 	}
+	
+	public static Message createStatusMessage(Conversation conversation) {
+		Message message = new Message();
+		message.setType(Message.TYPE_STATUS);
+		message.setConversation(conversation);
+		return message;
+	}
 }

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

@@ -170,15 +170,18 @@ public class ConversationFragment extends Fragment {
 
 			private static final int SENT = 0;
 			private static final int RECIEVED = 1;
+			private static final int STATUS = 2;
 
 			@Override
 			public int getViewTypeCount() {
-				return 2;
+				return 3;
 			}
 
 			@Override
 			public int getItemViewType(int position) {
-				if (getItem(position).getStatus() <= Message.STATUS_RECIEVED) {
+				if (getItem(position).getType() == Message.TYPE_STATUS) {
+					return STATUS;
+				} else 	if (getItem(position).getStatus() <= Message.STATUS_RECIEVED) {
 					return RECIEVED;
 				} else {
 					return SENT;
@@ -360,6 +363,15 @@ public class ConversationFragment extends Fragment {
 						viewHolder.contact_picture = (ImageView) view
 								.findViewById(R.id.message_photo);
 						viewHolder.contact_picture.setImageBitmap(selfBitmap);
+						viewHolder.indicator = (ImageView) view
+								.findViewById(R.id.security_indicator);
+						viewHolder.image = (ImageView) view
+								.findViewById(R.id.message_image);
+						viewHolder.messageBody = (TextView) view
+								.findViewById(R.id.message_body);
+						viewHolder.time = (TextView) view
+								.findViewById(R.id.message_time);
+						view.setTag(viewHolder);
 						break;
 					case RECIEVED:
 						view = (View) inflater.inflate(
@@ -381,24 +393,46 @@ public class ConversationFragment extends Fragment {
 											getActivity()
 													.getApplicationContext()));
 
+						}
+						viewHolder.indicator = (ImageView) view
+								.findViewById(R.id.security_indicator);
+						viewHolder.image = (ImageView) view
+								.findViewById(R.id.message_image);
+						viewHolder.messageBody = (TextView) view
+								.findViewById(R.id.message_body);
+						viewHolder.time = (TextView) view
+								.findViewById(R.id.message_time);
+						view.setTag(viewHolder);
+						break;
+					case STATUS:
+						view = (View) inflater.inflate(
+								R.layout.message_status, null);
+						viewHolder.contact_picture = (ImageView) view
+								.findViewById(R.id.message_photo);
+						if (item.getConversation().getMode() == Conversation.MODE_SINGLE) {
+
+							viewHolder.contact_picture
+									.setImageBitmap(mBitmapCache.get(
+											item.getConversation().getName(
+													useSubject), item
+													.getConversation()
+													.getContact(),
+											getActivity()
+													.getApplicationContext()));
+
 						}
 						break;
 					default:
 						viewHolder = null;
 						break;
 					}
-					viewHolder.indicator = (ImageView) view
-							.findViewById(R.id.security_indicator);
-					viewHolder.image = (ImageView) view
-							.findViewById(R.id.message_image);
-					viewHolder.messageBody = (TextView) view
-							.findViewById(R.id.message_body);
-					viewHolder.time = (TextView) view
-							.findViewById(R.id.message_time);
-					view.setTag(viewHolder);
 				} else {
 					viewHolder = (ViewHolder) view.getTag();
 				}
+				
+				if (type == STATUS) {
+					return view;
+				}
 
 				if (type == RECIEVED) {
 					if (item.getConversation().getMode() == Conversation.MODE_MULTI) {
@@ -620,6 +654,7 @@ public class ConversationFragment extends Fragment {
 			}
 			this.messageList.clear();
 			this.messageList.addAll(this.conversation.getMessages());
+			updateStatusMessages();
 			this.messageListAdapter.notifyDataSetChanged();
 			if (conversation.getMode() == Conversation.MODE_SINGLE) {
 				if (messageList.size() >= 1) {
@@ -649,6 +684,21 @@ public class ConversationFragment extends Fragment {
 			}
 		}
 	}
+	
+	protected void updateStatusMessages() {
+		if (conversation.getMode() == Conversation.MODE_SINGLE) {
+			for(int i = this.messageList.size() - 1; i >= 0; --i) {
+				if (this.messageList.get(i).getStatus() == Message.STATUS_RECIEVED) {
+					return;
+				} else {
+					if (this.messageList.get(i).getStatus() == Message.STATUS_SEND_DISPLAYED) {
+						this.messageList.add(i+1, Message.createStatusMessage(conversation));
+						return;
+					}
+				}
+			}
+		}
+	}
 
 	protected void makeFingerprintWarning(int latestEncryption) {
 		final LinearLayout fingerprintWarning = (LinearLayout) getView()