diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 3088277551..91c9fc9e50 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -115,6 +115,7 @@ import org.thoughtcrime.securesms.util.InterceptableLongClickCopyLinkSpan; import org.thoughtcrime.securesms.util.LongClickMovementMethod; import org.thoughtcrime.securesms.util.MessageRecordUtil; import org.thoughtcrime.securesms.util.SearchUtil; +import org.thoughtcrime.securesms.util.StringUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.ThemeUtil; import org.thoughtcrime.securesms.util.UrlClickHandler; @@ -642,7 +643,7 @@ public class ConversationItem extends LinearLayout implements BindableConversati bodyText.setMentionBackgroundTint(ContextCompat.getColor(context, R.color.transparent_black_40)); } - bodyText.setText(styledText); + bodyText.setText(StringUtil.trim(styledText)); bodyText.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java index 953ae88d9a..0f0a127739 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/StringUtil.java @@ -59,6 +59,33 @@ public final class StringUtil { return name; } + /** + * @return A charsequence with no leading or trailing whitespace. Only creates a new charsequence + * if it has to. + */ + public static @NonNull CharSequence trim(@NonNull CharSequence charSequence) { + if (charSequence.length() == 0) { + return charSequence; + } + + int start = 0; + int end = charSequence.length() - 1; + + while (start < charSequence.length() && Character.isWhitespace(charSequence.charAt(start))) { + start++; + } + + while (end >= 0 && end > start && Character.isWhitespace(charSequence.charAt(end))) { + end--; + } + + if (start > 0 || end < charSequence.length() - 1) { + return charSequence.subSequence(start, end + 1); + } else { + return charSequence; + } + } + /** * @return True if the string is empty, or if it contains nothing but whitespace characters. * Accounts for various unicode whitespace characters. diff --git a/app/src/test/java/org/thoughtcrime/securesms/util/StringUtilTest_trim.java b/app/src/test/java/org/thoughtcrime/securesms/util/StringUtilTest_trim.java new file mode 100644 index 0000000000..9d0fb446c6 --- /dev/null +++ b/app/src/test/java/org/thoughtcrime/securesms/util/StringUtilTest_trim.java @@ -0,0 +1,59 @@ +package org.thoughtcrime.securesms.util; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.Arrays; +import java.util.Collection; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; + +@RunWith(Parameterized.class) +public final class StringUtilTest_trim { + + private final CharSequence input; + private final CharSequence expected; + private final boolean changed; + + @Parameterized.Parameters + public static Collection data() { + return Arrays.asList(new Object[][]{ + { "", "", false }, + { " ", "", true }, + { " ", "", true }, + { "\n", "", true}, + { "\n\n\n", "", true }, + { "A", "A", false }, + { "A ", "A", true }, + { " A", "A", true }, + { " A ", "A", true }, + { "\nA\n", "A", true }, + { "A\n\n", "A", true }, + { "A\n\nB", "A\n\nB", false }, + { "A\n\nB ", "A\n\nB", true }, + { "A B", "A B", false }, + }); + } + + public StringUtilTest_trim(CharSequence input, CharSequence expected, boolean changed) { + this.input = input; + this.expected = expected; + this.changed = changed; + } + + @Test + public void trim() { + CharSequence output = StringUtil.trim(input); + assertEquals(expected, output); + + if (changed) { + assertNotSame(output, input); + } else { + assertSame(output, input); + } + } + +} \ No newline at end of file