Fix spoiler rendering in conversation list.

This commit is contained in:
Cody Henthorne
2023-04-24 14:52:54 -04:00
committed by Nicholas
parent b0b2b02a49
commit 806e81743c
6 changed files with 45 additions and 23 deletions

View File

@@ -36,7 +36,6 @@ import org.thoughtcrime.securesms.components.mention.MentionRendererDelegate;
import org.thoughtcrime.securesms.components.spoiler.SpoilerRendererDelegate;
import org.thoughtcrime.securesms.emoji.JumboEmoji;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.util.SpoilerFilteringSpannable;
import org.thoughtcrime.securesms.util.Util;
import java.util.Arrays;
@@ -110,7 +109,7 @@ public class EmojiTextView extends AppCompatTextView {
}
public void enableSpoilerFiltering() {
spoilerFilteringSpannableFactory = new SpoilerFilteringSpannableFactory();
spoilerFilteringSpannableFactory = new SpoilerFilteringSpannableFactory(() -> isInOnDraw);
setSpannableFactory(spoilerFilteringSpannableFactory);
}
@@ -454,15 +453,4 @@ public class EmojiTextView extends AppCompatTextView {
mentionRendererDelegate.setTint(mentionBackgroundTint);
}
}
private class SpoilerFilteringSpannableFactory extends Spannable.Factory {
@Override
public @NonNull Spannable newSpannable(CharSequence source) {
return wrap(super.newSpannable(source));
}
@NonNull SpoilerFilteringSpannable wrap(Spannable source) {
return new SpoilerFilteringSpannable(source, () -> isInOnDraw);
}
}
}

View File

@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components.emoji
import android.content.Context
import android.graphics.Canvas
import android.text.Spannable
import android.text.Spanned
import android.text.TextUtils
import android.util.AttributeSet
@@ -20,6 +21,8 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
private var bufferType: BufferType? = null
private val sizeChangeDebouncer: ThrottledDebouncer = ThrottledDebouncer(200)
private val spoilerRendererDelegate: SpoilerRendererDelegate
private var spoilerFilteringSpannableFactory: SpoilerFilteringSpannableFactory? = null
private var isInOnDraw: Boolean = false
init {
isEmojiCompatEnabled = isInEditMode || SignalStore.settings().isPreferSystemEmoji
@@ -27,6 +30,8 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
}
override fun onDraw(canvas: Canvas) {
isInOnDraw = true
if (text is Spanned && layout != null) {
val checkpoint = canvas.save()
canvas.translate(totalPaddingLeft.toFloat(), totalPaddingTop.toFloat())
@@ -37,6 +42,8 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
}
}
super.onDraw(canvas)
isInOnDraw = false
}
override fun setText(text: CharSequence?, type: BufferType?) {
@@ -56,11 +63,16 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
EmojiProvider.emojify(newCandidates, text, this, false)
}
val newContent = if (width == 0 || maxLines == -1) {
var newContent: CharSequence? = if (width == 0 || maxLines == -1) {
newText
} else {
TextUtils.ellipsize(newText, paint, (adjustedWidth * maxLines).toFloat(), TextUtils.TruncateAt.END, false, null)
}
if (newContent is Spannable && spoilerFilteringSpannableFactory != null) {
newContent = spoilerFilteringSpannableFactory!!.wrap(newContent)
}
bufferType = BufferType.SPANNABLE
super.setText(newContent, type)
}
@@ -74,4 +86,9 @@ open class SimpleEmojiTextView @JvmOverloads constructor(
}
}
}
fun enableSpoilerFiltering() {
spoilerFilteringSpannableFactory = SpoilerFilteringSpannableFactory { isInOnDraw }
setSpannableFactory(spoilerFilteringSpannableFactory!!)
}
}

View File

@@ -0,0 +1,21 @@
package org.thoughtcrime.securesms.components.emoji
import android.text.Spannable
import org.thoughtcrime.securesms.util.SpoilerFilteringSpannable
import org.thoughtcrime.securesms.util.SpoilerFilteringSpannable.InOnDrawProvider
/**
* Spannable factory used to help ensure spans are copied/maintained properly through the
* Android text handling system.
*
* @param inOnDraw Used by [SpoilerFilteringSpannable] to remove spans when being called from onDraw
*/
class SpoilerFilteringSpannableFactory(private val inOnDraw: InOnDrawProvider) : Spannable.Factory() {
override fun newSpannable(source: CharSequence): Spannable {
return wrap(super.newSpannable(source))
}
fun wrap(source: Spannable): SpoilerFilteringSpannable {
return SpoilerFilteringSpannable(source, inOnDraw)
}
}