changed message bubble appearance

Raphael Pohl created

Change summary

art/message_bubble_received.svg                                     | 165 
art/message_bubble_sent.svg                                         | 165 
art/render.rb                                                       | 128 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java |  37 
src/main/res/drawable-hdpi/ic_secure_indicator.png                  |   0 
src/main/res/drawable-hdpi/ic_secure_indicator_white.png            |   0 
src/main/res/drawable-hdpi/message_bubble_received.9.png            |   0 
src/main/res/drawable-hdpi/message_bubble_sent.9.png                |   0 
src/main/res/drawable-mdpi/ic_secure_indicator.png                  |   0 
src/main/res/drawable-mdpi/ic_secure_indicator_white.png            |   0 
src/main/res/drawable-mdpi/message_bubble_received.9.png            |   0 
src/main/res/drawable-mdpi/message_bubble_sent.9.png                |   0 
src/main/res/drawable-xhdpi/ic_secure_indicator.png                 |   0 
src/main/res/drawable-xhdpi/ic_secure_indicator_white.png           |   0 
src/main/res/drawable-xhdpi/message_bubble_received.9.png           |   0 
src/main/res/drawable-xhdpi/message_bubble_sent.9.png               |   0 
src/main/res/drawable-xxhdpi/ic_secure_indicator.png                |   0 
src/main/res/drawable-xxhdpi/ic_secure_indicator_white.png          |   0 
src/main/res/drawable-xxhdpi/message_bubble_received.9.png          |   0 
src/main/res/drawable-xxhdpi/message_bubble_sent.9.png              |   0 
src/main/res/drawable-xxxhdpi/message_bubble_received.9.png         |   0 
src/main/res/drawable-xxxhdpi/message_bubble_sent.9.png             |   0 
src/main/res/drawable/account_image_border.xml                      |   0 
src/main/res/layout/activity_publish_profile_picture.xml            |   2 
src/main/res/layout/fragment_conversation.xml                       |   5 
src/main/res/layout/message_received.xml                            |  55 
src/main/res/layout/message_sent.xml                                |  50 
src/main/res/layout/message_status.xml                              |  10 
src/main/res/values/dimens.xml                                      |   1 
29 files changed, 521 insertions(+), 97 deletions(-)

Detailed changes

art/message_bubble_received.svg 🔗

@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="36"
+   height="26"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.5 r10040"
+   sodipodi:docname="message_bubble_received.svg">
+  <defs
+     id="defs4">
+    <filter
+       x="-0.25"
+       y="-0.25"
+       width="1.5"
+       height="1.5"
+       inkscape:label="Drop Shadow"
+       id="filter3811"
+       color-interpolation-filters="sRGB">
+      <feFlood
+         flood-opacity="0.25"
+         flood-color="rgb(0,0,0)"
+         result="flood"
+         id="feFlood3813" />
+      <feComposite
+         in="flood"
+         in2="SourceGraphic"
+         operator="in"
+         result="composite1"
+         id="feComposite3815" />
+      <feGaussianBlur
+         stdDeviation="0.5"
+         result="blur"
+         id="feGaussianBlur3817" />
+      <feOffset
+         dx="0"
+         dy="1"
+         result="offset"
+         id="feOffset3819" />
+      <feComposite
+         in="SourceGraphic"
+         in2="offset"
+         operator="over"
+         result="composite2"
+         id="feComposite3821" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="16"
+     inkscape:cx="25.745257"
+     inkscape:cy="9.618802"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="989"
+     inkscape:window-height="755"
+     inkscape:window-x="22"
+     inkscape:window-y="16"
+     inkscape:window-maximized="0"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     guidecolor="#000000"
+     guideopacity="0.49803922">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2985"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="1px"
+       spacingy="1px"
+       originx="0px"
+       originy="0px"
+       color="#0000ff"
+       opacity="0.03137255" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="20,26"
+       id="guide3060" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="24,26"
+       id="guide3062" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="36,22"
+       id="guide3064" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="36,6"
+       id="guide3066" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="26,0"
+       id="guide3068" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="18,0"
+       id="guide3070" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="0,10"
+       id="guide3074" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="0,8"
+       id="guide3076" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer"
+     inkscape:groupmode="layer"
+     id="layer"
+     transform="translate(0,-2)">
+    <g
+       id="g3759"
+       style="fill:#259b24;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
+      <path
+         style="display:none"
+         d="m 8,6 c 2,2 4,6 4,10 L 16,6 z"
+         id="path3805"
+         inkscape:connector-curvature="0"
+         transform="translate(0,2)"
+         sodipodi:nodetypes="cccc" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path2989"
+         d="M 4,4 16,16 16,4 z"
+         sodipodi:nodetypes="cccc" />
+      <rect
+         ry="2"
+         y="4"
+         x="12"
+         height="20"
+         width="20"
+         id="rect2987" />
+    </g>
+  </g>
+</svg>

art/message_bubble_sent.svg 🔗

@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="36"
+   height="26"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.5 r10040"
+   sodipodi:docname="message_bubble_sent.svg">
+  <defs
+     id="defs4">
+    <filter
+       x="-0.25"
+       y="-0.25"
+       width="1.5"
+       height="1.5"
+       inkscape:label="Drop Shadow"
+       id="filter3811"
+       color-interpolation-filters="sRGB">
+      <feFlood
+         flood-opacity="0.25"
+         flood-color="rgb(0,0,0)"
+         result="flood"
+         id="feFlood3813" />
+      <feComposite
+         in="flood"
+         in2="SourceGraphic"
+         operator="in"
+         result="composite1"
+         id="feComposite3815" />
+      <feGaussianBlur
+         stdDeviation="0.5"
+         result="blur"
+         id="feGaussianBlur3817" />
+      <feOffset
+         dx="0"
+         dy="1"
+         result="offset"
+         id="feOffset3819" />
+      <feComposite
+         in="SourceGraphic"
+         in2="offset"
+         operator="over"
+         result="composite2"
+         id="feComposite3821" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="16"
+     inkscape:cx="14.269338"
+     inkscape:cy="16.118802"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="989"
+     inkscape:window-height="755"
+     inkscape:window-x="434"
+     inkscape:window-y="16"
+     inkscape:window-maximized="0"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     guidecolor="#404040"
+     guideopacity="0.49803922">
+    <inkscape:grid
+       type="xygrid"
+       id="grid2985"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="1px"
+       spacingy="1px"
+       originx="0px"
+       originy="0px"
+       color="#0000ff"
+       opacity="0.03137255" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="12,26"
+       id="guide3146" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="16,26"
+       id="guide3148" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="36,22"
+       id="guide3150" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="36,6"
+       id="guide3152" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="18,0"
+       id="guide3154" />
+    <sodipodi:guide
+       orientation="1,0"
+       position="10,0"
+       id="guide3160" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="0,20"
+       id="guide3162" />
+    <sodipodi:guide
+       orientation="0,1"
+       position="0,18"
+       id="guide3164" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer"
+     inkscape:groupmode="layer"
+     id="layer"
+     transform="translate(0,-2)">
+    <g
+       id="g3759"
+       style="fill:#fafafa;fill-opacity:1;stroke:none;fill-rule:nonzero;filter:url(#filter3811)">
+      <path
+         style="display:none"
+         d="M 28,18 C 26,16 24,12 24,8 l -4,10 z"
+         id="path3809"
+         inkscape:connector-curvature="0"
+         transform="translate(0,2)"
+         sodipodi:nodetypes="cccc" />
+      <path
+         inkscape:connector-curvature="0"
+         id="path2989"
+         d="m 20,12 0,12 12,0 z"
+         sodipodi:nodetypes="cccc" />
+      <rect
+         ry="2"
+         y="4"
+         x="4"
+         height="20"
+         width="20"
+         id="rect2987" />
+    </g>
+  </g>
+</svg>

art/render.rb 🔗

@@ -1,11 +1,15 @@
 #!/bin/env ruby
-resolutions={
-	'mdpi'=> 1,
+
+require 'xml'
+
+resolutions = {
+	'mdpi' => 1,
 	'hdpi' => 1.5,
 	'xhdpi' => 2,
 	'xxhdpi' => 3,
 	'xxxhdpi' => 4,
 	}
+
 images = {
 	'conversations_baloon.svg' => ['ic_launcher', 48],
 	'conversations_mono.svg' => ['ic_notification', 24],
@@ -14,38 +18,110 @@ images = {
 	'ic_send_text_online.svg' => ['ic_send_text_online', 36],
 	'ic_send_text_away.svg' => ['ic_send_text_away', 36],
 	'ic_send_text_dnd.svg' => ['ic_send_text_dnd', 36],
-        'ic_send_photo_online.svg' => ['ic_send_photo_online', 36],
-        'ic_send_photo_offline.svg' => ['ic_send_photo_offline', 36],
-        'ic_send_photo_away.svg' => ['ic_send_photo_away', 36],
-        'ic_send_photo_dnd.svg' => ['ic_send_photo_dnd', 36],
+	'ic_send_photo_online.svg' => ['ic_send_photo_online', 36],
+	'ic_send_photo_offline.svg' => ['ic_send_photo_offline', 36],
+	'ic_send_photo_away.svg' => ['ic_send_photo_away', 36],
+	'ic_send_photo_dnd.svg' => ['ic_send_photo_dnd', 36],
 	'ic_send_location_online.svg' => ['ic_send_location_online', 36],
-        'ic_send_location_offline.svg' => ['ic_send_location_offline', 36],
-        'ic_send_location_away.svg' => ['ic_send_location_away', 36],
-        'ic_send_location_dnd.svg' => ['ic_send_location_dnd', 36],
+	'ic_send_location_offline.svg' => ['ic_send_location_offline', 36],
+	'ic_send_location_away.svg' => ['ic_send_location_away', 36],
+	'ic_send_location_dnd.svg' => ['ic_send_location_dnd', 36],
 	'ic_send_voice_online.svg' => ['ic_send_voice_online', 36],
-        'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36],
-        'ic_send_voice_away.svg' => ['ic_send_voice_away', 36],
-        'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36],
+	'ic_send_voice_offline.svg' => ['ic_send_voice_offline', 36],
+	'ic_send_voice_away.svg' => ['ic_send_voice_away', 36],
+	'ic_send_voice_dnd.svg' => ['ic_send_voice_dnd', 36],
 	'ic_send_cancel_online.svg' => ['ic_send_cancel_online', 36],
-        'ic_send_cancel_offline.svg' => ['ic_send_cancel_offline', 36],
-        'ic_send_cancel_away.svg' => ['ic_send_cancel_away', 36],
-        'ic_send_cancel_dnd.svg' => ['ic_send_cancel_dnd', 36],
-        'ic_send_picture_online.svg' => ['ic_send_picture_online', 36],
-        'ic_send_picture_offline.svg' => ['ic_send_picture_offline', 36],
-        'ic_send_picture_away.svg' => ['ic_send_picture_away', 36],
-        'ic_send_picture_dnd.svg' => ['ic_send_picture_dnd', 36],
+	'ic_send_cancel_offline.svg' => ['ic_send_cancel_offline', 36],
+	'ic_send_cancel_away.svg' => ['ic_send_cancel_away', 36],
+	'ic_send_cancel_dnd.svg' => ['ic_send_cancel_dnd', 36],
+	'ic_send_picture_online.svg' => ['ic_send_picture_online', 36],
+	'ic_send_picture_offline.svg' => ['ic_send_picture_offline', 36],
+	'ic_send_picture_away.svg' => ['ic_send_picture_away', 36],
+	'ic_send_picture_dnd.svg' => ['ic_send_picture_dnd', 36],
 	'md_switch_thumb_disable.svg' => ['switch_thumb_disable', 48],
 	'md_switch_thumb_off_normal.svg' => ['switch_thumb_off_normal', 48],
 	'md_switch_thumb_off_pressed.svg' => ['switch_thumb_off_pressed', 48],
 	'md_switch_thumb_on_normal.svg' => ['switch_thumb_on_normal', 48],
 	'md_switch_thumb_on_pressed.svg' => ['switch_thumb_on_pressed', 48],
+	'message_bubble_received.svg' => ['message_bubble_received.9', 0],
+	'message_bubble_sent.svg' => ['message_bubble_sent.9', 0],
 	}
-images.each do |source, result|
-	resolutions.each do |name, factor|
-		size = factor * result[1]
-		path = "../src/main/res/drawable-#{name}/#{result[0]}.png"
-		cmd = "inkscape -e #{path} -C -h #{size} -w #{size} #{source}"
-		puts cmd
-		system cmd
+
+# Executable paths for Mac OSX
+# "/Applications/Inkscape.app/Contents/Resources/bin/inkscape"
+
+inkscape = "inkscape"
+imagemagick = "convert"
+
+def execute_cmd(cmd)
+	puts cmd
+	system cmd
+end
+
+images.each do |source_filename, settings|
+	svg_content = File.read(source_filename)
+
+	svg = XML::Document.string(svg_content)
+	base_width = svg.root["width"].to_i
+	base_height = svg.root["height"].to_i
+
+	guides = svg.find(".//sodipodi:guide")
+
+	resolutions.each do |resolution, factor|
+		output_filename, base_size = settings
+
+		if base_size > 0
+			width = factor * base_size
+			height = factor * base_size
+		else
+			width = factor * base_width
+			height = factor * base_height
+		end
+
+		path = "../src/main/res/drawable-#{resolution}/#{output_filename}.png"
+		execute_cmd "#{inkscape} -f #{source_filename} -z -C -w #{width} -h #{height} -e #{path}"
+
+		top = []
+		right = []
+		bottom = []
+		left = []
+
+		guides.each do |guide|
+			orientation = guide["orientation"]
+			x, y = guide["position"].split(",")
+			x, y = x.to_i, y.to_i
+
+			if orientation == "1,0" and y == base_height
+				top.push(x * factor)
+			end
+
+			if orientation == "0,1" and x == base_width
+				right.push((base_height - y) * factor)
+			end
+
+			if orientation == "1,0" and y == 0
+				bottom.push(x * factor)
+			end
+
+			if orientation == "0,1" and x == 0
+				left.push((base_height - y) * factor)
+			end
+		end
+
+		next if top.length != 2
+		next if right.length != 2
+		next if bottom.length != 2
+		next if left.length != 2
+
+		execute_cmd "#{imagemagick} -background none PNG32:#{path} -gravity center -extent #{width+2}x#{height+2} PNG32:#{path}"
+
+		draw_format = "-draw \"rectangle %d,%d %d,%d\""
+		top_line = draw_format % [top.min + 1, 0, top.max, 0]
+		right_line = draw_format % [width + 1, right.min + 1, width + 1, right.max]
+		bottom_line = draw_format % [bottom.min + 1, height + 1, bottom.max, height + 1]
+		left_line = draw_format % [0, left.min + 1, 0, left.max]
+		draws = "#{top_line} #{right_line} #{bottom_line} #{left_line}"
+
+		execute_cmd "#{imagemagick} -background none PNG32:#{path} -fill black -stroke none #{draws} PNG32:#{path}"
 	end
 end

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -81,15 +81,31 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 		return 3;
 	}
 
-	@Override
-	public int getItemViewType(int position) {
-		if (getItem(position).getType() == Message.TYPE_STATUS) {
+	public int getItemViewType(Message message) {
+		if (message.getType() == Message.TYPE_STATUS) {
 			return STATUS;
-		} else if (getItem(position).getStatus() <= Message.STATUS_RECEIVED) {
+		} else if (message.getStatus() <= Message.STATUS_RECEIVED) {
 			return RECEIVED;
-		} else {
-			return SENT;
 		}
+
+		return SENT;
+	}
+
+	@Override
+	public int getItemViewType(int position) {
+		return this.getItemViewType(getItem(position));
+	}
+
+	private int getMessageTextColor(Message message) {
+		int type = this.getItemViewType(message);
+
+		if (type == SENT) {
+			return activity.getResources().getColor(R.color.black87);
+		} else if (type == RECEIVED) {
+			return activity.getResources().getColor(R.color.white);
+		}
+
+		return activity.getPrimaryTextColor();
 	}
 
 	private void displayStatus(ViewHolder viewHolder, Message message) {
@@ -150,7 +166,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 		if (error) {
 			viewHolder.time.setTextColor(activity.getWarningTextColor());
 		} else {
-			viewHolder.time.setTextColor(activity.getSecondaryTextColor());
+			viewHolder.time.setTextColor(this.getMessageTextColor(message));
 		}
 		if (message.getEncryption() == Message.ENCRYPTION_NONE) {
 			viewHolder.indicator.setVisibility(View.GONE);
@@ -294,7 +310,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 		} else {
 			viewHolder.messageBody.setText("");
 		}
-		viewHolder.messageBody.setTextColor(activity.getPrimaryTextColor());
+		viewHolder.messageBody.setTextColor(this.getMessageTextColor(message));
 		viewHolder.messageBody.setTypeface(null, Typeface.NORMAL);
 		viewHolder.messageBody.setTextIsSelectable(true);
 	}
@@ -363,8 +379,9 @@ public class MessageAdapter extends ArrayAdapter<Message> {
 			scalledW = (int) target;
 			scalledH = (int) (params.height / ((double) params.width / target));
 		}
-		viewHolder.image.setLayoutParams(new LinearLayout.LayoutParams(
-				scalledW, scalledH));
+		LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(scalledW, scalledH);
+		layoutParams.setMargins(0, (int)(metrics.density * 4), 0, (int)(metrics.density * 4));
+		viewHolder.image.setLayoutParams(layoutParams);
 		activity.loadBitmap(message, viewHolder.image);
 		viewHolder.image.setOnClickListener(new OnClickListener() {
 

src/main/res/layout/activity_publish_profile_picture.xml 🔗

@@ -12,7 +12,7 @@
         android:layout_centerHorizontal="true"
         android:layout_marginBottom="8dp"
         android:layout_marginTop="24dp"
-        android:background="@drawable/message_border" >
+        android:background="@drawable/account_image_border" >
 
         <ImageView
             android:id="@+id/account_image"

src/main/res/layout/fragment_conversation.xml 🔗

@@ -18,7 +18,10 @@
         android:listSelector="@android:color/transparent"
         android:stackFromBottom="true"
         android:transcriptMode="normal"
-        tools:listitem="@layout/message_sent" >
+        android:paddingTop="@dimen/activity_horizontal_margin"
+        android:paddingBottom="@dimen/activity_horizontal_margin"
+        android:clipToPadding="false"
+        tools:listitem="@layout/message_sent">
     </ListView>
 
     <RelativeLayout

src/main/res/layout/message_received.xml 🔗

@@ -3,10 +3,21 @@
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingBottom="4dp"
-    android:paddingLeft="8dp"
-    android:paddingRight="8dp"
-    android:paddingTop="4dp" >
+    android:paddingBottom="0dp"
+    android:paddingLeft="@dimen/activity_vertical_margin"
+    android:paddingRight="4dp"
+    android:paddingTop="0dp">
+
+    <ImageView
+        android:id="@+id/message_photo"
+        android:layout_width="36dp"
+        android:layout_height="38dp"
+        android:paddingTop="2dp"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_marginRight="@dimen/message_profile_image_gap"
+        android:scaleType="fitXY"
+        android:src="@drawable/ic_profile" />
 
     <LinearLayout
         android:id="@+id/message_box"
@@ -14,28 +25,24 @@
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:layout_toRightOf="@+id/message_photo"
-        android:background="@drawable/message_border"
+        android:background="@drawable/message_bubble_received"
         android:minHeight="48dp"
         android:longClickable="true">
 
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="fill_parent"
-            android:background="@color/grey50"
             android:gravity="center_vertical"
-            android:orientation="vertical"
-            android:paddingBottom="4dp"
-            android:paddingLeft="5dp"
-            android:paddingRight="5dp"
-            android:paddingTop="4dp" >
+            android:orientation="vertical">
 
             <ImageView
                 android:id="@+id/message_image"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="4dp"
                 android:adjustViewBounds="true"
                 android:background="@color/black87"
-                android:paddingBottom="2dp"
                 android:scaleType="centerCrop" />
 
             <TextView
@@ -43,7 +50,8 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:autoLink="web"
-                android:textColor="@color/black87"
+                android:textColorLink="@color/white"
+                android:textColor="@color/white"
                 android:textSize="?attr/TextSizeBody" />
 
             <Button
@@ -56,8 +64,9 @@
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_gravity="left"
                 android:orientation="horizontal"
-                android:paddingTop="1dp" >
+                android:paddingBottom="2dp">
 
                 <ImageView
                     android:id="@+id/security_indicator"
@@ -65,9 +74,9 @@
                     android:layout_height="?attr/TextSizeInfo"
                     android:layout_gravity="center_vertical"
                     android:layout_marginRight="4sp"
-                    android:alpha="0.54"
+                    android:alpha="0.70"
                     android:gravity="center_vertical"
-                    android:src="@drawable/ic_secure_indicator" />
+                    android:src="@drawable/ic_secure_indicator_white" />
 
                 <TextView
                     android:id="@+id/message_time"
@@ -76,21 +85,11 @@
                     android:layout_gravity="center_vertical"
                     android:gravity="center_vertical"
                     android:text="@string/sending"
-                    android:textColor="@color/black54"
+                    android:textColor="@color/white70"
+                    android:alpha="0.70"
                     android:textSize="?attr/TextSizeInfo" />
             </LinearLayout>
         </LinearLayout>
     </LinearLayout>
 
-    <ImageView
-        android:id="@+id/message_photo"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        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/main/res/layout/message_sent.xml 🔗

@@ -3,10 +3,21 @@
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingBottom="4dp"
-    android:paddingLeft="8dp"
-    android:paddingRight="8dp"
-    android:paddingTop="4dp" >
+    android:paddingBottom="0dp"
+    android:paddingLeft="4dp"
+    android:paddingRight="@dimen/activity_vertical_margin"
+    android:paddingTop="0dp">
+
+    <ImageView
+        android:id="@+id/message_photo"
+        android:layout_width="36dp"
+        android:layout_height="40dp"
+        android:paddingBottom="4dp"
+        android:layout_alignParentBottom="true"
+        android:layout_alignParentRight="true"
+        android:layout_marginLeft="@dimen/message_profile_image_gap"
+        android:scaleType="fitXY"
+        android:src="@drawable/ic_profile" />
 
     <LinearLayout
         android:id="@+id/message_box"
@@ -14,28 +25,24 @@
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
         android:layout_toLeftOf="@+id/message_photo"
-        android:background="@drawable/message_border"
+        android:background="@drawable/message_bubble_sent"
         android:minHeight="48dp"
         android:longClickable="true">
 
         <LinearLayout
             android:layout_width="wrap_content"
             android:layout_height="fill_parent"
-            android:background="@color/grey50"
             android:gravity="center_vertical"
-            android:orientation="vertical"
-            android:paddingBottom="4dp"
-            android:paddingLeft="5dp"
-            android:paddingRight="5dp"
-            android:paddingTop="4dp" >
+            android:orientation="vertical">
 
             <ImageView
                 android:id="@+id/message_image"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="4dp"
                 android:adjustViewBounds="true"
                 android:background="@color/black87"
-                android:paddingBottom="2dp"
                 android:scaleType="centerCrop" />
 
             <TextView
@@ -43,10 +50,11 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:autoLink="web"
+                android:textColorLink="@color/black87"
                 android:textColor="@color/black87"
                 android:textSize="?attr/TextSizeBody" />
-            
-             <Button
+
+            <Button
                 android:id="@+id/download_button"
                 style="?android:attr/buttonStyleSmall"
                 android:layout_width="wrap_content"
@@ -58,7 +66,7 @@
                 android:layout_height="wrap_content"
                 android:layout_gravity="right"
                 android:orientation="horizontal"
-                android:paddingTop="1dp" >
+                android:paddingBottom="2dp">
 
                 <TextView
                     android:id="@+id/message_time"
@@ -68,6 +76,7 @@
                     android:gravity="center_vertical"
                     android:text="@string/sending"
                     android:textColor="@color/black54"
+                    android:alpha="0.54"
                     android:textSize="?attr/TextSizeInfo" />
 
                 <ImageView
@@ -93,15 +102,4 @@
         </LinearLayout>
     </LinearLayout>
 
-    <ImageView
-        android:id="@+id/message_photo"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
-        android:layout_marginLeft="-1.5dp"
-        android:padding="0dp"
-        android:scaleType="fitXY"
-        android:src="@drawable/ic_profile" />
-
 </RelativeLayout>

src/main/res/layout/message_status.xml 🔗

@@ -3,15 +3,15 @@
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical"
-    android:paddingBottom="6dp"
+    android:paddingBottom="2dp"
     android:paddingLeft="8dp"
-    android:paddingRight="6dp"
-    android:paddingTop="6dp" >
+    android:paddingRight="8dp"
+    android:paddingTop="2dp" >
 
     <ImageView
         android:id="@+id/message_photo"
-        android:layout_width="32dp"
-        android:layout_height="32dp"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
         android:layout_alignParentLeft="true"
         android:layout_alignParentTop="true"
         android:layout_marginRight="-1.5dp"

src/main/res/values/dimens.xml 🔗

@@ -5,4 +5,5 @@
 	<dimen name="infocard_padding">16dp</dimen>
 	<dimen name="conversations_overview_width">288dp</dimen>
 	<dimen name="image_button_padding">8dp</dimen>
+	<dimen name="message_profile_image_gap">0dp</dimen>
 </resources>