Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

don't load custom emojis in their full size #4429

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
package com.keylesspalace.tusky.adapter

import android.graphics.Typeface
import android.text.SpannableStringBuilder
import android.text.SpannableString
import android.text.Spanned
import android.text.style.StyleSpan
import androidx.recyclerview.widget.RecyclerView
Expand Down Expand Up @@ -67,7 +67,7 @@ class FollowRequestViewHolder(
val wrappedName = account.name.unicodeWrap()
val emojifiedName: CharSequence = wrappedName.emojify(
account.emojis,
itemView,
binding.displayNameTextView,
animateEmojis
)
binding.displayNameTextView.text = emojifiedName
Expand All @@ -76,9 +76,9 @@ class FollowRequestViewHolder(
R.string.notification_follow_request_format,
wrappedName
)
binding.notificationTextView.text = SpannableStringBuilder(wholeMessage).apply {
binding.notificationTextView.text = SpannableString(wholeMessage).apply {
setSpan(StyleSpan(Typeface.BOLD), 0, wrappedName.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}.emojify(account.emojis, itemView, animateEmojis)
}.emojify(account.emojis, binding.notificationTextView, animateEmojis)
}
binding.notificationTextView.visible(showHeader)
val formattedUsername = itemView.context.getString(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import com.keylesspalace.tusky.util.emojify
import com.keylesspalace.tusky.util.parseAsMastodonHtml
import com.keylesspalace.tusky.util.setClickableText
import com.keylesspalace.tusky.util.visible
import java.lang.ref.WeakReference

interface AnnouncementActionListener : LinkListener {
fun openReactionPicker(announcementId: String, target: View)
Expand Down Expand Up @@ -111,7 +110,7 @@ class AnnouncementAdapter(
// we set the EmojiSpan on a space, because otherwise the Chip won't have the right size
// https://github.com/tuskyapp/Tusky/issues/2308
val spanBuilder = SpannableStringBuilder(" ${reaction.count}")
val span = EmojiSpan(WeakReference(this))
val span = EmojiSpan(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
span.contentDescription = reaction.name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ class ReportNotificationViewHolder(
val report = viewData.report!!
val reporter = viewData.account

val reporterName = reporter.name.unicodeWrap().emojify(reporter.emojis, itemView, statusDisplayOptions.animateEmojis)
val reporteeName = report.targetAccount.name.unicodeWrap().emojify(report.targetAccount.emojis, itemView, statusDisplayOptions.animateEmojis)
val reporterName = reporter.name.unicodeWrap().emojify(reporter.emojis, binding.notificationTopText, statusDisplayOptions.animateEmojis)
val reporteeName = report.targetAccount.name.unicodeWrap().emojify(report.targetAccount.emojis, binding.notificationTopText, statusDisplayOptions.animateEmojis)

binding.notificationTopText.text = itemView.context.getString(R.string.notification_header_report_format, reporterName, reporteeName)
binding.notificationSummary.text = itemView.context.getString(R.string.notification_summary_report_format, getRelativeTimeSpanString(itemView.context, report.createdAt.time, System.currentTimeMillis()), report.statusIds?.size ?: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import android.graphics.drawable.Drawable
import android.text.SpannableStringBuilder
import android.text.style.ReplacementSpan
import android.view.View
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.Emoji
import java.lang.ref.WeakReference
import java.util.regex.Pattern
Expand All @@ -51,7 +53,7 @@ fun CharSequence.emojify(emojis: List<Emoji>, view: View, animate: Boolean): Cha
.matcher(this)

while (matcher.find()) {
val span = EmojiSpan(WeakReference(view))
val span = EmojiSpan(view)

builder.setSpan(span, matcher.start(), matcher.end(), 0)
Glide.with(view)
Expand All @@ -69,7 +71,19 @@ fun CharSequence.emojify(emojis: List<Emoji>, view: View, animate: Boolean): Cha
return builder
}

class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan() {
class EmojiSpan(view: View) : ReplacementSpan() {

private val viewWeakReference = WeakReference(view)

private val emojiSize: Int = if (view is TextView) {
view.paint.textSize
} else {
// sometimes it is not possible to determine the TextView the emoji will be shown in,
// e.g. because it is passed to a library, so we fallback to a size that should be large
// enough in most cases
view.context.resources.getDimension(R.dimen.fallback_emoji_size)
}.times(1.2).toInt()

var imageDrawable: Drawable? = null

override fun getSize(
Expand All @@ -89,7 +103,7 @@ class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan()
fm.bottom = metrics.bottom
}

return (paint.textSize * 1.2).toInt()
return emojiSize
}

override fun draw(
Expand Down Expand Up @@ -134,7 +148,7 @@ class EmojiSpan(val viewWeakReference: WeakReference<View>) : ReplacementSpan()
}

fun getTarget(animate: Boolean): Target<Drawable> {
return object : CustomTarget<Drawable>() {
return object : CustomTarget<Drawable>(emojiSize, emojiSize) {
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
viewWeakReference.get()?.let { view ->
if (animate && resource is Animatable) {
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/keylesspalace/tusky/util/LinkHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.HashTag
import com.keylesspalace.tusky.entity.Status.Mention
import com.keylesspalace.tusky.interfaces.LinkListener
import java.lang.ref.WeakReference
import java.net.URI
import java.net.URISyntaxException

Expand Down Expand Up @@ -128,7 +127,7 @@ fun markupHiddenUrls(view: TextView, content: CharSequence): SpannableStringBuil

val linkDrawable = AppCompatResources.getDrawable(view.context, R.drawable.ic_link)!!
// ImageSpan does not always align the icon correctly in the line, let's use our custom emoji span for this
val linkDrawableSpan = EmojiSpan(WeakReference(view))
val linkDrawableSpan = EmojiSpan(view)
linkDrawableSpan.imageDrawable = linkDrawable

val placeholderIndex = replacementText.indexOf("🔗")
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,6 @@

<dimen name="account_swiperefresh_distance">64dp</dimen>

<dimen name="fallback_emoji_size">16sp</dimen>

</resources>
Loading