From 9664aea520f7980783682c7a33222303aa313853 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Tue, 16 Aug 2016 14:10:54 -0300
Subject: [PATCH] Introduce and use CardView and AuthorView for Blog Posts

---
 briar-android/build.gradle                    |   2 +
 briar-android/res/layout/author_view.xml      |  49 ++++++
 .../res/layout/list_item_blog_post.xml        | 148 +++++-------------
 briar-android/res/values/styles.xml           |   6 +
 .../android/blogs/BlogPostAdapter.java        |  32 ++--
 .../briarproject/android/util/AuthorView.java |  60 +++++++
 6 files changed, 163 insertions(+), 134 deletions(-)
 create mode 100644 briar-android/res/layout/author_view.xml
 create mode 100644 briar-android/src/org/briarproject/android/util/AuthorView.java

diff --git a/briar-android/build.gradle b/briar-android/build.gradle
index 8e75abfe40..adea13909d 100644
--- a/briar-android/build.gradle
+++ b/briar-android/build.gradle
@@ -27,6 +27,7 @@ dependencies {
 		exclude module: 'support-v4'
 		exclude module: 'recyclerview-v7'
 	}
+	compile "com.android.support:cardview-v7:$supportVersion"
 	compile('ch.acra:acra:4.8.5') {
 		exclude module: 'support-v4'
 		exclude module: 'support-annotations'
@@ -61,6 +62,7 @@ dependencyVerification {
 			'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
 			'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
 			'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
+			'com.android.support:cardview-v7:4595f1c4a28cfa083b6c0920ad4d49e1c2ca4b8302a955e548f68eb63b74931b',
 	]
 }
 
diff --git a/briar-android/res/layout/author_view.xml b/briar-android/res/layout/author_view.xml
new file mode 100644
index 0000000000..2f4a335641
--- /dev/null
+++ b/briar-android/res/layout/author_view.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
+	tools:showIn="@layout/list_item_blog_post">
+
+	<de.hdodenhof.circleimageview.CircleImageView
+		android:id="@+id/avatar"
+		style="@style/BriarAvatar"
+		android:layout_width="30dp"
+		android:layout_height="30dp"
+		android:layout_marginRight="@dimen/margin_medium"
+		tools:src="@drawable/ic_launcher"/>
+
+	<TextView
+		android:id="@+id/authorName"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignTop="@+id/avatar"
+		android:layout_toEndOf="@+id/avatar"
+		android:layout_toRightOf="@+id/avatar"
+		android:textColor="@color/briar_text_primary"
+		android:textSize="@dimen/text_size_tiny"
+		tools:text="Author Name"/>
+
+	<org.briarproject.android.util.TrustIndicatorView
+		android:id="@+id/trustIndicator"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_alignBottom="@+id/authorName"
+		android:layout_alignTop="@+id/authorName"
+		android:layout_marginLeft="@dimen/margin_small"
+		android:layout_toRightOf="@id/authorName"
+		android:scaleType="center"
+		tools:src="@drawable/trust_indicator_verified"/>
+
+	<TextView
+		android:id="@+id/dateView"
+		android:layout_width="wrap_content"
+		android:layout_height="wrap_content"
+		android:layout_below="@+id/authorName"
+		android:layout_toEndOf="@+id/avatar"
+		android:layout_toRightOf="@+id/avatar"
+		android:gravity="bottom"
+		android:textColor="@color/briar_text_primary"
+		android:textSize="@dimen/text_size_tiny"
+		tools:text="yesterday"/>
+
+</merge>
diff --git a/briar-android/res/layout/list_item_blog_post.xml b/briar-android/res/layout/list_item_blog_post.xml
index 0f7e1d5329..2408a1923f 100644
--- a/briar-android/res/layout/list_item_blog_post.xml
+++ b/briar-android/res/layout/list_item_blog_post.xml
@@ -1,118 +1,42 @@
 <?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout
+<android.support.v7.widget.CardView
+	style="@style/BriarCard"
 	xmlns:android="http://schemas.android.com/apk/res/android"
 	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
-	android:layout_height="wrap_content"
-	android:layout_marginLeft="@dimen/listitem_horizontal_margin"
-	android:layout_marginStart="@dimen/listitem_horizontal_margin"
-	android:layout_marginTop="@dimen/listitem_vertical_margin"
-	android:background="?attr/selectableItemBackground">
+	android:layout_height="wrap_content">
 
-	<de.hdodenhof.circleimageview.CircleImageView
-		android:id="@+id/avatar"
-		style="@style/BriarAvatar"
-		android:layout_width="30dp"
-		android:layout_height="30dp"
-		android:layout_marginBottom="@dimen/margin_medium"
-		android:layout_marginRight="@dimen/margin_medium"
-		tools:src="@drawable/ic_launcher"/>
-
-	<TextView
-		android:id="@+id/authorName"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignTop="@+id/avatar"
-		android:layout_toEndOf="@+id/avatar"
-		android:layout_toRightOf="@+id/avatar"
-		android:textColor="@color/briar_text_primary"
-		android:textSize="@dimen/text_size_tiny"
-		tools:text="Author Name"/>
-
-	<TextView
-		android:id="@+id/dateView"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignBottom="@id/avatar"
-		android:layout_below="@+id/authorName"
-		android:layout_toEndOf="@+id/avatar"
-		android:layout_toRightOf="@+id/avatar"
-		android:gravity="bottom"
-		android:textColor="@color/briar_text_primary"
-		android:textSize="@dimen/text_size_tiny"
-		tools:text="yesterday"/>
-
-	<TextView
-		android:id="@+id/newView"
-		style="@style/BriarTag"
-		android:layout_alignBottom="@+id/dateView"
-		android:layout_marginLeft="@dimen/margin_small"
-		android:layout_toRightOf="@+id/dateView"
-		android:text="@string/tag_new"
-		android:visibility="gone"/>
-
-	<org.briarproject.android.util.TrustIndicatorView
-		android:id="@+id/trustIndicator"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignBottom="@+id/authorName"
-		android:layout_alignTop="@+id/authorName"
-		android:layout_marginLeft="@dimen/margin_small"
-		android:layout_toRightOf="@+id/authorName"
-		android:scaleType="center"
-		tools:src="@drawable/trust_indicator_verified"/>
-
-	<ImageView
-		android:id="@+id/chatView"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_toLeftOf="@+id/commentView"
-		android:padding="@dimen/margin_small"
-		android:src="@drawable/ic_chat"
-		android:visibility="gone"/>
-
-	<ImageView
-		android:id="@+id/commentView"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_alignParentRight="true"
-		android:layout_marginRight="@dimen/listitem_horizontal_margin"
-		android:padding="@dimen/margin_small"
-		android:src="@drawable/ic_repeat"
-		android:visibility="gone"/>
-
-	<TextView
-		android:id="@+id/titleView"
+	<RelativeLayout
 		android:layout_width="match_parent"
-		android:layout_height="wrap_content"
-		android:layout_below="@+id/avatar"
-		android:layout_marginBottom="@dimen/margin_medium"
-		android:layout_marginEnd="@dimen/listitem_horizontal_margin"
-		android:layout_marginRight="@dimen/listitem_horizontal_margin"
-		android:ellipsize="end"
-		android:maxLines="3"
-		android:textColor="@color/briar_text_primary"
-		android:textSize="@dimen/text_size_large"
-		android:visibility="gone"
-		tools:text="This is a blog post title which can also be longer"/>
-
-	<TextView
-		android:id="@+id/bodyView"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content"
-		android:layout_below="@id/titleView"
-		android:layout_marginEnd="@dimen/margin_medium"
-		android:layout_marginRight="@dimen/listitem_horizontal_margin"
-		android:textColor="@color/briar_text_secondary"
-		android:textSize="@dimen/text_size_medium"
-		tools:text="This is a body text that shows the content of a blog post. This one is not short, but it is also not too long."/>
-
-	<View
-		style="@style/Divider.ForumList"
-		android:layout_alignParentLeft="true"
-		android:layout_alignParentStart="true"
-		android:layout_below="@+id/bodyView"
-		android:layout_marginTop="@dimen/listitem_vertical_margin"/>
-
-</RelativeLayout>
-
+		android:layout_height="wrap_content">
+
+		<org.briarproject.android.util.AuthorView
+			android:id="@+id/authorView"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_alignParentLeft="true"
+			android:layout_alignParentTop="true"
+			android:layout_marginBottom="@dimen/listitem_vertical_margin"
+			android:layout_toLeftOf="@+id/commentView"/>
+
+		<ImageView
+			android:id="@+id/commentView"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_alignParentRight="true"
+			android:layout_alignParentTop="true"
+			android:padding="@dimen/margin_small"
+			android:src="@drawable/ic_repeat"/>
+
+		<TextView
+			android:id="@+id/bodyView"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_below="@+id/authorView"
+			android:textColor="@color/briar_text_secondary"
+			android:textSize="@dimen/text_size_medium"
+			tools:text="This is a body text that shows the content of a blog post.\n\nThis one is not short, but it is also not too long."/>
+
+	</RelativeLayout>
+
+</android.support.v7.widget.CardView>
\ No newline at end of file
diff --git a/briar-android/res/values/styles.xml b/briar-android/res/values/styles.xml
index 98751d04c1..c432dddfa8 100644
--- a/briar-android/res/values/styles.xml
+++ b/briar-android/res/values/styles.xml
@@ -124,6 +124,12 @@
 		<item name="tabTextColor">@color/briar_text_primary_inverse</item>
 	</style>
 
+	<style name="BriarCard" parent="CardView">
+		<item name="cardUseCompatPadding">true</item>
+		<item name="contentPadding">@dimen/listitem_vertical_margin</item>
+		<item name="android:layout_margin">@dimen/margin_small</item>
+	</style>
+
 	<!-- This fixes the missing TextAppearance.Design.Counter.Overflow style -->
 	<style name="BriarTextCounter.Overflow" parent="TextAppearance.Design.Counter">
 		<item name="android:textColor">@color/briar_button_negative</item>
diff --git a/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java b/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java
index 44d971c83f..e6b2ee82ef 100644
--- a/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java
+++ b/briar-android/src/org/briarproject/android/blogs/BlogPostAdapter.java
@@ -6,19 +6,15 @@ import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.widget.ImageView;
 import android.widget.TextView;
 
 import org.briarproject.R;
-import org.briarproject.android.util.AndroidUtils;
-import org.briarproject.android.util.TrustIndicatorView;
-import org.briarproject.api.identity.Author;
+import org.briarproject.android.util.AuthorView;
 import org.briarproject.util.StringUtils;
 
 import java.util.Collection;
 
-import de.hdodenhof.circleimageview.CircleImageView;
-import im.delight.android.identicons.IdenticonDrawable;
-
 class BlogPostAdapter extends
 		RecyclerView.Adapter<BlogPostAdapter.BlogPostHolder> {
 
@@ -80,14 +76,10 @@ class BlogPostAdapter extends
 	public void onBindViewHolder(final BlogPostHolder ui, int position) {
 		final BlogPostItem post = getItem(position);
 
-		Author author = post.getAuthor();
-		IdenticonDrawable d = new IdenticonDrawable(author.getId().getBytes());
-		ui.avatar.setImageDrawable(d);
-		ui.author.setText(author.getName());
-		ui.trust.setTrustLevel(post.getAuthorStatus());
-
-		// date
-		ui.date.setText(AndroidUtils.formatDate(ctx, post.getTimestamp()));
+		// author and date
+		ui.author.setAuthor(post.getAuthor());
+		ui.author.setAuthorStatus(post.getAuthorStatus());
+		ui.author.setDate(post.getTimestamp());
 
 		// post body
 		ui.body.setText(StringUtils.fromUtf8(post.getBody()));
@@ -132,20 +124,16 @@ class BlogPostAdapter extends
 	static class BlogPostHolder extends RecyclerView.ViewHolder {
 
 		private final ViewGroup layout;
-		private final CircleImageView avatar;
-		private final TextView author;
-		private final TrustIndicatorView trust;
-		private final TextView date;
+		private final AuthorView author;
+		private final ImageView comment;
 		private final TextView body;
 
 		BlogPostHolder(View v) {
 			super(v);
 
 			layout = (ViewGroup) v;
-			avatar = (CircleImageView) v.findViewById(R.id.avatar);
-			author = (TextView) v.findViewById(R.id.authorName);
-			trust = (TrustIndicatorView) v.findViewById(R.id.trustIndicator);
-			date = (TextView) v.findViewById(R.id.dateView);
+			author = (AuthorView) v.findViewById(R.id.authorView);
+			comment = (ImageView) v.findViewById(R.id.commentView);
 			body = (TextView) v.findViewById(R.id.bodyView);
 		}
 	}
diff --git a/briar-android/src/org/briarproject/android/util/AuthorView.java b/briar-android/src/org/briarproject/android/util/AuthorView.java
new file mode 100644
index 0000000000..1f351c1c73
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/util/AuthorView.java
@@ -0,0 +1,60 @@
+package org.briarproject.android.util;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.widget.AppCompatTextView;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import org.briarproject.R;
+import org.briarproject.api.identity.Author;
+import org.briarproject.api.identity.Author.Status;
+
+import de.hdodenhof.circleimageview.CircleImageView;
+import im.delight.android.identicons.IdenticonDrawable;
+
+public class AuthorView extends RelativeLayout {
+
+	private final CircleImageView avatar;
+	private final TextView authorName;
+	private final TextView date;
+	private final TrustIndicatorView trustIndicator;
+
+	public AuthorView(Context context, AttributeSet attrs) {
+		super(context, attrs);
+
+		LayoutInflater inflater = (LayoutInflater) context
+				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+		inflater
+				.inflate(R.layout.author_view, this, true);
+
+		avatar = (CircleImageView) findViewById(R.id.avatar);
+		authorName = (TextView) findViewById(R.id.authorName);
+		date = (TextView) findViewById(R.id.dateView);
+		trustIndicator = (TrustIndicatorView) findViewById(R.id.trustIndicator);
+	}
+
+	public AuthorView(Context context) {
+		this(context, null);
+	}
+
+	public void setAuthor(Author author) {
+		authorName.setText(author.getName());
+		IdenticonDrawable d = new IdenticonDrawable(author.getId().getBytes());
+		avatar.setImageDrawable(d);
+	}
+
+	public void setAuthorStatus(Status status) {
+		trustIndicator.setTrustLevel(status);
+	}
+
+	public void setDate(long date) {
+		this.date.setText(AndroidUtils.formatDate(getContext(), date));
+	}
+
+}
-- 
GitLab