From dcb2bb5d3536c5230775627ad4c833e7cbd2cf48 Mon Sep 17 00:00:00 2001 From: Arne Date: Thu, 19 Sep 2024 12:42:10 +0200 Subject: [PATCH] Apply monocles read more read less feature --- .../ui/adapter/MessageAdapter.java | 12 +- src/main/res/layout/fragment_conversation.xml | 6 +- src/main/res/layout/item_message_content.xml | 18 +- src/main/res/values/bools.xml | 1 + src/main/res/values/strings.xml | 4 + src/main/res/xml/preferences_interface.xml | 6 + .../de/monocles/chat/ReadMoreListener.java | 9 + .../de/monocles/chat/ReadMoreTextView.java | 239 ++++++++++++++++++ src/monocleschat/res/values/attrs.xml | 14 + 9 files changed, 305 insertions(+), 4 deletions(-) create mode 100644 src/monocleschat/java/de/monocles/chat/ReadMoreListener.java create mode 100644 src/monocleschat/java/de/monocles/chat/ReadMoreTextView.java diff --git a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java index b1139a606..b00656bde 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -1136,7 +1136,11 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.indicator = view.findViewById(R.id.security_indicator); viewHolder.edit_indicator = view.findViewById(R.id.edit_indicator); viewHolder.image = view.findViewById(R.id.message_image); - viewHolder.messageBody = view.findViewById(R.id.message_body); + if (activity.xmppConnectionService.getBooleanPreference("set_text_collapsable", R.bool.set_text_collapsable)) { + viewHolder.messageBody = view.findViewById(R.id.message_body_collapsable); + } else if (!activity.xmppConnectionService.getBooleanPreference("set_text_collapsable", R.bool.set_text_collapsable)) { + viewHolder.messageBody = view.findViewById(R.id.message_body); + } viewHolder.time = view.findViewById(R.id.message_time); viewHolder.subject = view.findViewById(R.id.message_subject); viewHolder.inReplyTo = view.findViewById(R.id.in_reply_to); @@ -1160,7 +1164,11 @@ public class MessageAdapter extends ArrayAdapter { viewHolder.indicator = view.findViewById(R.id.security_indicator); viewHolder.edit_indicator = view.findViewById(R.id.edit_indicator); viewHolder.image = view.findViewById(R.id.message_image); - viewHolder.messageBody = view.findViewById(R.id.message_body); + if (activity.xmppConnectionService.getBooleanPreference("set_text_collapsable", R.bool.set_text_collapsable)) { + viewHolder.messageBody = view.findViewById(R.id.message_body_collapsable); + } else if (!activity.xmppConnectionService.getBooleanPreference("set_text_collapsable", R.bool.set_text_collapsable)) { + viewHolder.messageBody = view.findViewById(R.id.message_body); + } viewHolder.time = view.findViewById(R.id.message_time); viewHolder.subject = view.findViewById(R.id.message_subject); viewHolder.inReplyTo = view.findViewById(R.id.in_reply_to); diff --git a/src/main/res/layout/fragment_conversation.xml b/src/main/res/layout/fragment_conversation.xml index 543773ecf..9316de1c3 100644 --- a/src/main/res/layout/fragment_conversation.xml +++ b/src/main/res/layout/fragment_conversation.xml @@ -135,7 +135,11 @@ app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" android:visibility="gone" /> - + android:textAppearance="?textAppearanceBodyMedium" + android:visibility="gone" /> + + false true false + false diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 69c1063a0..b076a276c 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1114,4 +1114,8 @@ Load a preview of maps for a share location inside the chat Show own account name Shows the used account on messages overview and details + Collapses text with more than 230 signs + Collapse long text + ... show less + ... show more diff --git a/src/main/res/xml/preferences_interface.xml b/src/main/res/xml/preferences_interface.xml index c6c76eca5..a8ffcdc45 100644 --- a/src/main/res/xml/preferences_interface.xml +++ b/src/main/res/xml/preferences_interface.xml @@ -117,6 +117,12 @@ android:entryValues="@array/avatars_shape_values" android:summary="@string/pref_avatar_shape_summary" android:title="@string/pref_avatars_shape" /> + trimLength) { + if (readMore) { + return updateCollapsedText(); + } else { + return updateExpandedText(); + } + } + } + if (trimMode == TRIM_MODE_LINES) { + if (text != null && lineEndIndex > 0) { + if (readMore) { + if (getLayout().getLineCount() > trimLines) { + return updateCollapsedText(); + } + } else { + return updateExpandedText(); + } + } + } + return text; + } + + private CharSequence updateCollapsedText() { + int trimEndIndex = text.length(); + switch (trimMode) { + case TRIM_MODE_LINES: + trimEndIndex = lineEndIndex - (ELLIPSIZE.length() + trimCollapsedText.length() + 1); + if (trimEndIndex < 0) { + trimEndIndex = trimLength + 1; + } + break; + case TRIM_MODE_LENGTH: + trimEndIndex = trimLength + 1; + break; + } + SpannableStringBuilder s = new SpannableStringBuilder(text, 0, trimEndIndex) + .append(ELLIPSIZE) + .append(trimCollapsedText); + return addClickableSpan(s, trimCollapsedText); + } + + private CharSequence updateExpandedText() { + if (showTrimExpandedText) { + SpannableStringBuilder s = new SpannableStringBuilder(text, 0, text.length()).append(trimExpandedText); + return addClickableSpan(s, trimExpandedText); + } + return text; + } + + private CharSequence addClickableSpan(SpannableStringBuilder s, CharSequence trimText) { + s.setSpan(viewMoreSpan, s.length() - trimText.length(), s.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + return s; + } + + public void setTrimLength(int trimLength) { + this.trimLength = trimLength; + setText(); + } + + public void setColorClickableText(int colorClickableText) { + this.colorClickableText = colorClickableText; + } + + public void setTrimCollapsedText(CharSequence trimCollapsedText) { + this.trimCollapsedText = trimCollapsedText; + } + + public void setTrimExpandedText(CharSequence trimExpandedText) { + this.trimExpandedText = trimExpandedText; + } + + public void setTrimMode(int trimMode) { + this.trimMode = trimMode; + } + + public void setTrimLines(int trimLines) { + this.trimLines = trimLines; + } + + public void setReadMore(boolean readMore) { + this.readMore = readMore; + } + + public void setReadMoreListener(ReadMoreListener readMoreListener) { + this.readMoreListener = readMoreListener; + } + + private class ReadMoreClickableSpan extends ClickableSpan { + @Override + public void onClick(View widget) { + readMore = !readMore; + setText(); + + if(readMoreListener != null){ + readMoreListener.onReadMoreClick(readMore); + } + } + + @Override + public void updateDrawState(TextPaint ds) { + ds.setColor(colorClickableText); + } + } + + private void onGlobalLayoutLineEndIndex() { + if (trimMode == TRIM_MODE_LINES) { + getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + ViewTreeObserver obs = getViewTreeObserver(); + obs.removeOnGlobalLayoutListener(this); + refreshLineEndIndex(); + setText(); + } + }); + } + } + + private void refreshLineEndIndex() { + try { + if (trimLines == 0) { + lineEndIndex = getLayout().getLineEnd(0); + } else if (trimLines > 0 && getLineCount() >= trimLines) { + lineEndIndex = getLayout().getLineEnd(trimLines - 1); + } else { + lineEndIndex = INVALID_END_INDEX; + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/monocleschat/res/values/attrs.xml b/src/monocleschat/res/values/attrs.xml index c35af8a3b..5d3c8d075 100644 --- a/src/monocleschat/res/values/attrs.xml +++ b/src/monocleschat/res/values/attrs.xml @@ -10,4 +10,18 @@ + + + + + + + + + + + + + +