mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 04:58:45 +00:00
Fix formatting on long text messages.
This commit is contained in:
@@ -363,7 +363,7 @@ public class ComposeText extends EmojiEditText {
|
||||
} else if (item.getItemId() == R.id.edittext_monospace) {
|
||||
style = MessageStyler.monoStyle();
|
||||
} else if (item.getItemId() == R.id.edittext_spoiler) {
|
||||
style = MessageStyler.spoilerStyle(MessageStyler.COMPOSE_ID, start, charSequence.length(), text);
|
||||
style = MessageStyler.spoilerStyle(MessageStyler.COMPOSE_ID, start, charSequence.length());
|
||||
}
|
||||
|
||||
if (style != null) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.os.Build;
|
||||
import android.text.Annotation;
|
||||
import android.text.Layout;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextDirectionHeuristic;
|
||||
@@ -315,12 +316,19 @@ public class EmojiTextView extends AppCompatTextView {
|
||||
if (maxLength > 0 && getText().length() > maxLength + 1) {
|
||||
SpannableStringBuilder newContent = new SpannableStringBuilder();
|
||||
|
||||
CharSequence shortenedText = getText().subSequence(0, maxLength);
|
||||
if (shortenedText instanceof Spanned) {
|
||||
Spanned spanned = (Spanned) shortenedText;
|
||||
List<Annotation> mentionAnnotations = MentionAnnotation.getMentionAnnotations(spanned, maxLength - 1, maxLength);
|
||||
if (!mentionAnnotations.isEmpty()) {
|
||||
shortenedText = shortenedText.subSequence(0, spanned.getSpanStart(mentionAnnotations.get(0)));
|
||||
SpannableString shortenedText = new SpannableString(getText().subSequence(0, maxLength));
|
||||
List<Annotation> mentionAnnotations = MentionAnnotation.getMentionAnnotations(shortenedText, maxLength - 1, maxLength);
|
||||
if (!mentionAnnotations.isEmpty()) {
|
||||
shortenedText = new SpannableString(shortenedText.subSequence(0, shortenedText.getSpanStart(mentionAnnotations.get(0))));
|
||||
}
|
||||
|
||||
Object[] endSpans = shortenedText.getSpans(shortenedText.length() - 1, shortenedText.length(), Object.class);
|
||||
for (Object span : endSpans) {
|
||||
if (shortenedText.getSpanFlags(span) == Spanned.SPAN_EXCLUSIVE_INCLUSIVE) {
|
||||
int start = shortenedText.getSpanStart(span);
|
||||
int end = shortenedText.getSpanEnd(span);
|
||||
shortenedText.removeSpan(span);
|
||||
shortenedText.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,12 +338,18 @@ public class EmojiTextView extends AppCompatTextView {
|
||||
|
||||
EmojiParser.CandidateList newCandidates = isInEditMode() ? null : EmojiProvider.getCandidates(newContent);
|
||||
|
||||
Spannable newTextToSet;
|
||||
if (useSystemEmoji || newCandidates == null || newCandidates.size() == 0) {
|
||||
super.setText(newContent, BufferType.SPANNABLE);
|
||||
newTextToSet = newContent;
|
||||
} else {
|
||||
CharSequence emojified = EmojiProvider.emojify(newCandidates, newContent, this, isJumbomoji || forceJumboEmoji);
|
||||
super.setText(emojified, BufferType.SPANNABLE);
|
||||
newTextToSet = EmojiProvider.emojify(newCandidates, newContent, this, isJumbomoji || forceJumboEmoji);
|
||||
}
|
||||
|
||||
if (spoilerFilteringSpannableFactory != null) {
|
||||
spoilerFilteringSpannableFactory.wrap(newTextToSet);
|
||||
}
|
||||
|
||||
super.setText(newContent, BufferType.SPANNABLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ object MessageStyler {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun spoilerStyle(id: Any, start: Int, length: Int, body: Spannable? = null): Annotation {
|
||||
return SpoilerAnnotation.spoilerAnnotation(arrayOf(id, start, length, body?.toString()).contentHashCode())
|
||||
fun spoilerStyle(id: Any, start: Int, length: Int): Annotation {
|
||||
return SpoilerAnnotation.spoilerAnnotation(arrayOf(id, start, length).contentHashCode())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@@ -61,8 +61,11 @@ object MessageStyler {
|
||||
|
||||
messageRanges
|
||||
.rangesList
|
||||
.filter { r -> r.start >= 0 && r.start < span.length && r.start + r.length >= 0 && r.start + r.length <= span.length }
|
||||
.filter { r -> r.start >= 0 && r.start < span.length && r.start + r.length >= 0 }
|
||||
.forEach { range ->
|
||||
val start = range.start
|
||||
val end = (range.start + range.length).coerceAtMost(span.length)
|
||||
|
||||
if (range.hasStyle()) {
|
||||
val styleSpan: Any? = when (range.style) {
|
||||
BodyRangeList.BodyRange.Style.BOLD -> boldStyle()
|
||||
@@ -70,9 +73,9 @@ object MessageStyler {
|
||||
BodyRangeList.BodyRange.Style.STRIKETHROUGH -> strikethroughStyle()
|
||||
BodyRangeList.BodyRange.Style.MONOSPACE -> monoStyle()
|
||||
BodyRangeList.BodyRange.Style.SPOILER -> {
|
||||
val spoiler = spoilerStyle(id, range.start, range.length, span)
|
||||
val spoiler = spoilerStyle(id, range.start, range.length)
|
||||
if (hideSpoilerText) {
|
||||
span.setSpan(SpoilerAnnotation.SpoilerClickableSpan(spoiler), range.start, range.start + range.length, SPAN_FLAGS)
|
||||
span.setSpan(SpoilerAnnotation.SpoilerClickableSpan(spoiler), start, end, SPAN_FLAGS)
|
||||
}
|
||||
spoiler
|
||||
}
|
||||
@@ -80,11 +83,11 @@ object MessageStyler {
|
||||
}
|
||||
|
||||
if (styleSpan != null) {
|
||||
span.setSpan(styleSpan, range.start, range.start + range.length, SPAN_FLAGS)
|
||||
span.setSpan(styleSpan, start, end, SPAN_FLAGS)
|
||||
appliedStyle = true
|
||||
}
|
||||
} else if (range.hasLink() && range.link != null) {
|
||||
span.setSpan(PlaceholderURLSpan(range.link), range.start, range.start + range.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
span.setSpan(PlaceholderURLSpan(range.link), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
hasLinks = true
|
||||
} else if (range.hasButton() && range.button != null) {
|
||||
bottomButton = range.button
|
||||
|
||||
@@ -129,6 +129,7 @@ public class LongMessageFragment extends FullScreenDialogFragment {
|
||||
SpannableString styledBody = linkifyMessageBody(new SpannableString(trimmedBody));
|
||||
|
||||
bubble.setVisibility(View.VISIBLE);
|
||||
text.enableSpoilerFiltering();
|
||||
text.setText(styledBody);
|
||||
text.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings().getMessageFontSize());
|
||||
|
||||
Reference in New Issue
Block a user