Use tags from status when adding handlers to hashtag spans in status content (#2344)

* Migrate LinkHelper to kotlin

* Support tags field on statuses

* Use embedded tags list in status instead of text scraping to embed tag click handler.
Fixes #2283

* Make mentions and tags lists nonnullable

* Make LinkHelper.openLink a Context extension method

* Use builtin extension for uri conversion

* More cleanup in LinkHelper

* Add tests for LinkHelper.getDomain

* Unbreak tags in places that don't have a tag list (e.g. profiles)

* Fixup javadoc
This commit is contained in:
Levi Bard 2022-02-25 18:56:21 +01:00 committed by GitHub
commit addce87eb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1294 additions and 296 deletions

View file

@ -71,13 +71,15 @@ import com.keylesspalace.tusky.interfaces.ReselectableFragment
import com.keylesspalace.tusky.settings.PrefKeys
import com.keylesspalace.tusky.util.DefaultTextWatcher
import com.keylesspalace.tusky.util.Error
import com.keylesspalace.tusky.util.LinkHelper
import com.keylesspalace.tusky.util.Loading
import com.keylesspalace.tusky.util.Success
import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.emojify
import com.keylesspalace.tusky.util.getDomain
import com.keylesspalace.tusky.util.hide
import com.keylesspalace.tusky.util.loadAvatar
import com.keylesspalace.tusky.util.openLink
import com.keylesspalace.tusky.util.setClickableText
import com.keylesspalace.tusky.util.show
import com.keylesspalace.tusky.util.viewBinding
import com.keylesspalace.tusky.util.visible
@ -409,7 +411,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
binding.accountDisplayNameTextView.text = account.name.emojify(account.emojis, binding.accountDisplayNameTextView, animateEmojis)
val emojifiedNote = account.note.emojify(account.emojis, binding.accountNoteTextView, animateEmojis)
LinkHelper.setClickableText(binding.accountNoteTextView, emojifiedNote, null, this)
setClickableText(binding.accountNoteTextView, emojifiedNote, emptyList(), null, this)
// accountFieldAdapter.fields = account.fields ?: emptyList()
accountFieldAdapter.emojis = account.emojis ?: emptyList()
@ -517,7 +519,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
if (account.isRemote()) {
binding.accountRemoveView.show()
binding.accountRemoveView.setOnClickListener {
LinkHelper.openLink(account.url, this)
openLink(account.url)
}
}
}
@ -714,7 +716,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
if (loadedAccount != null) {
val muteDomain = menu.findItem(R.id.action_mute_domain)
domain = LinkHelper.getDomain(loadedAccount?.url)
domain = getDomain(loadedAccount?.url)
if (domain.isEmpty()) {
// If we can't get the domain, there's no way we can mute it anyway...
menu.removeItem(R.id.action_mute_domain)
@ -834,8 +836,8 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
when (item.itemId) {
R.id.action_open_in_web -> {
// If the account isn't loaded yet, eat the input.
if (loadedAccount != null) {
LinkHelper.openLink(loadedAccount?.url, this)
if (loadedAccount?.url != null) {
openLink(loadedAccount!!.url)
}
return true
}

View file

@ -27,8 +27,9 @@ import com.keylesspalace.tusky.entity.IdentityProof
import com.keylesspalace.tusky.interfaces.LinkListener
import com.keylesspalace.tusky.util.BindingHolder
import com.keylesspalace.tusky.util.Either
import com.keylesspalace.tusky.util.LinkHelper
import com.keylesspalace.tusky.util.createClickableText
import com.keylesspalace.tusky.util.emojify
import com.keylesspalace.tusky.util.setClickableText
class AccountFieldAdapter(
private val linkListener: LinkListener,
@ -54,7 +55,7 @@ class AccountFieldAdapter(
val identityProof = proofOrField.asLeft()
nameTextView.text = identityProof.provider
valueTextView.text = LinkHelper.createClickableText(identityProof.username, identityProof.profileUrl)
valueTextView.text = createClickableText(identityProof.username, identityProof.profileUrl)
valueTextView.movementMethod = LinkMovementMethod.getInstance()
@ -65,7 +66,7 @@ class AccountFieldAdapter(
nameTextView.text = emojifiedName
val emojifiedValue = field.value.emojify(emojis, valueTextView, animateEmojis)
LinkHelper.setClickableText(valueTextView, emojifiedValue, null, linkListener)
setClickableText(valueTextView, emojifiedValue, emptyList(), null, linkListener)
if (field.verifiedAt != null) {
valueTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, R.drawable.ic_check_circle, 0)

View file

@ -37,9 +37,9 @@ import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.interfaces.RefreshableFragment
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.LinkHelper
import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.hide
import com.keylesspalace.tusky.util.openLink
import com.keylesspalace.tusky.util.show
import com.keylesspalace.tusky.util.viewBinding
import com.keylesspalace.tusky.view.SquareImageView
@ -252,7 +252,7 @@ class AccountMediaFragment : Fragment(R.layout.fragment_timeline), RefreshableFr
}
}
Attachment.Type.UNKNOWN -> {
LinkHelper.openLink(items[currentIndex].attachment.url, context)
context?.openLink(items[currentIndex].attachment.url)
}
}
}