From 269eef57e9fd5a86203025b7a42c4931b984c2e7 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Sun, 9 Feb 2014 19:50:12 +0000
Subject: [PATCH] Speech bubble layout for private conversations.

---
 briar-android/AndroidManifest.xml             |   4 +-
 .../res/drawable/bubble_read_left.png         | Bin 0 -> 496 bytes
 .../res/drawable/bubble_read_right.png        | Bin 0 -> 507 bytes
 .../res/drawable/bubble_unread_left.png       | Bin 0 -> 341 bytes
 .../res/drawable/bubble_unread_right.png      | Bin 0 -> 322 bytes
 briar-android/res/values/color.xml            |   1 +
 briar-android/res/values/strings.xml          |   5 +-
 .../android/PasswordActivity.java             |   4 +-
 .../android/contact/ConversationActivity.java |   9 ++
 .../android/contact/ConversationAdapter.java  | 106 +++++++++++++-----
 .../contact/ReadPrivateMessageActivity.java   |   1 -
 .../contact/WritePrivateMessageActivity.java  |   2 -
 .../groups/WriteGroupPostActivity.java        |   2 -
 .../android/util/FixedHorizontalSpace.java    |  17 +++
 .../android/util/FixedVerticalSpace.java      |   6 +-
 15 files changed, 114 insertions(+), 43 deletions(-)
 create mode 100644 briar-android/res/drawable/bubble_read_left.png
 create mode 100644 briar-android/res/drawable/bubble_read_right.png
 create mode 100644 briar-android/res/drawable/bubble_unread_left.png
 create mode 100644 briar-android/res/drawable/bubble_unread_right.png
 create mode 100644 briar-android/src/org/briarproject/android/util/FixedHorizontalSpace.java

diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml
index 41757188f5..eab3a2c91e 100644
--- a/briar-android/AndroidManifest.xml
+++ b/briar-android/AndroidManifest.xml
@@ -78,7 +78,7 @@
 		<activity
 			android:name=".android.contact.ReadPrivateMessageActivity"
 			android:logo="@drawable/logo"
-			android:label="@string/app_name"
+			android:label="@string/read_message_title"
 		    android:parentActivityName=".android.contact.ContactListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
@@ -88,7 +88,7 @@
 		<activity
 			android:name=".android.contact.WritePrivateMessageActivity"
 			android:logo="@drawable/logo"
-			android:label="@string/new_message_title"
+			android:label="@string/write_message_title"
 		    android:parentActivityName=".android.contact.ContactListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
diff --git a/briar-android/res/drawable/bubble_read_left.png b/briar-android/res/drawable/bubble_read_left.png
new file mode 100644
index 0000000000000000000000000000000000000000..ec9ebc117d23037a8f4bf87b5c3eb1865fbd4c96
GIT binary patch
literal 496
zcmV<M0T2F(P)<h;3K|Lk000e1NJLTq000yK0015c1^@s6ED}Cz00001b5ch_0Itp)
z=>Px$s!2paR7l6ImAy*?F&M^^`yi$CDu@nF1t$eZ2RFZV!BG%LDGmw_4vxCJh&VVp
zIadDx2cd|Q=pZOg&O+~c&0X>)uY*)d?X{OnvnKp_p1dCqC1X16c6(AO_2i5L#yOt@
zfJXqBrM9pnNoF|b&sytgN-3e1HfsRzsg!ak{Y4eF9LMn*0KD|V2qDE3b~>GvBuVZN
zvC<1G1dO6+2>_aiIPl&vgzW%8Q)`|1#xW?so|N)RYfbuX8e5K{Xj=$zJq(mvVHk$T
zQp#K~LJ09j*t`@%>>?tu0tz9#G)+&_G_6xgbHg%$obz*~RNVxWS(Gpg?*U-h#OA1?
zpv`>$16HfmRnPM-im1zM8^+jy@B1fN<7M=ReQk3lgxE(!H?QKMja{i!4n5C1qLh-n
zYV(fXhLo~lt+0E7Ah>0WZ4p9}QA&+U8OQOa5aLE_?PvXIkp;T|054f<%s5kmAb4er
z%{z|sJ;;8ckSdqUZ;Y{Z*LA=8p|&wPrIh*rfQhbs>!3$Oztw8JYprWmx%_95QdugM
m7G2kUKty|mJy{(9K;sABXylLR396$20000<MNUMnLSTaYMAsAm

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable/bubble_read_right.png b/briar-android/res/drawable/bubble_read_right.png
new file mode 100644
index 0000000000000000000000000000000000000000..5bacbfa93a03a7afde2ae5001fc57d1b1054b9cd
GIT binary patch
literal 507
zcmV<X0R;YuP)<h;3K|Lk000e1NJLTq000yK0015c1^@s6ED}Cz00001b5ch_0Itp)
z=>Px$wMj%lR7l6I);)_9F&GE%e<sgtmU%-CEUW}k&{DCm^yLFsD`I`x2o@qXf)@6|
zVPWY95d8ouBFNQVVRMCWr3jm3XOo@0*v!gs$g;PY)Zs_|$@3(^Y&JX8TJK<_kvZqi
zIp_8li^auJK*kun_vei<UyU(ml0g7qj3I<@+8A@BwLY5+u2AoN=A8R6pU-b5g9Eg-
z)_!Q)_Ifh7LIG6P+RsX<Ysuhhgb?7I`>vF_KML3%6uPc^tF?ZZ3=ZN?thIYese8%b
z5bnC}os{y~C?EjD7~!0IskMGH3fRZbthKvJsaMP8lKwZ3PFfay{HGy=Qve=py~5-1
zz4yCP$}gjULwgjEF$N;qYntXpG8kh-p64%w5RZ}$CB_KGm={94uBz&JQrYwvi0DaG
zRgc%rrA_xN&-2@LU4KmKlo%rb7$L-+O|Z2qj4>k1vTib&+%3!U{ib_OYcLSem9i`k
zlJ3JE`y+(7RM+*vNy{obj&aV9gb=riqWHN@(bEtkq8aD>a#0k&x9!D$Am{v7(=-<t
xV_nj_+{gSjoldW&VgLXs<)^l7>#;sde*soi!Eeay0#g70002ovPDHLkV1fZS?oa>#

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable/bubble_unread_left.png b/briar-android/res/drawable/bubble_unread_left.png
new file mode 100644
index 0000000000000000000000000000000000000000..1152c1cbed6de35b5b077e7f33086f769a79e3e6
GIT binary patch
literal 341
zcmV-b0jmCqP)<h;3K|Lk000e1NJLTq000yK0015c1^@s6ED}Cz00001b5ch_0Itp)
z=>Px$4@pEpR7l6I)z2zLQ5c5twGB>@iIj;lU`!bv*I-7OxCZ4W3|xb`D^OA{K}s1I
zn8<_)C1*gM$G}#n-8uX0z1H_$z^`}x{Za~wx}cs%VN2?TYB2`P12@(w#g>6Pz+w<s
z2X1X77h6-G#+zk>z=rzbl=Q`hz_Tssb2WzQ`=n*|2Gt$ldluFS1oqVrJ7yMksE)cc
zYX#K`I4~pAz~erxT0!6x_{s(6CKXI6rK+k@3jEuS)SsM|ZHKZKb|{TI_*r~y8tAV2
z))no#r`y0N46K`O0<U3U-E<3hXj^{H2fM01hJpWM6Sxl<0b@;9)axc%`l1%qtB^6;
nfG_z=7&rjV!oYe@2kOZ$yqMfuipU{;00000NkvXXu0mjfd0>&6

literal 0
HcmV?d00001

diff --git a/briar-android/res/drawable/bubble_unread_right.png b/briar-android/res/drawable/bubble_unread_right.png
new file mode 100644
index 0000000000000000000000000000000000000000..29b4a618625b7aef1b8416c61df1995c74839d9f
GIT binary patch
literal 322
zcmV-I0lof-P)<h;3K|Lk000e1NJLTq000yK0015c1^@s6ED}Cz00001b5ch_0Itp)
z=>Px#{7FPXR7l6I)<G)8Q547V`!`Tz@=_+sfHC!k&l=1q6Kha5VPFmBR-j(W5~P%Y
zfr(6*Q1S-k`!#UWO-kPXcNXyJoX)xD+@hYS^CcC2#i=?-f&v%7ToM$x0v01+178BG
zNl^6;Sc!m5JOFD+P~aXIB|+6^brb=c?!T*>5wM9DU?&FF@+ZJvD#I4vRl6jpdJqMH
zH{j@}H#5y+=(_J}?VVvQ_e0%Jmb~4&DK)d#KWFhD*b}f78Ejyp4pVRW5m@iN9O|sy
zs2i#Ebqg#<P5^K{^;!L;o9Dn%<cz9k>O!wGT1!M7M}7_!JXU8@Uy(x~gOyS~0hXTJ
UTioCTVgLXD07*qoM6N<$g6|E4!~g&Q

literal 0
HcmV?d00001

diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml
index 90b7b6e696..384421bf8d 100644
--- a/briar-android/res/values/color.xml
+++ b/briar-android/res/values/color.xml
@@ -2,6 +2,7 @@
 <resources>
     <color name="home_screen_background">#FFFFFF</color>
     <color name="content_background">#FFFFFF</color>
+    <color name="conversation_background">#DDDDDD</color>
     <color name="unread_background">#FFFFFF</color>
     <color name="read_background">#EEEEEE</color>
 	<color name="horizontal_border">#CCCCCC</color>
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index baec15faf0..5574bd3751 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -55,11 +55,10 @@
     <string name="interfering">This could mean that someone is trying to interfere with your connection</string>
     <string name="contact_added_toast">Contact added</string>
     <string name="done_button">Done</string>
-    <string name="messages_title">Messages</string>
-    <string name="no_messages">(No messages)</string>
     <string name="format_from">From: %1$s</string>
     <string name="format_to">To: %1$s</string>
-    <string name="new_message_title">New Message</string>
+    <string name="read_message_title">Private Message</string>
+    <string name="write_message_title">New Private Message</string>
     <string name="from">From:</string>
     <string name="to">To:</string>
     <string name="anonymous">Anonymous</string>
diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java
index 393b981e97..c309261e66 100644
--- a/briar-android/src/org/briarproject/android/PasswordActivity.java
+++ b/briar-android/src/org/briarproject/android/PasswordActivity.java
@@ -86,7 +86,9 @@ public class PasswordActivity extends RoboActivity {
 		layout.addView(passwordEntry);
 
 		// Adjusting the padding of buttons and EditTexts has the wrong results
-		layout.addView(new FixedVerticalSpace(this));
+		FixedVerticalSpace space = new FixedVerticalSpace(this);
+		space.setHeight(pad);
+		layout.addView(space);
 
 		continueButton = new Button(this);
 		continueButton.setLayoutParams(WRAP_WRAP);
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 4fb17c5998..930193ce07 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -24,6 +24,7 @@ import javax.inject.Inject;
 import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.HorizontalBorder;
+import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.android.util.ListLoadingProgressBar;
 import org.briarproject.api.AuthorId;
 import org.briarproject.api.ContactId;
@@ -43,6 +44,8 @@ import org.briarproject.api.messaging.GroupId;
 import org.briarproject.api.messaging.MessageId;
 
 import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -100,6 +103,12 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		list = new ListView(this);
 		// Give me all the width and all the unused height
 		list.setLayoutParams(MATCH_WRAP_1);
+		// Make the dividers the same colour as the background
+		Resources res = getResources();
+		int background = res.getColor(R.color.conversation_background);
+		list.setBackgroundColor(background);
+		list.setDivider(new ColorDrawable(background));
+		list.setDividerHeight(LayoutUtils.getSeparatorWidth(this));
 		list.setAdapter(adapter);
 		list.setOnItemClickListener(this);
 		layout.addView(list);
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
index 0bf24a24f1..d0c2aa1c5b 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
@@ -1,29 +1,33 @@
 package org.briarproject.android.contact;
 
-import static android.view.Gravity.CENTER_HORIZONTAL;
-import static android.view.Gravity.CENTER_VERTICAL;
-import static android.widget.LinearLayout.HORIZONTAL;
-import static android.widget.LinearLayout.VERTICAL;
+import static android.view.Gravity.LEFT;
+import static android.view.Gravity.RIGHT;
+import static android.widget.RelativeLayout.ALIGN_PARENT_LEFT;
+import static android.widget.RelativeLayout.ALIGN_PARENT_RIGHT;
+import static android.widget.RelativeLayout.ALIGN_PARENT_TOP;
+import static android.widget.RelativeLayout.BELOW;
+import static android.widget.RelativeLayout.LEFT_OF;
+import static android.widget.RelativeLayout.RIGHT_OF;
 import static java.text.DateFormat.SHORT;
-import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
-import static org.briarproject.api.Author.Status.VERIFIED;
 
 import java.util.ArrayList;
 
 import org.briarproject.R;
-import org.briarproject.android.util.AuthorView;
+import org.briarproject.android.util.CommonLayoutParams;
 import org.briarproject.android.util.LayoutUtils;
 import org.briarproject.api.db.MessageHeader;
 import org.briarproject.util.StringUtils;
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.text.format.DateUtils;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.ImageButton;
-import android.widget.LinearLayout;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
 import android.widget.TextView;
 
 class ConversationAdapter extends ArrayAdapter<ConversationItem> {
@@ -43,46 +47,88 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
 		Context ctx = getContext();
 		Resources res = ctx.getResources();
 
-		LinearLayout layout = new LinearLayout(ctx);
-		layout.setOrientation(VERTICAL);
-		layout.setGravity(CENTER_HORIZONTAL);
+		RelativeLayout layout = new RelativeLayout(ctx);
+
 		int background;
 		if(header.isRead()) background = res.getColor(R.color.read_background);
 		else background = res.getColor(R.color.unread_background);
-		layout.setBackgroundColor(background);
-
-		LinearLayout headerLayout = new LinearLayout(ctx);
-		headerLayout.setOrientation(HORIZONTAL);
-		headerLayout.setGravity(CENTER_VERTICAL);
-
-		AuthorView authorView = new AuthorView(ctx);
-		authorView.setLayoutParams(WRAP_WRAP_1);
-		authorView.init(header.getAuthor().getName(), VERIFIED);
-		headerLayout.addView(authorView);
 
 		TextView date = new TextView(ctx);
+		date.setId(1);
 		date.setTextSize(14);
-		date.setPadding(0, pad, pad, pad);
+		date.setBackgroundColor(background);
+		date.setPadding(pad, pad, pad, 0);
 		long then = header.getTimestamp(), now = System.currentTimeMillis();
 		date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
-		headerLayout.addView(date);
-		layout.addView(headerLayout);
 
+		View content;
 		if(item.getBody() == null) {
 			TextView ellipsis = new TextView(ctx);
-			ellipsis.setPadding(pad, 0, pad, pad);
 			ellipsis.setText("\u2026");
-			layout.addView(ellipsis);
+			content = ellipsis;
 		} else if(header.getContentType().equals("text/plain")) {
 			TextView text = new TextView(ctx);
-			text.setPadding(pad, 0, pad, pad);
 			text.setText(StringUtils.fromUtf8(item.getBody()));
-			layout.addView(text);
+			content = text;
 		} else {
 			ImageButton attachment = new ImageButton(ctx);
-			attachment.setPadding(pad, 0, pad, pad);
 			attachment.setImageResource(R.drawable.content_attachment);
-			layout.addView(attachment);
+			content = attachment;
+		}
+		content.setId(2);
+		content.setBackgroundColor(background);
+		content.setPadding(pad, 0, pad, pad);
+
+		ImageView bubble = new ImageView(ctx);
+		bubble.setId(3);
+
+		if(header.isLocal()) {
+			Drawable d;
+			if(header.isRead())
+				d = res.getDrawable(R.drawable.bubble_read_right);
+			else d = res.getDrawable(R.drawable.bubble_unread_right);
+			bubble.setImageDrawable(d);
+			layout.setPadding(d.getIntrinsicWidth(), 0, 0, 0);
+			date.setGravity(RIGHT);
+			// Bubble point at the top right, date on top, content below
+			RelativeLayout.LayoutParams topRight =
+					CommonLayoutParams.wrapWrap();
+			topRight.addRule(ALIGN_PARENT_TOP);
+			topRight.addRule(ALIGN_PARENT_RIGHT);
+			layout.addView(bubble, topRight);
+			RelativeLayout.LayoutParams leftOf = CommonLayoutParams.wrapWrap();
+			leftOf.addRule(ALIGN_PARENT_TOP);
+			leftOf.addRule(ALIGN_PARENT_LEFT);
+			leftOf.addRule(LEFT_OF, 3);
+			layout.addView(date, leftOf);
+			RelativeLayout.LayoutParams below = CommonLayoutParams.wrapWrap();
+			below.addRule(ALIGN_PARENT_LEFT);
+			below.addRule(LEFT_OF, 3);
+			below.addRule(BELOW, 1);
+			layout.addView(content, below);
+		} else {
+			Drawable d;
+			if(header.isRead())
+				d = res.getDrawable(R.drawable.bubble_read_left);
+			else d = res.getDrawable(R.drawable.bubble_unread_left);
+			bubble.setImageDrawable(d);
+			layout.setPadding(0, 0, d.getIntrinsicWidth(), 0);
+			date.setGravity(LEFT);
+			// Bubble point at the top left, date on top, content below
+			RelativeLayout.LayoutParams topLeft = CommonLayoutParams.wrapWrap();
+			topLeft.addRule(ALIGN_PARENT_TOP);
+			topLeft.addRule(ALIGN_PARENT_LEFT);
+			layout.addView(bubble, topLeft);
+			RelativeLayout.LayoutParams rightOf = CommonLayoutParams.wrapWrap();
+			rightOf.addRule(ALIGN_PARENT_TOP);
+			rightOf.addRule(ALIGN_PARENT_RIGHT);
+			rightOf.addRule(RIGHT_OF, 3);
+			layout.addView(date, rightOf);
+			RelativeLayout.LayoutParams below = CommonLayoutParams.wrapWrap();
+			below.addRule(ALIGN_PARENT_RIGHT);
+			below.addRule(RIGHT_OF, 3);
+			below.addRule(BELOW, 1);
+			layout.addView(content, below);
 		}
 
 		return layout;
diff --git a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
index 7b223a7f27..4bf4e31d99 100644
--- a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
@@ -76,7 +76,6 @@ implements OnClickListener {
 		Intent i = getIntent();
 		contactName = i.getStringExtra("briar.CONTACT_NAME");
 		if(contactName == null) throw new IllegalStateException();
-		setTitle(contactName);
 		byte[] b = i.getByteArrayExtra("briar.LOCAL_AUTHOR_ID");
 		if(b == null) throw new IllegalStateException();
 		localAuthorId = new AuthorId(b);
diff --git a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
index 48e9451b74..b04b8a5905 100644
--- a/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/WritePrivateMessageActivity.java
@@ -99,8 +99,6 @@ implements OnClickListener {
 		layout.setOrientation(VERTICAL);
 
 		RelativeLayout header = new RelativeLayout(this);
-		header.setLayoutParams(MATCH_WRAP);
-
 		int pad = LayoutUtils.getPadding(this);
 
 		from = new TextView(this);
diff --git a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
index 071195d23f..b822d48e69 100644
--- a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
@@ -112,8 +112,6 @@ implements OnItemSelectedListener, OnClickListener {
 		layout.setOrientation(VERTICAL);
 
 		RelativeLayout header = new RelativeLayout(this);
-		header.setLayoutParams(MATCH_WRAP);
-
 		int pad = LayoutUtils.getPadding(this);
 
 		TextView from = new TextView(this);
diff --git a/briar-android/src/org/briarproject/android/util/FixedHorizontalSpace.java b/briar-android/src/org/briarproject/android/util/FixedHorizontalSpace.java
new file mode 100644
index 0000000000..45810af1bb
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/util/FixedHorizontalSpace.java
@@ -0,0 +1,17 @@
+package org.briarproject.android.util;
+
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+
+public class FixedHorizontalSpace extends View {
+
+	public FixedHorizontalSpace(Context ctx) {
+		super(ctx);
+	}
+
+	public void setWidth(int width) {
+		setLayoutParams(new LayoutParams(width, WRAP_CONTENT));
+	}
+}
diff --git a/briar-android/src/org/briarproject/android/util/FixedVerticalSpace.java b/briar-android/src/org/briarproject/android/util/FixedVerticalSpace.java
index da923d84b8..e9625f3484 100644
--- a/briar-android/src/org/briarproject/android/util/FixedVerticalSpace.java
+++ b/briar-android/src/org/briarproject/android/util/FixedVerticalSpace.java
@@ -9,7 +9,9 @@ public class FixedVerticalSpace extends View {
 
 	public FixedVerticalSpace(Context ctx) {
 		super(ctx);
-		int pad = LayoutUtils.getPadding(ctx);
-		setLayoutParams(new LayoutParams(WRAP_CONTENT, pad));
+	}
+
+	public void setHeight(int height) {
+		setLayoutParams(new LayoutParams(WRAP_CONTENT, height));
 	}
 }
-- 
GitLab