diff --git a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt index c50b66fc74d98d2a413b8e80cea165f61b21478e..b175e538f0ce19790105b67c4f00ad40e0a75e2f 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/service/QuasselNotificationBackend.kt @@ -29,9 +29,9 @@ import de.kuschku.libquassel.quassel.ExtendedFeature import de.kuschku.libquassel.quassel.syncables.IgnoreListManager import de.kuschku.libquassel.session.NotificationManager import de.kuschku.libquassel.session.Session -import de.kuschku.libquassel.util.IrcUserUtils import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.irc.HostmaskHelper +import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.GlideRequest import de.kuschku.quasseldroid.R @@ -234,7 +234,7 @@ class QuasselNotificationBackend @Inject constructor( val content = contentFormatter.formatContent(it.content, false) val nickName = HostmaskHelper.nick(it.sender) - val senderColorIndex = IrcUserUtils.senderColor(nickName) + val senderColorIndex = SenderColorUtil.senderColor(nickName) val rawInitial = nickName.trimStart('-', '_', '[', diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt index 842ec28569adc9ee3a3b35490aa2252234e18ca9..1f6419617fc930ab6a6a6e3592790a93387a1df9 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt @@ -30,11 +30,11 @@ import de.kuschku.libquassel.quassel.syncables.IrcChannel import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.quassel.syncables.Network import de.kuschku.libquassel.session.ISession -import de.kuschku.libquassel.util.IrcUserUtils import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.helpers.nullIf import de.kuschku.libquassel.util.helpers.value +import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings @@ -89,7 +89,7 @@ class AutoCompleteHelper( }.map { if (it is AutoCompleteItem.UserItem) { val nickName = it.nick - val senderColorIndex = IrcUserUtils.senderColor(nickName) + val senderColorIndex = SenderColorUtil.senderColor(nickName) val rawInitial = nickName.trimStart(*IGNORED_CHARS).firstOrNull() ?: nickName.firstOrNull() val initial = rawInitial?.toUpperCase().toString() 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 c5805a0a141524be59f3ab29723502c8971d47e2..3b5254bce009e6b2130d323ef86bc51e6a1a7577 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 @@ -32,9 +32,9 @@ import android.widget.LinearLayout import de.kuschku.libquassel.protocol.Message.MessageType.* import de.kuschku.libquassel.protocol.Message_Flag import de.kuschku.libquassel.protocol.Message_Type -import de.kuschku.libquassel.util.IrcUserUtils import de.kuschku.libquassel.util.flag.hasFlag import de.kuschku.libquassel.util.irc.HostmaskHelper +import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.settings.MessageSettings @@ -212,7 +212,7 @@ class QuasselMessageRenderer @Inject constructor( } val content = contentFormatter.formatContent(message.content.content, highlight) val nickName = HostmaskHelper.nick(message.content.sender) - val senderColorIndex = IrcUserUtils.senderColor(nickName) + val senderColorIndex = SenderColorUtil.senderColor(nickName) val rawInitial = nickName.trimStart('-', '_', '[', ']', '{', '}', '|', '`', '^', '.', '\\') .firstOrNull() ?: nickName.firstOrNull() val initial = rawInitial?.toUpperCase().toString() diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt index 6f7e0ba2af69cb13bef7c94a3ad025ad05ac3252..6b00e1e4c036e2f59443fb8bee26ae30e0642265 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/nicks/NickListFragment.kt @@ -39,9 +39,9 @@ import com.bumptech.glide.integration.recyclerview.RecyclerViewPreloader import com.bumptech.glide.util.FixedPreloadSizeProvider import de.kuschku.libquassel.protocol.Buffer_Type import de.kuschku.libquassel.quassel.BufferInfo -import de.kuschku.libquassel.util.IrcUserUtils import de.kuschku.libquassel.util.helpers.value import de.kuschku.libquassel.util.irc.IrcCaseMappers +import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.GlideApp import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings @@ -103,7 +103,7 @@ class NickListFragment : ServiceBoundFragment() { runInBackground { it?.asSequence()?.map { val nickName = it.nick - val senderColorIndex = IrcUserUtils.senderColor(nickName) + val senderColorIndex = SenderColorUtil.senderColor(nickName) val rawInitial = nickName.trimStart('-', '_', '[', diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/ContentFormatter.kt b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/ContentFormatter.kt index 6259d284bbf50ac6b81276eae4150246e818adc0..92283235dd5a0a7664c68ad7860553725f2716ae 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/ContentFormatter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/irc/format/ContentFormatter.kt @@ -27,7 +27,8 @@ import android.text.TextPaint import android.text.style.ForegroundColorSpan import android.text.style.StyleSpan import android.text.style.URLSpan -import de.kuschku.libquassel.util.IrcUserUtils +import de.kuschku.libquassel.util.irc.HostmaskHelper +import de.kuschku.libquassel.util.irc.SenderColorUtil import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.helper.styledAttributes @@ -106,7 +107,7 @@ class ContentFormatter @Inject constructor( senderColors: IntArray): CharSequence { val spannableString = SpannableString(nick) if (colorize) { - val senderColor = IrcUserUtils.senderColor(nick) + val senderColor = SenderColorUtil.senderColor(nick) spannableString.setSpan( ForegroundColorSpan(senderColors[(senderColor + senderColors.size) % senderColors.size]), 0, @@ -125,12 +126,11 @@ class ContentFormatter @Inject constructor( private fun formatNickImpl(sender: String, colorize: Boolean, hostmask: Boolean, senderColors: IntArray): CharSequence { - val nick = IrcUserUtils.nick(sender) - val mask = IrcUserUtils.mask(sender) + val (nick, user, host) = HostmaskHelper.split(sender) val formattedNick = formatNickNickImpl(nick, colorize, senderColors) return if (hostmask) { - SpanFormatter.format("%s (%s)", formattedNick, mask) + SpanFormatter.format("%s (%s@%s)", formattedNick, user, host) } else { formattedNick } diff --git a/lib/src/main/java/de/kuschku/libquassel/util/IrcUserUtils.kt b/lib/src/main/java/de/kuschku/libquassel/util/IrcUserUtils.kt deleted file mode 100644 index 87fed68d3f8eb38aeb163fd0db6e9f336275d35f..0000000000000000000000000000000000000000 --- a/lib/src/main/java/de/kuschku/libquassel/util/IrcUserUtils.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Quasseldroid - Quassel client for Android - * - * Copyright (c) 2018 Janne Koschinski - * Copyright (c) 2018 The Quassel Project - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.libquassel.util - -import java.util.* - -object IrcUserUtils { - fun senderColor(nick: String): Int { - return 0xf and CRCUtils.qChecksum( - nick.trimEnd('_').toLowerCase(Locale.US).toByteArray(Charsets.ISO_8859_1) - ) - } - - fun nick(hostmask: String): String { - return hostmask.substring( - 0, - hostmask.lastIndex('!', hostmask.lastIndex('@')) ?: hostmask.length - ) - } - - fun user(hostmask: String): String { - return hostmask.substring( - (hostmask.lastIndex('!', hostmask.lastIndex('@')) ?: -1) + 1, - hostmask.lastIndex('@') ?: hostmask.length - ) - } - - fun host(hostmask: String): String { - return hostmask.substring( - (hostmask.lastIndex('@') ?: -1) + 1 - ) - } - - fun mask(hostmask: String): String { - return hostmask.substring( - (hostmask.lastIndex('!', hostmask.lastIndex('@')) ?: -1) + 1 - ) - } - - private fun String.firstIndex(char: Char, - startIndex: Int? = null, - ignoreCase: Boolean = false): Int? { - val lastIndex = indexOf(char, startIndex ?: 0, ignoreCase) - return if (lastIndex < 0) - null - else - lastIndex - } - - private fun String.lastIndex(char: Char, - startIndex: Int? = null, - ignoreCase: Boolean = false): Int? = - lastIndexOf(char, startIndex ?: lastIndex, ignoreCase).let { lastIndex -> - if (lastIndex < 0) - null - else - lastIndex - } -} diff --git a/lib/src/main/java/de/kuschku/libquassel/util/irc/SenderColorUtil.kt b/lib/src/main/java/de/kuschku/libquassel/util/irc/SenderColorUtil.kt new file mode 100644 index 0000000000000000000000000000000000000000..6c5da692ee6abda14a542590d2ecb25dd3b173c8 --- /dev/null +++ b/lib/src/main/java/de/kuschku/libquassel/util/irc/SenderColorUtil.kt @@ -0,0 +1,31 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2018 Janne Koschinski + * Copyright (c) 2018 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.libquassel.util.irc + +import de.kuschku.libquassel.util.CRCUtils +import java.util.* + +object SenderColorUtil { + fun senderColor(nick: String): Int { + return 0xf and CRCUtils.qChecksum( + nick.trimEnd('_').toLowerCase(Locale.US).toByteArray(Charsets.ISO_8859_1) + ) + } +} diff --git a/lib/src/test/java/de/kuschku/libquassel/util/irc/HostmaskHelperTest.kt b/lib/src/test/java/de/kuschku/libquassel/util/irc/HostmaskHelperTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..51c406e0b9402670e6d63365b1103bd7ce0092c5 --- /dev/null +++ b/lib/src/test/java/de/kuschku/libquassel/util/irc/HostmaskHelperTest.kt @@ -0,0 +1,39 @@ +package de.kuschku.libquassel.util.irc + +import org.junit.Assert.assertEquals +import org.junit.Test + +class HostmaskHelperTest { + @Test + fun testNormal() { + assertEquals("justJanne", HostmaskHelper.nick("justJanne!kuschku@lithium.kuschku.de")) + assertEquals("kuschku", HostmaskHelper.user("justJanne!kuschku@lithium.kuschku.de")) + assertEquals("lithium.kuschku.de", HostmaskHelper.host("justJanne!kuschku@lithium.kuschku.de")) + } + + @Test + fun testUnvalidatedIdent() { + assertEquals("justJanne", HostmaskHelper.nick("justJanne!~kuschku@lithium.kuschku.de")) + assertEquals("~kuschku", HostmaskHelper.user("justJanne!~kuschku@lithium.kuschku.de")) + assertEquals("lithium.kuschku.de", HostmaskHelper.host("justJanne!~kuschku@lithium.kuschku.de")) + } + + @Test + fun testUnicode() { + assertEquals("bärlauch", HostmaskHelper.nick("bärlauch!maße@flüge.de")) + assertEquals("maße", HostmaskHelper.user("bärlauch!maße@flüge.de")) + assertEquals("flüge.de", HostmaskHelper.host("bärlauch!maße@flüge.de")) + } + + @Test + fun testServer() { + assertEquals("irc.freenode.org", HostmaskHelper.nick("irc.freenode.org")) + } + + @Test + fun testDiscord() { + assertEquals("Gin_", HostmaskHelper.nick("Gin_!Gin_!♡♅ƸӜƷ♅♡!@discord")) + assertEquals("Gin_!♡♅ƸӜƷ♅♡!", HostmaskHelper.user("Gin_!Gin_!♡♅ƸӜƷ♅♡!@discord")) + assertEquals("discord", HostmaskHelper.host("Gin_!Gin_!♡♅ƸӜƷ♅♡!@discord")) + } +}