Rich quotes

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/Message.java | 27 +++++--
1 file changed, 19 insertions(+), 8 deletions(-)

Detailed changes

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

@@ -130,7 +130,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
     protected Jid trueCounterpart;
     protected String occupantId = null;
     protected String body;
-    protected SpannableStringBuilder spannableBody = null;
     protected String subject;
     protected String encryptedBody;
     protected long timeSent;
@@ -632,7 +631,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         final Element oldHtml = getHtml(true);
         if (oldHtml != null) this.payloads.remove(oldHtml);
         if (html != null) addPayload(html);
-        this.spannableBody = null;
     }
 
     public synchronized void setBody(String body) {
@@ -640,7 +638,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         this.isGeoUri = null;
         this.isEmojisOnly = null;
         this.treatAsDownloadable = null;
-        this.spannableBody = null;
     }
 
     public synchronized void appendBody(Spanned append) {
@@ -656,7 +653,6 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
         this.isGeoUri = null;
         this.isEmojisOnly = null;
         this.treatAsDownloadable = null;
-        this.spannableBody = null;
     }
 
     public String getSubject() {
@@ -1052,11 +1048,10 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
     }
 
     public SpannableStringBuilder getSpannableBody(GetThumbnailForCid thumbnailer, Drawable fallbackImg) {
-        if (spannableBody != null) return new SpannableStringBuilder(spannableBody);
-
+        SpannableStringBuilder spannableBody;
         final Element html = getHtml();
         if (html == null || Build.VERSION.SDK_INT < 24) {
-            spannableBody = new SpannableStringBuilder(MessageUtils.filterLtrRtl(getBody()).trim());
+            spannableBody = new SpannableStringBuilder(MessageUtils.filterLtrRtl(getBody(getInReplyTo() != null)).trim());
             spannableBody.setSpan(PLAIN_TEXT_SPAN, 0, spannableBody.length(), 0); // Let adapter know it can do more formatting
         } else {
             boolean[] anyfallbackimg = new boolean[]{ false };
@@ -1112,7 +1107,23 @@ public class Message extends AbstractEntity implements AvatarService.Avatarable
             spannableBody = (SpannableStringBuilder) spannable.subSequence(0, i+1);
         }
 
-        return new SpannableStringBuilder(spannableBody);
+        if (getInReplyTo() != null) {
+            final var quote = getInReplyTo().getSpannableBody(thumbnailer, fallbackImg);
+            if ((getInReplyTo().isFileOrImage() || getInReplyTo().isOOb()) && getInReplyTo().getFileParams() != null) {
+                quote.insert(0, "🖼️");
+                final var cid = getInReplyTo().getFileParams().getCids().get(0);
+                Drawable thumbnail = thumbnailer == null ? null : thumbnailer.getThumbnail(cid);
+                if (thumbnail == null) thumbnail = fallbackImg;
+                if (thumbnail != null) {
+                    quote.setSpan(new InlineImageSpan(thumbnail, cid.toString()), 0, 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                }
+            }
+            quote.setSpan(new android.text.style.QuoteSpan(), 0, quote.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+            spannableBody.insert(0, "\n");
+            spannableBody.insert(0, quote);
+        }
+
+        return spannableBody;
     }
 
     public SpannableStringBuilder getMergedBody() {