diff --git a/src/org/thoughtcrime/securesms/ConversationListItem.java b/src/org/thoughtcrime/securesms/ConversationListItem.java index b03b6a3f7b..1415f9ac51 100644 --- a/src/org/thoughtcrime/securesms/ConversationListItem.java +++ b/src/org/thoughtcrime/securesms/ConversationListItem.java @@ -37,6 +37,8 @@ import org.thoughtcrime.securesms.components.FromTextView; import org.thoughtcrime.securesms.components.ThumbnailView; import org.thoughtcrime.securesms.components.TypingIndicatorView; import org.thoughtcrime.securesms.database.model.ThreadRecord; +import org.thoughtcrime.securesms.loki.LokiAPIUtilities; +import org.thoughtcrime.securesms.loki.MentionUtilities; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientModifiedListener; @@ -270,8 +272,9 @@ public class ConversationListItem extends RelativeLayout } private @NonNull CharSequence getTrimmedSnippet(@NonNull CharSequence snippet) { - return snippet.length() <= MAX_SNIPPET_LENGTH ? snippet - : snippet.subSequence(0, MAX_SNIPPET_LENGTH); + LokiAPIUtilities.INSTANCE.populateUserIDCacheIfNeeded(threadId, getContext()); // TODO: Terrible place to do this, but okay for now + snippet = MentionUtilities.highlightMentions(snippet, this.recipient.isGroupRecipient(), getContext()); + return snippet.length() <= MAX_SNIPPET_LENGTH ? snippet : snippet.subSequence(0, MAX_SNIPPET_LENGTH); } private void setThumbnailSnippet(ThreadRecord thread) { diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java index e315e8ba5b..1d239c6adf 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -42,7 +42,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.URLSpan; import android.text.util.Linkify; import android.util.AttributeSet; -import android.util.Range; import android.util.TypedValue; import android.view.View; import android.view.ViewGroup; @@ -91,6 +90,7 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.FriendRequestView; import org.thoughtcrime.securesms.loki.FriendRequestViewDelegate; import org.thoughtcrime.securesms.loki.LokiMessageDatabase; +import org.thoughtcrime.securesms.loki.MentionUtilities; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.PartAuthority; @@ -115,14 +115,11 @@ import org.thoughtcrime.securesms.util.views.Stub; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import network.loki.messenger.R; @@ -476,7 +473,7 @@ public class ConversationItem extends LinearLayout if (isCaptionlessMms(messageRecord)) { bodyText.setVisibility(View.GONE); } else { ; - Spannable text = highlightMentions(linkifyMessageBody(messageRecord.getDisplayBody(context), batchSelected.isEmpty()), isGroupThread); + Spannable text = MentionUtilities.highlightMentions(linkifyMessageBody(messageRecord.getDisplayBody(context), batchSelected.isEmpty()), messageRecord.isOutgoing(), isGroupThread, context); text = SearchUtil.getHighlightedSpan(locale, () -> new BackgroundColorSpan(Color.YELLOW), text, searchQuery); text = SearchUtil.getHighlightedSpan(locale, () -> new ForegroundColorSpan(Color.BLACK), text, searchQuery); @@ -776,41 +773,6 @@ public class ConversationItem extends LinearLayout return messageBody; } - private SpannableString highlightMentions(CharSequence text, boolean isGroupThread) { - Pattern pattern = Pattern.compile("@[0-9a-fA-F]*"); - Matcher matcher = pattern.matcher(text); - ArrayList> mentions = new ArrayList<>(); - int startIndex = 0; - if (matcher.find(startIndex) && isGroupThread) { - while (true) { - String userID = text.subSequence(matcher.start() + 1, matcher.end()).toString(); // +1 to get rid of the @ - String userDisplayName; - if (userID.toLowerCase().equals(TextSecurePreferences.getLocalNumber(context).toLowerCase())) { - userDisplayName = TextSecurePreferences.getProfileName(context); - } else { - String publicChatID = LokiGroupChatAPI.getPublicChatServer() + "." + LokiGroupChatAPI.getPublicChatServerID(); - userDisplayName = DatabaseFactory.getLokiUserDatabase(context).getServerDisplayName(publicChatID, userID.toString()); - } - if (userDisplayName != null) { - text = text.subSequence(0, matcher.start()) + "@" + userDisplayName + text.subSequence(matcher.end(), text.length()); - int endIndex = matcher.start() + 1 + userDisplayName.length(); - startIndex = endIndex; - mentions.add(Range.create(matcher.start(), endIndex)); - } else { - startIndex = matcher.end(); - } - matcher = pattern.matcher(text); - if (!matcher.find(startIndex)) { break; } - } - } - SpannableString result = new SpannableString(text); - for (Range range : mentions) { - int highlightColor = (messageRecord.isOutgoing()) ? getResources().getColor(R.color.loki_dark_green) : getResources().getColor(R.color.loki_green); - result.setSpan(new BackgroundColorSpan(highlightColor), range.getLower(), range.getUpper(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - } - return result; - } - private void setStatusIcons(MessageRecord messageRecord) { bodyText.setCompoundDrawablesWithIntrinsicBounds(0, 0, messageRecord.isKeyExchange() ? R.drawable.ic_menu_login : 0, 0); @@ -827,7 +789,7 @@ public class ConversationItem extends LinearLayout if (current.isMms() && !current.isMmsNotification() && ((MediaMmsMessageRecord)current).getQuote() != null) { Quote quote = ((MediaMmsMessageRecord)current).getQuote(); //noinspection ConstantConditions - String quoteBody = highlightMentions(quote.getText(), isGroupThread).toString(); + String quoteBody = MentionUtilities.highlightMentions(quote.getText(), isGroupThread, context); quoteView.setQuote(glideRequests, quote.getId(), Recipient.from(context, quote.getAuthor(), true), quoteBody, quote.isOriginalMissing(), quote.getAttachment(), conversationRecipient); quoteView.setVisibility(View.VISIBLE); quoteView.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; diff --git a/src/org/thoughtcrime/securesms/loki/MentionUtilities.kt b/src/org/thoughtcrime/securesms/loki/MentionUtilities.kt new file mode 100644 index 0000000000..d9f0643cad --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/MentionUtilities.kt @@ -0,0 +1,56 @@ +package org.thoughtcrime.securesms.loki + +import android.content.Context +import android.text.Spannable +import android.text.SpannableString +import android.text.style.BackgroundColorSpan +import android.util.Range +import network.loki.messenger.R +import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.whispersystems.signalservice.loki.api.LokiGroupChatAPI +import java.util.regex.Pattern + +object MentionUtilities { + + @JvmStatic + fun highlightMentions(text: CharSequence, isGroupThread: Boolean, context: Context): String { + return MentionUtilities.highlightMentions(text, false, isGroupThread, context).toString() // isOutgoingMessage is irrelevant + } + + @JvmStatic + fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, isGroupThread: Boolean, context: Context): SpannableString { + var text = text + val pattern = Pattern.compile("@[0-9a-fA-F]*") + var matcher = pattern.matcher(text) + val mentions = mutableListOf>() + var startIndex = 0 + if (matcher.find(startIndex) && isGroupThread) { + while (true) { + val userID = text.subSequence(matcher.start() + 1, matcher.end()).toString() // +1 to get rid of the @ + val userDisplayName: String? = if (userID.toLowerCase() == TextSecurePreferences.getLocalNumber(context).toLowerCase()) { + TextSecurePreferences.getProfileName(context) + } else { + val publicChatID = LokiGroupChatAPI.publicChatServer + "." + LokiGroupChatAPI.publicChatServerID + DatabaseFactory.getLokiUserDatabase(context).getServerDisplayName(publicChatID, userID) + } + if (userDisplayName != null) { + text = text.subSequence(0, matcher.start()).toString() + "@" + userDisplayName + text.subSequence(matcher.end(), text.length) + val endIndex = matcher.start() + 1 + userDisplayName.length + startIndex = endIndex + mentions.add(Range.create(matcher.start(), endIndex)) + } else { + startIndex = matcher.end() + } + matcher = pattern.matcher(text) + if (!matcher.find(startIndex)) { break } + } + } + val result = SpannableString(text) + for (range in mentions) { + val highlightColor = if (isOutgoingMessage) context.resources.getColor(R.color.loki_dark_green) else context.resources.getColor(R.color.loki_green) + result.setSpan(BackgroundColorSpan(highlightColor), range.lower, range.upper, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + } + return result + } +} \ No newline at end of file