Fix conversation bubbles becoming too long.

Co-authored-by: Cody Henthorne <cody@signal.org>
This commit is contained in:
Alex Hart
2024-01-23 15:55:54 -04:00
committed by Nicholas Tinsley
parent 4ada7c9be9
commit e71bb33b23
5 changed files with 65 additions and 4 deletions

View File

@@ -32,6 +32,7 @@ import androidx.core.view.GestureDetectorCompat;
import androidx.core.view.ViewKt;
import androidx.core.widget.TextViewCompat;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
import org.thoughtcrime.securesms.components.mention.MentionAnnotation;
@@ -73,6 +74,7 @@ public class EmojiTextView extends AppCompatTextView {
private boolean isJumbomoji;
private boolean forceJumboEmoji;
private boolean renderSpoilers;
private boolean shrinkWrap;
private MentionRendererDelegate mentionRendererDelegate;
private SpoilerRendererDelegate spoilerRendererDelegate;
@@ -96,6 +98,7 @@ public class EmojiTextView extends AppCompatTextView {
measureLastLine = a.getBoolean(R.styleable.EmojiTextView_measureLastLine, false);
forceJumboEmoji = a.getBoolean(R.styleable.EmojiTextView_emoji_forceJumbo, false);
renderSpoilers = a.getBoolean(R.styleable.EmojiTextView_emoji_renderSpoilers, false);
shrinkWrap = a.getBoolean(R.styleable.EmojiTextView_emoji_shrinkWrap, false);
a.recycle();
a = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.textSize });
@@ -224,6 +227,25 @@ public class EmojiTextView extends AppCompatTextView {
widthMeasureSpec = applyWidthMeasureRoundingFix(widthMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int mode = MeasureSpec.getMode(widthMeasureSpec);
if (shrinkWrap && getLayout() != null && mode == MeasureSpec.AT_MOST) {
Layout layout = getLayout();
float maxLineWidth = 0f;
for (int i = 0; i < layout.getLineCount(); i++) {
if (layout.getLineWidth(i) > maxLineWidth) {
maxLineWidth = layout.getLineWidth(i);
}
}
int desiredWidth = (int) maxLineWidth + getPaddingLeft() + getPaddingRight();
if (getMeasuredWidth() > desiredWidth) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(desiredWidth, mode);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
CharSequence text = getText();
if (getLayout() == null || !measureLastLine || text == null || text.length() == 0) {
lastLineWidth = -1;

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2024 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.conversation.v2.items
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.LinearLayoutCompat
/**
* Custom LinearLayoutCompat that will intercept EXACTLY measure-specs and
* overwrite them with AT_MOST. This guarantees that wrap_content is respected
* when the Layout is within a constraintlayout.
*/
class ShrinkWrapLinearLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : LinearLayoutCompat(context, attrs) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val shrinkWrapWidthSpec = shrinkWrapWidthMeasureSpec(widthMeasureSpec)
super.onMeasure(shrinkWrapWidthSpec, heightMeasureSpec)
}
private fun shrinkWrapWidthMeasureSpec(widthMeasureSpec: Int): Int {
val mode = MeasureSpec.getMode(widthMeasureSpec)
val size = MeasureSpec.getSize(widthMeasureSpec)
return if (mode == MeasureSpec.EXACTLY) {
MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST)
} else {
widthMeasureSpec
}
}
}