From 269eef57e9fd5a86203025b7a42c4931b984c2e7 Mon Sep 17 00:00:00 2001 From: akwizgran 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 41757188f..eab3a2c91 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -78,7 +78,7 @@ 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$20000Px$wMj%lR7l6I);)_9F&GE%evF_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(=-#;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)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+wz=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&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)Px#{7FPXR7l6I)5wM9DU?&FF@+ZJvD#I4vRl6jpdJqMH zH{j@}H#5y+=(_J}?VVvQ_e0%Jmb~4&DK)d#KWFhD*b}f78Ejyp4pVRW5m@iN9O|sy zs2i#Ebqg#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 90b7b6e69..384421bf8 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -2,6 +2,7 @@ #FFFFFF #FFFFFF + #DDDDDD #FFFFFF #EEEEEE #CCCCCC diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index baec15faf..5574bd375 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -55,11 +55,10 @@ This could mean that someone is trying to interfere with your connection Contact added Done - Messages - (No messages) From: %1$s To: %1$s - New Message + Private Message + New Private Message From: To: Anonymous diff --git a/briar-android/src/org/briarproject/android/PasswordActivity.java b/briar-android/src/org/briarproject/android/PasswordActivity.java index 393b981e9..c309261e6 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 4fb17c599..930193ce0 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 0bf24a24f..d0c2aa1c5 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 { @@ -43,46 +47,88 @@ class ConversationAdapter extends ArrayAdapter { 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 7b223a7f2..4bf4e31d9 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 48e9451b7..b04b8a590 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 071195d23..b822d48e6 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 000000000..45810af1b --- /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 da923d84b..e9625f348 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)); } }