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
}
}
}

View File

@@ -56,7 +56,7 @@
tools:visibility="gone" />
<!-- Body -->
<LinearLayout
<org.thoughtcrime.securesms.conversation.v2.items.ShrinkWrapLinearLayout
android:id="@+id/conversation_item_body_wrapper"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -104,10 +104,11 @@
app:emoji_maxLength="1000"
app:emoji_renderMentions="true"
app:emoji_renderSpoilers="true"
app:emoji_shrinkWrap="true"
app:measureLastLine="true"
app:scaleEmojis="true"
tools:text="Testy test test test" />
</LinearLayout>
</org.thoughtcrime.securesms.conversation.v2.items.ShrinkWrapLinearLayout>
<!-- Footer -->
<View
@@ -155,9 +156,9 @@
android:id="@+id/footer_end_pad"
android:layout_width="@dimen/message_bubble_horizontal_padding"
android:layout_height="@dimen/message_bubble_horizontal_padding"
app:layout_constraintTop_toTopOf="@id/conversation_item_footer_date"
app:layout_constraintBottom_toBottomOf="@id/conversation_item_body_wrapper"
app:layout_constraintEnd_toEndOf="@id/conversation_item_body_wrapper" />
app:layout_constraintEnd_toEndOf="@id/conversation_item_body_wrapper"
app:layout_constraintTop_toTopOf="@id/conversation_item_footer_date" />
<!-- End Footer -->

View File

@@ -60,6 +60,7 @@
app:emoji_maxLength="1000"
app:emoji_renderMentions="true"
app:emoji_renderSpoilers="true"
app:emoji_shrinkWrap="true"
app:measureLastLine="true"
app:scaleEmojis="true"
tools:text="Mango pickle lorem ipsum" />

View File

@@ -153,6 +153,7 @@
<attr name="emoji_renderMentions" format="boolean" />
<attr name="emoji_forceJumbo" format="boolean" />
<attr name="emoji_renderSpoilers" format="boolean" />
<attr name="emoji_shrinkWrap" format="boolean" />
</declare-styleable>
<declare-styleable name="EmojiImageView">