From 39721d8f84b7a7b64d5a6bae81cb0e14aba4d63d Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 18 Feb 2018 22:49:12 +0100
Subject: [PATCH] Correctly parse colors and links

---
 .../quasseldroid_ng/ui/chat/MessageAdapter.kt |  1 +
 .../ui/chat/QuasselMessageRenderer.kt         | 44 +++++++++++++++++--
 .../ui/settings/data/RenderingSettings.kt     |  1 +
 3 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageAdapter.kt
index 7831ba4c5..547b5601f 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageAdapter.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MessageAdapter.kt
@@ -23,6 +23,7 @@ class MessageAdapter(context: Context) :
     RenderingSettings(
       showPrefix = RenderingSettings.ShowPrefixMode.FIRST,
       colorizeNicknames = RenderingSettings.ColorizeNicknamesMode.ALL_BUT_MINE,
+      colorizeMirc = true,
       timeFormat = ""
     )
   )
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/QuasselMessageRenderer.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/QuasselMessageRenderer.kt
index 1d9014e88..b5a9a7c85 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/QuasselMessageRenderer.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/QuasselMessageRenderer.kt
@@ -3,9 +3,11 @@ package de.kuschku.quasseldroid_ng.ui.chat
 import android.content.Context
 import android.graphics.Typeface
 import android.text.SpannableString
+import android.text.Spanned
 import android.text.format.DateFormat
 import android.text.style.ForegroundColorSpan
 import android.text.style.StyleSpan
+import android.text.style.URLSpan
 import de.kuschku.libquassel.protocol.Message.MessageType.*
 import de.kuschku.libquassel.protocol.Message_Flag
 import de.kuschku.libquassel.protocol.Message_Type
@@ -16,6 +18,7 @@ import de.kuschku.quasseldroid_ng.ui.settings.data.RenderingSettings
 import de.kuschku.quasseldroid_ng.ui.settings.data.RenderingSettings.ColorizeNicknamesMode
 import de.kuschku.quasseldroid_ng.ui.settings.data.RenderingSettings.ShowPrefixMode
 import de.kuschku.quasseldroid_ng.util.helper.styledAttributes
+import de.kuschku.quasseldroid_ng.util.irc.format.IrcFormatDeserializer
 import de.kuschku.quasseldroid_ng.util.quassel.IrcUserUtils
 import de.kuschku.quasseldroid_ng.util.ui.SpanFormatter
 import org.threeten.bp.ZoneId
@@ -37,6 +40,8 @@ class QuasselMessageRenderer(
 
   private val zoneId = ZoneId.systemDefault()
 
+  private val ircFormatDeserializer = IrcFormatDeserializer(context)
+
   init {
     context.theme.styledAttributes(
       R.attr.senderColor0, R.attr.senderColor1, R.attr.senderColor2, R.attr.senderColor3,
@@ -86,7 +91,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_plain),
           formatPrefix(message.senderPrefixes),
           formatNick(message.sender, Message_Flag.of(message.flag).hasFlag(Message_Flag.Self)),
-          message.content
+          formatContent(message.content)
         )
       )
       Message_Type.Action -> FormattedMessage(
@@ -96,7 +101,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_action),
           formatPrefix(message.senderPrefixes),
           formatNick(message.sender, Message_Flag.of(message.flag).hasFlag(Message_Flag.Self)),
-          message.content
+          formatContent(message.content)
         )
       )
       Message_Type.Notice -> FormattedMessage(
@@ -106,7 +111,7 @@ class QuasselMessageRenderer(
           context.getString(R.string.message_format_notice),
           formatPrefix(message.senderPrefixes),
           formatNick(message.sender, Message_Flag.of(message.flag).hasFlag(Message_Flag.Self)),
-          message.content
+          formatContent(message.content)
         )
       )
       Message_Type.Nick   -> FormattedMessage(
@@ -209,7 +214,7 @@ class QuasselMessageRenderer(
       Message_Type.Topic -> FormattedMessage(
         message.messageId,
         timeFormatter.format(message.time.atZone(zoneId)),
-        message.content
+        formatContent(message.content)
       )
       else -> FormattedMessage(
         message.messageId,
@@ -225,6 +230,37 @@ class QuasselMessageRenderer(
     }
   }
 
+  private val scheme = "(?:(?:mailto:|(?:[+.-]?\\w)+://)|www(?=\\.\\S+\\.))"
+  private val authority = "(?:(?:[,.;@:]?[-\\w]+)+\\.?|\\[[0-9a-f:.]+\\])(?::\\d+)?"
+  private val urlChars = "(?:[,.;:]*[\\w~@/?&=+$()!%#*-])"
+  private val urlEnd = "((?:>|[,.;:\"]*\\s|\\b|$))"
+  private val urlPattern = Regex(
+    String.format("\\b(%s%s(?:/%s*)?)%s", scheme, authority, urlChars, urlEnd),
+    RegexOption.IGNORE_CASE
+  )
+  private val channelPattern = Regex(
+    "((?:#|![A-Z0-9]{5})[^,:\\s]+(?::[^,:\\s]+)?)\\b",
+    RegexOption.IGNORE_CASE
+  )
+
+  private fun formatContent(content: String): CharSequence {
+    val text = SpannableString(
+      ircFormatDeserializer.formatString(content, renderingSettings.colorizeMirc)
+    )
+    for (result in urlPattern.findAll(content)) {
+      text.setSpan(
+        URLSpan(result.value), result.range.start, result.range.start + result.value.length,
+        Spanned.SPAN_INCLUSIVE_INCLUSIVE
+      )
+    }
+    /*
+    for (result in channelPattern.findAll(content)) {
+      text.setSpan(URLSpan(result.value), result.range.start, result.range.endInclusive, Spanned.SPAN_INCLUSIVE_INCLUSIVE)
+    }
+    */
+    return text
+  }
+
   private fun formatNickImpl(sender: String, colorize: Boolean): CharSequence {
     val nick = IrcUserUtils.nick(sender)
     val spannableString = SpannableString(nick)
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/RenderingSettings.kt b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/RenderingSettings.kt
index a0a86d5c0..f1c6eea92 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/RenderingSettings.kt
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/settings/data/RenderingSettings.kt
@@ -3,6 +3,7 @@ package de.kuschku.quasseldroid_ng.ui.settings.data
 data class RenderingSettings(
   val showPrefix: ShowPrefixMode = ShowPrefixMode.FIRST,
   val colorizeNicknames: ColorizeNicknamesMode = ColorizeNicknamesMode.ALL_BUT_MINE,
+  val colorizeMirc: Boolean = true,
   val timeFormat: String = ""
 ) {
   enum class ColorizeNicknamesMode(val value: Int) {
-- 
GitLab