From 762cebb093e68af4731d1b7d08bb7e69c4dad2e9 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Wed, 16 May 2018 23:41:35 +0200 Subject: [PATCH] Fixes additional issues with WHOIS functionality --- .../ui/chat/info/user/IrcUserInfo.kt | 36 ++++ .../ui/chat/info/user/UserInfoFragment.kt | 187 ++++++++++-------- .../quasseldroid/util/avatars/AvatarHelper.kt | 28 ++- 3 files changed, 164 insertions(+), 87 deletions(-) create mode 100644 app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt new file mode 100644 index 000000000..05fbf8d6a --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/IrcUserInfo.kt @@ -0,0 +1,36 @@ +/* + * 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.quasseldroid.ui.chat.info.user + +import de.kuschku.libquassel.quassel.syncables.Network + +data class IrcUserInfo( + val networkId: Int, + val nick: String, + val user: String? = null, + val host: String? = null, + val account: String? = null, + val server: String? = null, + val realName: String? = null, + val isAway: Boolean? = false, + val awayMessage: String? = null, + val network: Network? = null, + val knownToCore: Boolean = false +) diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt index c5f7f7450..3f33ead50 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/info/user/UserInfoFragment.kt @@ -32,9 +32,12 @@ import android.widget.Toast import butterknife.BindView import butterknife.ButterKnife import de.kuschku.libquassel.protocol.Buffer_Type +import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.IrcUser import de.kuschku.libquassel.util.IrcUserUtils +import de.kuschku.libquassel.util.Optional import de.kuschku.libquassel.util.helpers.nullIf +import de.kuschku.libquassel.util.helpers.value import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.ChatActivity @@ -130,31 +133,55 @@ class UserInfoFragment : ServiceBoundFragment() { getColor(0, 0) } - val networkId = arguments?.getInt("networkId") - val nickName = arguments?.getString("nick") + val networkId2 = arguments?.getInt("networkId") + val nickName2 = arguments?.getString("nick") combineLatest(viewModel.session, viewModel.networks).switchMap { (sessionOptional, networks) -> + fun processUser(user: IrcUser, info: BufferInfo? = null) = when { + user == IrcUser.NULL && info != null -> Optional.of(IrcUserInfo( + info.networkId, + info.bufferName ?: "" + )) + user == IrcUser.NULL -> Optional.empty() + else -> Optional.of(IrcUserInfo( + networkId = user.network().networkId(), + nick = user.nick(), + user = user.user(), + host = user.host(), + account = user.account(), + server = user.server(), + realName = user.realName(), + isAway = user.isAway(), + awayMessage = user.awayMessage(), + network = user.network(), + knownToCore = true + )) + } + if (openBuffer == true) { val session = sessionOptional?.orNull() val bufferSyncer = session?.bufferSyncer val bufferInfo = bufferSyncer?.bufferInfo(arguments?.getInt("bufferId") ?: -1) bufferInfo?.let { - networks[it.networkId]?.liveIrcUser(it.bufferName) + networks[it.networkId]?.liveIrcUser(it.bufferName)?.switchMap(IrcUser::updates)?.map { + processUser(it, bufferInfo) + } } } else { - networks[networkId]?.liveIrcUser(nickName) - } ?: Observable.just(IrcUser.NULL) - }.filter { - it != IrcUser.NULL - }.switchMap(IrcUser::updates).toLiveData().observe(this, Observer { user -> - if (user != null) { - val senderColorIndex = IrcUserUtils.senderColor(user.nick()) - val rawInitial = user.nick().trimStart(*IGNORED_CHARS).firstOrNull() - ?: user.nick().firstOrNull() + networks[networkId2] + ?.liveIrcUser(nickName2) + ?.switchMap(IrcUser::updates) + ?.map { user -> processUser(user) } + } ?: Observable.just(IrcUser.NULL).map { user -> processUser(user) } + }.toLiveData().observe(this, Observer { + val processUser = { user: IrcUserInfo -> + val senderColorIndex = IrcUserUtils.senderColor(user.nick) + val rawInitial = user.nick.trimStart(*IGNORED_CHARS).firstOrNull() + ?: user.nick.firstOrNull() val initial = rawInitial?.toUpperCase().toString() val senderColor = when (messageSettings.colorizeNicknames) { MessageSettings.ColorizeNicknamesMode.ALL -> senderColors[senderColorIndex] MessageSettings.ColorizeNicknamesMode.ALL_BUT_MINE -> - if (user.network().isMyNick(user.nick())) selfColor + if (user.network?.isMyNick(user.nick) == true) selfColor else senderColors[senderColorIndex] MessageSettings.ColorizeNicknamesMode.NONE -> selfColor } @@ -165,84 +192,90 @@ class UserInfoFragment : ServiceBoundFragment() { crop = false ) - nick.text = user.nick() - realName.text = contentFormatter.formatContent(user.realName()) - realName.visibleIf(user.realName().isNotBlank() && user.realName() != user.nick()) + nick.text = user.nick + realName.text = contentFormatter.formatContent(user.realName ?: "") + realName.visibleIf(!user.realName.isNullOrBlank() && user.realName != user.nick) - awayMessage.text = user.awayMessage().nullIf { it.isBlank() } ?: SpannableString(getString(R.string.label_no_away_message)).apply { + awayMessage.text = user.awayMessage.nullIf { it.isNullOrBlank() } ?: SpannableString( + getString( + R.string.label_no_away_message)).apply { setSpan(IrcItalicSpan(), 0, length, 0) } - awayContainer.visibleIf(user.isAway()) - - account.text = user.account() - accountContainer.visibleIf(user.account().isNotBlank()) - - ident.text = user.user() - identContainer.visibleIf(user.user().isNotBlank()) - - host.text = user.host() - hostContainer.visibleIf(user.host().isNotBlank()) - - server.text = user.server() - serverContainer.visibleIf(user.server().isNotBlank()) - } - }) - - actionQuery.setOnClickListener { - viewModel.session { - it.orNull()?.let { session -> - val info = session.bufferSyncer?.find( - bufferName = nickName, - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.QueryBuffer) - ) - - if (info != null) { - ChatActivity.launch(requireContext(), bufferId = info.bufferId) - } else { - viewModel.allBuffers.map { - listOfNotNull(it.find { - it.networkId == networkId && it.bufferName == nickName + awayContainer.visibleIf(user.isAway == true) + + account.text = user.account + accountContainer.visibleIf(!user.account.isNullOrBlank()) + + ident.text = user.user + identContainer.visibleIf(!user.user.isNullOrBlank()) + + host.text = user.host + hostContainer.visibleIf(!user.host.isNullOrBlank()) + + server.text = user.server + serverContainer.visibleIf(!user.server.isNullOrBlank()) + + actionWhois.visibleIf(user.knownToCore) + + actionQuery.setOnClickListener { + viewModel.session.value?.orNull()?.let { session -> + val info = session.bufferSyncer?.find( + bufferName = user.nick, + networkId = user.networkId, + type = Buffer_Type.of(Buffer_Type.QueryBuffer) + ) + + if (info != null) { + ChatActivity.launch(requireContext(), + bufferId = info.bufferId) + } else { + viewModel.allBuffers.map { + listOfNotNull(it.find { + it.networkId == user.networkId && it.bufferName == user.nick + }) + }.filter { + it.isNotEmpty() + }.firstElement().toLiveData().observe(this, Observer { + it?.firstOrNull()?.let { info -> + ChatActivity.launch(requireContext(), + bufferId = info.bufferId) + } }) - }.filter { - it.isNotEmpty() - }.firstElement().toLiveData().observe(this, Observer { - it?.firstOrNull()?.let { info -> - ChatActivity.launch(requireContext(), bufferId = info.bufferId) - } - }) - session.bufferSyncer?.find( - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.StatusBuffer) - )?.let { statusInfo -> - session.rpcHandler?.sendInput(statusInfo, "/query $nickName") + session.bufferSyncer?.find( + networkId = user.networkId, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.let { statusInfo -> + session.rpcHandler?.sendInput(statusInfo, + "/query ${user.nick}") + } } } } - } - } - actionIgnore.setOnClickListener { - Toast.makeText(requireContext(), "Not Implemented", Toast.LENGTH_SHORT).show() - } + actionIgnore.setOnClickListener { + Toast.makeText(requireContext(), "Not Implemented", Toast.LENGTH_SHORT).show() + } - actionMention.setOnClickListener { - ChatActivity.launch(requireContext(), sharedText = "$nickName: ") - } + actionMention.setOnClickListener { + ChatActivity.launch(requireContext(), sharedText = "${user.nick}: ") + } - actionWhois.setOnClickListener { - viewModel.session { - it.orNull()?.let { session -> - session.bufferSyncer?.find( - networkId = networkId, - type = Buffer_Type.of(Buffer_Type.StatusBuffer) - )?.let { statusInfo -> - session.rpcHandler?.sendInput(statusInfo, "/whois $nickName $nickName") + actionWhois.setOnClickListener { + viewModel.session { + it.orNull()?.let { session -> + session.bufferSyncer?.find( + networkId = user.networkId, + type = Buffer_Type.of(Buffer_Type.StatusBuffer) + )?.let { statusInfo -> + session.rpcHandler?.sendInput(statusInfo, "/whois ${user.nick} ${user.nick}") + } + } } } } - } + it?.orNull()?.let(processUser) + }) actionMention.visibleIf(arguments?.getBoolean("openBuffer") == false) diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt index 79edf1367..78d0b6c87 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/avatars/AvatarHelper.kt @@ -24,6 +24,7 @@ import de.kuschku.libquassel.util.irc.HostmaskHelper import de.kuschku.libquassel.util.irc.IrcCaseMappers import de.kuschku.quasseldroid.persistence.QuasselDatabase import de.kuschku.quasseldroid.settings.MessageSettings +import de.kuschku.quasseldroid.ui.chat.info.user.IrcUserInfo import de.kuschku.quasseldroid.util.Patterns import de.kuschku.quasseldroid.util.backport.codec.Hex import de.kuschku.quasseldroid.util.helper.letIf @@ -37,8 +38,7 @@ object AvatarHelper { size: Int? = null) = listOfNotNull( message.avatarUrl.notBlank()?.let { listOf(Avatar.NativeAvatar(it)) }, settings.showIRCCloudAvatars.letIf { - ircCloudFallback(HostmaskHelper.user(message.sender), - size) + ircCloudFallback(HostmaskHelper.user(message.sender), size) }, settings.showGravatarAvatars.letIf { gravatarFallback(message.realName, size) @@ -52,8 +52,7 @@ object AvatarHelper { size: Int? = null) = listOfNotNull( message.avatarUrl.notBlank()?.let { listOf(Avatar.NativeAvatar(it)) }, settings.showIRCCloudAvatars.letIf { - ircCloudFallback(HostmaskHelper.user(message.sender), - size) + ircCloudFallback(HostmaskHelper.user(message.sender), size) }, settings.showGravatarAvatars.letIf { gravatarFallback(message.realName, size) @@ -65,16 +64,25 @@ object AvatarHelper { fun avatar(settings: MessageSettings, user: IrcUserItem, size: Int? = null) = listOfNotNull( settings.showIRCCloudAvatars.letIf { - ircCloudFallback(HostmaskHelper.user(user.hostmask), - size) + ircCloudFallback(HostmaskHelper.user(user.hostmask), size) }, settings.showGravatarAvatars.letIf { - gravatarFallback(user.realname.toString(), - size) + gravatarFallback(user.realname.toString(), size) }, settings.showMatrixAvatars.letIf { - matrixFallback(user.realname.toString(), - size) + matrixFallback(user.realname.toString(), size) + } + ).flatten() + + fun avatar(settings: MessageSettings, user: IrcUserInfo, size: Int? = null) = listOfNotNull( + settings.showIRCCloudAvatars.letIf { + ircCloudFallback(user.user ?: "", size) + }, + settings.showGravatarAvatars.letIf { + gravatarFallback(user.realName ?: "", size) + }, + settings.showMatrixAvatars.letIf { + matrixFallback(user.realName ?: "", size) } ).flatten() -- GitLab