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 7ba625636..8b77e8ba3 100644 --- a/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java +++ b/src/main/java/eu/siacs/conversations/ui/adapter/MessageAdapter.java @@ -203,7 +203,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie return 4; } - public int getItemViewType(Message message) { + private int getItemViewType(Message message) { if (message.getType() == Message.TYPE_STATUS) { if (DATE_SEPARATOR_BODY.equals(message.getBody())) { return DATE_SEPARATOR; @@ -222,7 +222,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie return this.getItemViewType(getItem(position)); } - public int getMessageTextColor(boolean onDark, boolean primary) { + private int getMessageTextColor(boolean onDark, boolean primary) { if (onDark) { return ContextCompat.getColor(activity, primary ? R.color.white : R.color.white70); } else { @@ -390,7 +390,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie viewHolder.messageBody.setText(EmojiWrapper.transform(span)); } - private int applyQuoteSpan(SpannableStringBuilder body, int start, int end, boolean darkBackground) { + private void applyQuoteSpan(SpannableStringBuilder body, int start, int end, boolean darkBackground) { if (start > 1 && !"\n\n".equals(body.subSequence(start - 2, start).toString())) { body.insert(start++, "\n"); body.setSpan(new DividerSpan(false), start - 2, start, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -404,7 +404,6 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie : ContextCompat.getColor(activity, R.color.green700_desaturated); DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); body.setSpan(new QuoteSpan(color, metrics), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - return 0; } /** @@ -536,7 +535,7 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } } - Matcher matcher = Emoticons.generatePattern(body).matcher(body); + Matcher matcher = Emoticons.getEmojiPattern(body).matcher(body); while (matcher.find()) { if (matcher.start() < matcher.end()) { body.setSpan(new RelativeSizeSpan(1.2f), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); diff --git a/src/main/java/eu/siacs/conversations/utils/Emoticons.java b/src/main/java/eu/siacs/conversations/utils/Emoticons.java index dc0433fa7..6abcf9b02 100644 --- a/src/main/java/eu/siacs/conversations/utils/Emoticons.java +++ b/src/main/java/eu/siacs/conversations/utils/Emoticons.java @@ -29,8 +29,12 @@ package eu.siacs.conversations.utils; +import android.util.LruCache; + import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.regex.Pattern; @@ -71,12 +75,16 @@ public class Emoticons { ENCLOSED_IDEOGRAPHIC_SUPPLEMENT, MISC_TECHNICAL); + private static final int MAX_EMOIJS = 42; + private static final int ZWJ = 0x200D; private static final int VARIATION_16 = 0xFE0F; private static final int COMBINING_ENCLOSING_KEYCAP = 0x20E3; private static final int BLACK_FLAG = 0x1F3F4; private static final UnicodeRange FITZPATRICK = new UnicodeRange(0x1F3FB,0x1F3FF); + private static final LruCache CACHE = new LruCache<>(256); + private static List parse(String input) { List symbols = new ArrayList<>(); Builder builder = new Builder(); @@ -99,16 +107,33 @@ public class Emoticons { return symbols; } - public static Pattern generatePattern(CharSequence input) { - final StringBuilder pattern = new StringBuilder(); + public static Pattern getEmojiPattern(CharSequence input) { + Pattern pattern = CACHE.get(input); + if (pattern == null) { + pattern = generatePattern(input); + CACHE.put(input, pattern); + } + return pattern; + } + + private static Pattern generatePattern(CharSequence input) { + final HashSet emojis = new HashSet<>(); + int i = 0; for(Symbol symbol : parse(input.toString())) { if (symbol instanceof Emoji) { - if (pattern.length() != 0) { - pattern.append('|'); + emojis.add(symbol.toString()); + if (++i >= MAX_EMOIJS) { + return Pattern.compile(""); } - pattern.append(Pattern.quote(symbol.toString())); } } + final StringBuilder pattern = new StringBuilder(); + for(String emoji : emojis) { + if (pattern.length() != 0) { + pattern.append('|'); + } + pattern.append(Pattern.quote(emoji)); + } return Pattern.compile(pattern.toString()); }