diff --git a/res/layout/conversation_item_received.xml b/res/layout/conversation_item_received.xml
index fa357bf2c..5169b4eb0 100644
--- a/res/layout/conversation_item_received.xml
+++ b/res/layout/conversation_item_received.xml
@@ -75,7 +75,8 @@
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?conversation_item_received_text_primary_color"
android:textColorLink="?conversation_item_received_text_primary_color"
- android:textSize="@dimen/conversation_item_body_text_size" />
+ android:textSize="@dimen/conversation_item_body_text_size"
+ app:scaleEmojis="true" />
+ app:scaleEmojis="true"
+ tools:text="Mango pickle lorem ipsum"/>
+
+
+
+
diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
index a3e194e55..b6f7d3d4f 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
@@ -26,7 +26,6 @@ import org.thoughtcrime.securesms.components.emoji.parsing.EmojiTree;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.Util;
-import java.util.List;
import java.util.concurrent.ExecutionException;
class EmojiProvider {
@@ -71,10 +70,19 @@ class EmojiProvider {
}
}
- @Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
+ @Nullable EmojiParser.CandidateList getCandidates(@Nullable CharSequence text) {
if (text == null) return null;
+ return new EmojiParser(emojiTree).findCandidates(text);
+ }
- List matches = new EmojiParser(emojiTree).findCandidates(text);
+ @Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
+ return emojify(getCandidates(text), text, tv);
+ }
+
+ @Nullable Spannable emojify(@Nullable EmojiParser.CandidateList matches,
+ @Nullable CharSequence text,
+ @NonNull TextView tv) {
+ if (matches == null || text == null) return null;
SpannableStringBuilder builder = new SpannableStringBuilder(text);
for (EmojiParser.Candidate candidate : matches) {
diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
index 31c297220..0cfb1bf53 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.components.emoji;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
@@ -9,12 +10,18 @@ import android.support.v7.widget.AppCompatTextView;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
+import android.util.TypedValue;
+import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider.EmojiDrawable;
+import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.ViewUtil;
public class EmojiTextView extends AppCompatTextView {
+ private final boolean scaleEmojis;
+ private final float originalFontSize;
+
private CharSequence source;
private boolean needsEllipsizing;
@@ -28,15 +35,38 @@ public class EmojiTextView extends AppCompatTextView {
public EmojiTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
+
+ TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EmojiTextView, 0, 0);
+ scaleEmojis = a.getBoolean(R.styleable.EmojiTextView_scaleEmojis, false);
+ a.recycle();
+
+ a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.textSize});
+ originalFontSize = a.getDimensionPixelSize(0, 0);
+ a.recycle();
}
@Override public void setText(@Nullable CharSequence text, BufferType type) {
+ EmojiProvider provider = EmojiProvider.getInstance(getContext());
+ EmojiParser.CandidateList candidates = provider.getCandidates(text);
+
+ if (scaleEmojis && candidates != null && candidates.allEmojis) {
+ int emojis = candidates.size();
+ float scale = 1.0f;
+ if (emojis <= 8) scale += 0.25f;
+ if (emojis <= 6) scale += 0.25f;
+ if (emojis <= 4) scale += 0.25f;
+ if (emojis <= 2) scale += 0.25f;
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, getTextSize() * scale);
+ } else if (scaleEmojis) {
+ setTextSize(TypedValue.COMPLEX_UNIT_PX, originalFontSize);
+ }
+
if (useSystemEmoji()) {
super.setText(text, type);
return;
}
- source = EmojiProvider.getInstance(getContext()).emojify(text, this);
+ source = EmojiProvider.getInstance(getContext()).emojify(candidates, text, this);
setTextEllipsized(source);
}
diff --git a/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiParser.java b/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiParser.java
index 95a92b0b2..0fec9806e 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiParser.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiParser.java
@@ -24,6 +24,7 @@ package org.thoughtcrime.securesms.components.emoji.parsing;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
@@ -38,10 +39,12 @@ public class EmojiParser {
this.emojiTree = emojiTree;
}
- public @NonNull List findCandidates(@Nullable CharSequence text) {
+ public @NonNull CandidateList findCandidates(@Nullable CharSequence text) {
List results = new LinkedList<>();
- if (text == null) return results;
+ if (text == null) return new CandidateList(results, false);
+
+ boolean allEmojis = text.length() > 0;
for (int i = 0; i < text.length(); i++) {
int emojiEnd = getEmojiEndPos(text, i);
@@ -58,10 +61,12 @@ public class EmojiParser {
results.add(new Candidate(i, emojiEnd, drawInfo));
i = emojiEnd - 1;
+ } else {
+ allEmojis = false;
}
}
- return results;
+ return new CandidateList(results, allEmojis);
}
private int getEmojiEndPos(CharSequence text, int startPos) {
@@ -105,4 +110,23 @@ public class EmojiParser {
}
}
+ public class CandidateList implements Iterable {
+ public final List list;
+ public final boolean allEmojis;
+
+ public CandidateList(List candidates, boolean allEmojis) {
+ this.list = candidates;
+ this.allEmojis = allEmojis;
+ }
+
+ public int size() {
+ return list.size();
+ }
+
+ @Override
+ public Iterator iterator() {
+ return list.iterator();
+ }
+ }
+
}