fix: other view types have clickable links, clickable links in the long message. Ordering of highlight mentions before getting clickable spans

fixes #664
This commit is contained in:
Harris 2021-08-12 15:36:08 +10:00
parent 18c177971a
commit 7e791d63dc
5 changed files with 39 additions and 25 deletions

View File

@ -21,13 +21,14 @@ import org.session.libsession.utilities.ViewUtil
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.MediaPreviewActivity import org.thoughtcrime.securesms.MediaPreviewActivity
import org.thoughtcrime.securesms.components.CornerMask import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentView
import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.util.ActivityDispatcher
import org.thoughtcrime.securesms.longmessage.LongMessageActivity import org.thoughtcrime.securesms.longmessage.LongMessageActivity
import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.mms.Slide import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.video.exo.AttachmentDataSource import org.thoughtcrime.securesms.util.ActivityDispatcher
import kotlin.math.roundToInt import kotlin.math.roundToInt
class AlbumThumbnailView : FrameLayout { class AlbumThumbnailView : FrameLayout {
@ -80,6 +81,13 @@ class AlbumThumbnailView : FrameLayout {
} }
return return
} }
val intersectedSpans = albumCellBodyText.getIntersectedModalSpans(eventRect)
if (intersectedSpans.isNotEmpty()) {
intersectedSpans.forEach { span ->
span.onClick(albumCellBodyText)
}
return
}
// test each album child // test each album child
albumCellContainer.findViewById<ViewGroup>(R.id.album_thumbnail_root)?.children?.forEachIndexed { index, child -> albumCellContainer.findViewById<ViewGroup>(R.id.album_thumbnail_root)?.children?.forEachIndexed { index, child ->
child.getGlobalVisibleRect(testRect) child.getGlobalVisibleRect(testRect)
@ -130,7 +138,8 @@ class AlbumThumbnailView : FrameLayout {
thumbnailView.setImageResource(glideRequests, slide, isPreview = false, mms = message) thumbnailView.setImageResource(glideRequests, slide, isPreview = false, mms = message)
} }
albumCellBodyParent.isVisible = message.body.isNotEmpty() albumCellBodyParent.isVisible = message.body.isNotEmpty()
albumCellBodyText.text = message.body val body = VisibleMessageContentView.getBodySpans(context, message, null)
albumCellBodyText.text = body
post { post {
// post to await layout of text // post to await layout of text
albumCellBodyText.layout?.let { layout -> albumCellBodyText.layout?.let { layout ->

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.style.BackgroundColorSpan import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.text.style.URLSpan import android.text.style.URLSpan
@ -28,21 +29,21 @@ import okhttp3.HttpUrl
import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.ThemeUtil
import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.ViewUtil
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView
import org.thoughtcrime.securesms.components.emoji.EmojiTextView import org.thoughtcrime.securesms.components.emoji.EmojiTextView
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.conversation.v2.components.AlbumThumbnailView
import org.thoughtcrime.securesms.conversation.v2.dialogs.OpenURLDialog import org.thoughtcrime.securesms.conversation.v2.dialogs.OpenURLDialog
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities
import org.thoughtcrime.securesms.conversation.v2.utilities.ModalURLSpan import org.thoughtcrime.securesms.conversation.v2.utilities.ModalURLSpan
import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans import org.thoughtcrime.securesms.conversation.v2.utilities.TextUtilities.getIntersectedModalSpans
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.util.*
import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.util.SearchUtil import org.thoughtcrime.securesms.util.SearchUtil
import org.thoughtcrime.securesms.util.SearchUtil.StyleFactory import org.thoughtcrime.securesms.util.SearchUtil.StyleFactory
import org.thoughtcrime.securesms.util.UiModeUtilities import org.thoughtcrime.securesms.util.UiModeUtilities
import java.net.IDN import org.thoughtcrime.securesms.util.getColorWithID
import org.thoughtcrime.securesms.util.toPx
import java.util.* import java.util.*
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -106,6 +107,10 @@ class VisibleMessageContentView : LinearLayout {
quoteView.getGlobalVisibleRect(r) quoteView.getGlobalVisibleRect(r)
if (r.contains(event.rawX.roundToInt(), event.rawY.roundToInt())) { if (r.contains(event.rawX.roundToInt(), event.rawY.roundToInt())) {
delegate?.scrollToMessageIfPossible(quote.id) delegate?.scrollToMessageIfPossible(quote.id)
} else {
bodyTextView.getIntersectedModalSpans(event).forEach { span ->
span.onClick(bodyTextView)
}
} }
} }
} else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) {
@ -209,7 +214,18 @@ class VisibleMessageContentView : LinearLayout {
val color = getTextColor(context, message) val color = getTextColor(context, message)
result.setTextColor(color) result.setTextColor(color)
result.setLinkTextColor(color) result.setLinkTextColor(color)
val body = getBodySpans(context, message, searchQuery)
result.text = body
return result
}
fun getBodySpans(context: Context, message: MessageRecord, searchQuery: String?): Spannable {
var body = message.body.toSpannable() var body = message.body.toSpannable()
body = MentionUtilities.highlightMentions(body, message.isOutgoing, message.threadId, context)
body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { BackgroundColorSpan(Color.WHITE) }, body, searchQuery)
body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { ForegroundColorSpan(Color.BLACK) }, body, searchQuery)
Linkify.addLinks(body, Linkify.WEB_URLS) Linkify.addLinks(body, Linkify.WEB_URLS)
// replace URLSpans with ModalURLSpans // replace URLSpans with ModalURLSpans
@ -225,13 +241,7 @@ class VisibleMessageContentView : LinearLayout {
body.removeSpan(urlSpan) body.removeSpan(urlSpan)
body.setSpan(replacementSpan, start, end, flags) body.setSpan(replacementSpan, start, end, flags)
} }
return body
body = MentionUtilities.highlightMentions(body, message.isOutgoing, message.threadId, context)
body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { BackgroundColorSpan(Color.WHITE) }, body, searchQuery)
body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { ForegroundColorSpan(Color.BLACK) }, body, searchQuery)
result.text = body
return result
} }
@ColorInt @ColorInt

View File

@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.longmessage;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.text.Spannable;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.TextView; import android.widget.TextView;
@ -15,7 +16,7 @@ import org.session.libsession.utilities.Address;
import org.session.libsession.utilities.Util; import org.session.libsession.utilities.Util;
import org.session.libsession.utilities.recipients.Recipient; import org.session.libsession.utilities.recipients.Recipient;
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity; import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities; import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageContentView;
import network.loki.messenger.R; import network.loki.messenger.R;
@ -81,18 +82,10 @@ public class LongMessageActivity extends PassphraseRequiredActionBarActivity {
String name = Util.getFirstNonEmpty(recipient.getName(), recipient.getProfileName(), recipient.getAddress().serialize()); String name = Util.getFirstNonEmpty(recipient.getName(), recipient.getProfileName(), recipient.getAddress().serialize());
getSupportActionBar().setTitle(getString(R.string.LongMessageActivity_message_from_s, name)); getSupportActionBar().setTitle(getString(R.string.LongMessageActivity_message_from_s, name));
} }
Spannable bodySpans = VisibleMessageContentView.Companion.getBodySpans(this, message.get().getMessageRecord(), null);
String trimmedBody = getTrimmedBody(message.get().getFullBody()); textBody.setText(bodySpans);
String mentionBody = MentionUtilities.highlightMentions(trimmedBody, message.get().getMessageRecord().getThreadId(), this);
textBody.setText(mentionBody);
textBody.setMovementMethod(LinkMovementMethod.getInstance()); textBody.setMovementMethod(LinkMovementMethod.getInstance());
}); });
} }
private String getTrimmedBody(@NonNull String text) {
return text.length() <= MAX_DISPLAY_LENGTH ? text
: text.substring(0, MAX_DISPLAY_LENGTH);
}
} }

View File

@ -52,7 +52,7 @@
android:layout_width="@dimen/accent_line_thickness" android:layout_width="@dimen/accent_line_thickness"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/accent"/> android:background="@color/accent"/>
<TextView <org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:maxLines="4" android:maxLines="4"
android:ellipsize="end" android:ellipsize="end"
android:id="@+id/albumCellBodyText" android:id="@+id/albumCellBodyText"

View File

@ -12,6 +12,8 @@
<TextView <TextView
android:textSize="@dimen/text_size" android:textSize="@dimen/text_size"
android:focusable="true"
android:textColorLink="@color/text"
android:id="@+id/longmessage_text" android:id="@+id/longmessage_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>