Make rich text optional, don't double-style html

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/Message.java          | 3 
src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java | 6 
src/main/java/eu/siacs/conversations/utils/StylingHelper.java       | 3 
src/main/res/values/bools.xml                                       | 1 
src/main/res/xml/preferences_interface.xml                          | 6 
5 files changed, 17 insertions(+), 2 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/Message.java 🔗

@@ -1016,6 +1016,7 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         final Element html = getHtml();
         if (html == null || Build.VERSION.SDK_INT < 24) {
             spannableBody = new SpannableStringBuilder(MessageUtils.filterLtrRtl(getBody()).trim());
+            spannableBody.setSpan(PLAIN_TEXT_SPAN, 0, spannableBody.length(), 0); // Let adapter know it can do more formatting
         } else {
             boolean[] anyfallbackimg = new boolean[]{ false };
 
@@ -1743,4 +1744,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         message.setType(isFile ? Message.TYPE_PRIVATE_FILE : Message.TYPE_PRIVATE);
         return true;
     }
+
+    public static class PlainTextSpan {}
 }

src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java 🔗

@@ -612,6 +612,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
             viewHolder.messageBody.setVisibility(View.VISIBLE);
             final String nick = UIHelper.getMessageDisplayName(message);
             SpannableStringBuilder body = getSpannableBody(message);
+            final var processMarkup = body.getSpans(0, body.length(), Message.PlainTextSpan.class).length > 0;
             boolean hasMeCommand = message.hasMeCommand();
             if (hasMeCommand) {
                 body = body.replace(0, Message.ME_COMMAND.length(), nick + " ");
@@ -633,7 +634,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
                 body.removeSpan(quote);
                 applyQuoteSpan(viewHolder.messageBody, body, start, end, bubbleColor, true);
             }
-            boolean startsWithQuote = handleTextQuotes(viewHolder.messageBody, body, bubbleColor, true);
+            boolean startsWithQuote = processMarkup ? handleTextQuotes(viewHolder.messageBody, body, bubbleColor, true) : false;
             if (!message.isPrivateMessage()) {
                 if (hasMeCommand) {
                     body.setSpan(
@@ -717,7 +718,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
                 }
             }
 
-            StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
+            if (processMarkup) StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor());
             MyLinkify.addLinks(body, message.getConversation().getAccount(), message.getConversation().getJid());
             if (highlightedTerm != null) {
                 StylingHelper.highlight(viewHolder.messageBody, body, highlightedTerm);
@@ -1593,6 +1594,7 @@ public class MessageAdapter extends ArrayAdapter<Message> {
         if (largeFont) {
             textView.setTextAppearance(
                     com.google.android.material.R.style.TextAppearance_Material3_BodyLarge);
+            textView.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 22);
         } else {
             textView.setTextAppearance(
                     com.google.android.material.R.style.TextAppearance_Material3_BodyMedium);

src/main/java/eu/siacs/conversations/utils/StylingHelper.java 🔗

@@ -32,6 +32,7 @@ package eu.siacs.conversations.utils;
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.Typeface;
+import android.preference.PreferenceManager;
 import android.text.Editable;
 import android.text.ParcelableSpan;
 import android.text.Spannable;
@@ -251,6 +252,8 @@ public class StylingHelper {
 		@Override
 		public void afterTextChanged(Editable editable) {
 			clear(editable);
+			final var p = PreferenceManager.getDefaultSharedPreferences(mEditText.getContext());
+			if (!p.getBoolean("compose_rich_text", mEditText.getContext().getResources().getBoolean(R.bool.compose_rich_text))) return;
 			for (final var span : editable.getSpans(0, editable.length() - 1, QuoteSpan.class)) {
 				editable.removeSpan(span);
 			}

src/main/res/values/bools.xml 🔗

@@ -2,4 +2,5 @@
 <resources>
     <bool name="show_avatar_incoming_call">true</bool>
     <bool name="send_link_previews">true</bool>
+    <bool name="compose_rich_text">true</bool>
 </resources>

src/main/res/xml/preferences_interface.xml 🔗

@@ -142,6 +142,12 @@
             android:key="message_autocomplete"
             android:summary="@string/pref_message_autocomplete_summary"
             android:title="@string/pref_message_autocomplete" />
+        <SwitchPreferenceCompat
+            android:icon="@drawable/ic_format_size_24dp"
+            android:defaultValue="@bool/compose_rich_text"
+            android:key="compose_rich_text"
+            android:summary="The message editor will show formatting as you type"
+            android:title="Compose using rich text" />
     </PreferenceCategory>
     <PreferenceCategory android:title="@string/pref_keyboard_options">
         <SwitchPreferenceCompat