From 1f3c9531df9e37e125804ece5152758ce497a554 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Wed, 6 Jun 2018 21:16:47 +0200
Subject: [PATCH] Display smaller avatars for /me actions. Fixes #118

---
 .../ui/chat/messages/MessageListFragment.kt   |  7 +-
 .../chat/messages/QuasselMessageRenderer.kt   | 74 ++++++++++-----
 .../res/layout/widget_chatmessage_action.xml  | 92 +++++++++++++------
 app/src/main/res/values/dimens.xml            |  1 +
 4 files changed, 122 insertions(+), 52 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
index 0bfa0ba75..4f3c216cf 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/MessageListFragment.kt
@@ -293,7 +293,12 @@ class MessageListFragment : ServiceBoundFragment() {
       return list.mapReverse {
         val date = it.time.atZone(ZoneId.systemDefault()).truncatedTo(ChronoUnit.DAYS)
         val isSameDay = previousDate?.isEqual(date) ?: false
-        val isFollowUp = previous?.sender == it.sender && previous?.type == it.type && isSameDay
+        if (it.sender.startsWith("testcrc3")) {
+          println("$previous:$it")
+        }
+        val isFollowUp = previous?.sender == it.sender &&
+                         (previous?.type?.hasFlag(Message_Type.Plain) == true || previous?.type == it.type) &&
+                         isSameDay
         previous = it
         previousDate = date
         DisplayMessage(
diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
index 40cb51c1b..8a8ace583 100644
--- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/messages/QuasselMessageRenderer.kt
@@ -26,6 +26,7 @@ import android.graphics.drawable.LayerDrawable
 import android.os.Build
 import android.text.SpannableStringBuilder
 import android.util.TypedValue
+import android.view.Gravity
 import android.view.View
 import android.widget.FrameLayout
 import android.widget.LinearLayout
@@ -165,15 +166,22 @@ class QuasselMessageRenderer @Inject constructor(
     val contentSize = if (messageSettings.largerEmoji && isEmoji) textSize * 2f else textSize
     viewHolder.content?.setTextSize(TypedValue.COMPLEX_UNIT_SP, contentSize)
     viewHolder.combined?.setTextSize(TypedValue.COMPLEX_UNIT_SP, contentSize)
-    val avatarSize = TypedValue.applyDimension(
+    val avatarContainerSize = TypedValue.applyDimension(
       TypedValue.COMPLEX_UNIT_SP,
       textSize * 2.5f,
       viewHolder.itemView.context.resources.displayMetrics
     ).roundToInt()
-    viewHolder.avatar?.layoutParams =
-      FrameLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, avatarSize)
+    val avatarSize = TypedValue.applyDimension(
+      TypedValue.COMPLEX_UNIT_SP,
+      if (messageType == Plain) textSize * 2.5f
+      else textSize * 1.5f,
+      viewHolder.itemView.context.resources.displayMetrics
+    ).roundToInt()
+    viewHolder.avatar?.layoutParams = FrameLayout.LayoutParams(avatarSize, avatarSize).apply {
+      gravity = Gravity.END
+    }
     avatarContainer?.layoutParams =
-      LinearLayout.LayoutParams(avatarSize, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
+      LinearLayout.LayoutParams(avatarContainerSize, LinearLayout.LayoutParams.WRAP_CONTENT).apply {
         val margin = viewHolder.itemView.context.resources.getDimensionPixelSize(R.dimen.message_horizontal)
         setMargins(0, 0, margin, 0)
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
@@ -181,7 +189,7 @@ class QuasselMessageRenderer @Inject constructor(
         }
       }
     avatarPlaceholder?.layoutParams =
-      LinearLayout.LayoutParams(avatarSize, LinearLayout.LayoutParams.MATCH_PARENT).apply {
+      LinearLayout.LayoutParams(avatarContainerSize, LinearLayout.LayoutParams.MATCH_PARENT).apply {
         val margin = viewHolder.itemView.context.resources.getDimensionPixelSize(R.dimen.message_horizontal)
         setMargins(0, 0, margin, 0)
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
@@ -208,7 +216,7 @@ class QuasselMessageRenderer @Inject constructor(
     val highlight__ = message.content.flag.hasFlag(Message_Flag.Highlight)
     val monochromeForeground = highlight__ && monochromeHighlights
     return when (message.content.type.enabledValues().firstOrNull()) {
-      Message_Type.Plain        -> {
+      Message_Type.Plain     -> {
         val realName = ircFormatDeserializer.formatString(message.content.realName,
                                                           !monochromeForeground)
         val nick = SpannableStringBuilder().apply {
@@ -257,22 +265,42 @@ class QuasselMessageRenderer @Inject constructor(
           isSelected = message.isSelected
         )
       }
-      Message_Type.Action       -> FormattedMessage(
-        id = message.content.messageId,
-        time = timeFormatter.format(message.content.time.atZone(zoneId)),
-        dayChange = formatDayChange(message),
-        combined = SpanFormatter.format(
-          context.getString(R.string.message_format_action),
-          contentFormatter.formatPrefix(message.content.senderPrefixes),
-          contentFormatter.formatNick(message.content.sender, self, monochromeForeground, false),
-          contentFormatter.formatContent(message.content.content, monochromeForeground)
-        ),
-        hasDayChange = message.hasDayChange,
-        isMarkerLine = message.isMarkerLine,
-        isExpanded = message.isExpanded,
-        isSelected = message.isSelected
-      )
-      Message_Type.Notice       -> FormattedMessage(
+      Message_Type.Action    -> {
+        val nickName = HostmaskHelper.nick(message.content.sender)
+        val senderColorIndex = SenderColorUtil.senderColor(nickName)
+        val rawInitial = nickName.trimStart('-', '_', '[', ']', '{', '}', '|', '`', '^', '.', '\\')
+                           .firstOrNull() ?: nickName.firstOrNull()
+        val initial = rawInitial?.toUpperCase().toString()
+        val senderColor = when (messageSettings.colorizeNicknames) {
+          MessageSettings.ColorizeNicknamesMode.ALL          -> senderColors[senderColorIndex]
+          MessageSettings.ColorizeNicknamesMode.ALL_BUT_MINE ->
+            if (message.content.flag.hasFlag(Message_Flag.Self)) selfColor
+            else senderColors[senderColorIndex]
+          MessageSettings.ColorizeNicknamesMode.NONE         -> selfColor
+        }
+
+        FormattedMessage(
+          id = message.content.messageId,
+          time = timeFormatter.format(message.content.time.atZone(zoneId)),
+          dayChange = formatDayChange(message),
+          combined = SpanFormatter.format(
+            context.getString(R.string.message_format_action),
+            contentFormatter.formatPrefix(message.content.senderPrefixes),
+            contentFormatter.formatNick(message.content.sender, self, monochromeForeground, false),
+            contentFormatter.formatContent(message.content.content, monochromeForeground)
+          ),
+          avatarUrls = AvatarHelper.avatar(messageSettings, message.content, avatarSize),
+          fallbackDrawable = TextDrawable.builder().let {
+            if (messageSettings.squareAvatars) it.buildRect(initial, senderColor)
+            else it.buildRound(initial, senderColor)
+          },
+          hasDayChange = message.hasDayChange,
+          isMarkerLine = message.isMarkerLine,
+          isExpanded = message.isExpanded,
+          isSelected = message.isSelected
+        )
+      }
+      Message_Type.Notice    -> FormattedMessage(
         id = message.content.messageId,
         time = timeFormatter.format(message.content.time.atZone(zoneId)),
         dayChange = formatDayChange(message),
@@ -542,7 +570,7 @@ class QuasselMessageRenderer @Inject constructor(
       }
       Message_Type.Server,
       Message_Type.Info,
-      Message_Type.Error        -> FormattedMessage(
+      Message_Type.Error     -> FormattedMessage(
         id = message.content.messageId,
         time = timeFormatter.format(message.content.time.atZone(zoneId)),
         dayChange = formatDayChange(message),
diff --git a/app/src/main/res/layout/widget_chatmessage_action.xml b/app/src/main/res/layout/widget_chatmessage_action.xml
index 19bfb06f2..6094ee2ff 100644
--- a/app/src/main/res/layout/widget_chatmessage_action.xml
+++ b/app/src/main/res/layout/widget_chatmessage_action.xml
@@ -21,8 +21,7 @@
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
-  android:orientation="vertical"
-  tools:showIn="@layout/fragment_messages">
+  android:orientation="vertical">
 
   <include layout="@layout/widget_chatmessage_daychange" />
 
@@ -49,38 +48,75 @@
       android:layout_marginRight="@dimen/message_horizontal"
       android:textColor="?attr/colorForegroundSecondary"
       android:typeface="monospace"
-      tools:text="@sample/messages.json/data/time" />
+      tools:text="@sample/messages.json/data/time"
+      tools:visibility="gone" />
 
-    <Space
-      android:id="@+id/avatar_placeholder"
+    <FrameLayout
+      android:id="@+id/avatar_container"
       android:layout_width="@dimen/avatar_size"
-      android:layout_height="match_parent"
+      android:layout_height="@dimen/avatar_size"
       android:layout_marginEnd="@dimen/message_horizontal"
       android:layout_marginRight="@dimen/message_horizontal"
-      android:visibility="gone" />
+      android:visibility="gone"
+      tools:ignore="UselessParent"
+      tools:visibility="visible">
 
-    <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
-      android:id="@+id/combined"
-      style="@style/Widget.RtlConformTextView"
-      android:layout_width="0dip"
-      android:layout_height="wrap_content"
-      android:layout_weight="1"
-      android:textColor="?attr/colorForegroundAction"
-      android:textStyle="italic"
-      tools:text="@sample/messages.json/data/message" />
+      <ImageView
+        android:id="@+id/avatar"
+        android:layout_width="21sp"
+        android:layout_height="21sp"
+        android:layout_gravity="end"
+        android:contentDescription="@string/label_avatar"
+        tools:src="@tools:sample/avatars" />
+    </FrameLayout>
 
-    <TextView
-      android:id="@+id/time_right"
-      android:layout_width="wrap_content"
+    <LinearLayout
+      android:layout_width="match_parent"
       android:layout_height="wrap_content"
-      android:layout_gravity="top"
-      android:layout_marginLeft="@dimen/message_horizontal"
-      android:layout_marginStart="@dimen/message_horizontal"
-      android:textColor="?attr/colorForegroundSecondary"
-      android:textStyle="italic"
-      android:visibility="gone"
-      tools:text="@sample/messages.json/data/time"
-      tools:textSize="11.9sp"
-      tools:visibility="visible" />
+      android:layout_gravity="center_vertical|fill_horizontal"
+      android:orientation="horizontal">
+
+      <LinearLayout
+        android:layout_width="0dip"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:orientation="vertical">
+
+        <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+          android:id="@+id/content"
+          style="@style/Widget.RtlConformTextView"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:textColor="?attr/colorForeground"
+          android:visibility="gone"
+          tools:text="@sample/messages.json/data/content"
+          tools:visibility="visible" />
+
+        <de.kuschku.quasseldroid.util.ui.RipplePassthroughTextView
+          android:id="@+id/combined"
+          style="@style/Widget.RtlConformTextView"
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:textColor="?attr/colorForeground"
+          tools:text="@sample/messages.json/data/message"
+          tools:visibility="gone" />
+
+      </LinearLayout>
+
+      <TextView
+        android:id="@+id/time_right"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="top"
+        android:layout_marginLeft="@dimen/message_horizontal"
+        android:layout_marginStart="@dimen/message_horizontal"
+        android:textColor="?attr/colorForegroundSecondary"
+        android:textStyle="italic"
+        android:visibility="gone"
+        tools:text="@sample/messages.json/data/time"
+        tools:textSize="11.9sp"
+        tools:visibility="visible" />
+    </LinearLayout>
   </LinearLayout>
+
 </LinearLayout>
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index b27240fb9..c0d6497fa 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -36,6 +36,7 @@
 
   <dimen name="colorchooser_circlesize">56dp</dimen>
   <dimen name="avatar_size">35sp</dimen>
+  <dimen name="avatar_size_action">20sp</dimen>
 
   <dimen name="notification_avatar_width">64dp</dimen>
   <dimen name="notification_avatar_height">64dp</dimen>
-- 
GitLab