diff --git a/res/layout/map_bubble_layout.xml b/res/layout/map_bubble_layout.xml
index bd3c6fc4f..8b4b5a00d 100644
--- a/res/layout/map_bubble_layout.xml
+++ b/res/layout/map_bubble_layout.xml
@@ -48,6 +48,7 @@
android:paddingTop="@dimen/message_bubble_top_padding"
android:textColor="?conversation_item_outgoing_text_primary_color"
android:textColorLink="?conversation_item_outgoing_text_primary_color"
+ app:createInBackground="true"
app:scaleEmojis="true"
tools:text="Mango pickle lorem ipsum"/>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 396cd0225..2c6da346b 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -201,6 +201,7 @@
+
diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
index 79f1ed9a7..9796c5acd 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiProvider.java
@@ -11,6 +11,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
+import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.Spannable;
@@ -27,12 +28,13 @@ import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.Pair;
+import java.io.IOException;
import java.util.concurrent.ExecutionException;
class EmojiProvider {
private static final String TAG = EmojiProvider.class.getSimpleName();
- private static volatile EmojiProvider instance = null;
+ protected static volatile EmojiProvider instance = null;
private static final Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
private final EmojiTree emojiTree = new EmojiTree();
@@ -56,7 +58,7 @@ class EmojiProvider {
return instance;
}
- private EmojiProvider(Context context) {
+ protected EmojiProvider(Context context) {
this.decodeScale = Math.min(1f, context.getResources().getDimension(R.dimen.emoji_drawer_size) / EMOJI_RAW_HEIGHT);
this.verticalPad = EMOJI_VERT_PAD * this.decodeScale;
@@ -81,17 +83,18 @@ class EmojiProvider {
}
@Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
- return emojify(getCandidates(text), text, tv);
+ return emojify(getCandidates(text), text, tv, false);
}
@Nullable Spannable emojify(@Nullable EmojiParser.CandidateList matches,
@Nullable CharSequence text,
- @NonNull TextView tv) {
+ @NonNull TextView tv,
+ boolean background) {
if (matches == null || text == null) return null;
SpannableStringBuilder builder = new SpannableStringBuilder(text);
for (EmojiParser.Candidate candidate : matches) {
- Drawable drawable = getEmojiDrawable(candidate.getDrawInfo());
+ Drawable drawable = getEmojiDrawable(candidate.getDrawInfo(), background);
if (drawable != null) {
builder.setSpan(new EmojiSpan(drawable, tv), candidate.getStartIndex(), candidate.getEndIndex(),
@@ -104,24 +107,32 @@ class EmojiProvider {
@Nullable Drawable getEmojiDrawable(CharSequence emoji) {
EmojiDrawInfo drawInfo = emojiTree.getEmoji(emoji, 0, emoji.length());
- return getEmojiDrawable(drawInfo);
+ return getEmojiDrawable(drawInfo, false);
}
- private @Nullable Drawable getEmojiDrawable(@Nullable EmojiDrawInfo drawInfo) {
+ protected @Nullable Drawable getEmojiDrawable(@Nullable EmojiDrawInfo drawInfo, boolean background) {
if (drawInfo == null) {
return null;
}
final EmojiDrawable drawable = new EmojiDrawable(drawInfo, decodeScale);
- drawInfo.getPage().get().addListener(new FutureTaskListener() {
- @Override public void onSuccess(final Bitmap result) {
- Util.runOnMain(() -> drawable.setBitmap(result));
+ if (background) {
+ try {
+ drawable.setBitmap(drawInfo.getPage().loadPage(), background);
+ } catch (IOException e) {
+ e.printStackTrace();
}
+ } else {
+ drawInfo.getPage().get().addListener(new FutureTaskListener() {
+ @Override public void onSuccess(final Bitmap result) {
+ Util.runOnMain(() -> drawable.setBitmap(result));
+ }
- @Override public void onFailure(ExecutionException error) {
- Log.w(TAG, error);
- }
- });
+ @Override public void onFailure(ExecutionException error) {
+ Log.w(TAG, error);
+ }
+ });
+ }
return drawable;
}
@@ -167,7 +178,14 @@ class EmojiProvider {
@TargetApi(VERSION_CODES.HONEYCOMB_MR1)
public void setBitmap(Bitmap bitmap) {
- Util.assertMainThread();
+ setBitmap(bitmap, false);
+ }
+
+ @TargetApi(VERSION_CODES.HONEYCOMB_MR1)
+ public void setBitmap(Bitmap bitmap, boolean background) {
+ if (!background) {
+ Util.assertMainThread();
+ }
if (VERSION.SDK_INT < VERSION_CODES.HONEYCOMB_MR1 || bmp == null || !bmp.sameAs(bitmap)) {
bmp = bitmap;
invalidateSelf();
diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
index 1cc92bd1d..2edb1e661 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiTextView.java
@@ -22,6 +22,7 @@ import org.thoughtcrime.securesms.util.Util;
public class EmojiTextView extends AppCompatTextView {
private final boolean scaleEmojis;
+ private final boolean createInBackground;
private CharSequence previousText;
private BufferType previousBufferType;
@@ -42,6 +43,7 @@ public class EmojiTextView extends AppCompatTextView {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.EmojiTextView, 0, 0);
scaleEmojis = a.getBoolean(R.styleable.EmojiTextView_scaleEmojis, false);
+ createInBackground = a.getBoolean(R.styleable.EmojiTextView_createInBackground, false);
a.recycle();
a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.textSize});
@@ -80,7 +82,7 @@ public class EmojiTextView extends AppCompatTextView {
return;
}
- CharSequence emojified = provider.emojify(candidates, text, this);
+ CharSequence emojified = provider.emojify(candidates, text, this, createInBackground);
super.setText(emojified, BufferType.SPANNABLE);
// Android fails to ellipsize spannable strings. (https://issuetracker.google.com/issues/36991688)
@@ -113,7 +115,7 @@ public class EmojiTextView extends AppCompatTextView {
.append(ellipsized.subSequence(0, ellipsized.length()));
EmojiParser.CandidateList newCandidates = EmojiProvider.getInstance(getContext()).getCandidates(newContent);
- CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this);
+ CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this, createInBackground);
super.setText(emojified, BufferType.SPANNABLE);
}
diff --git a/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiPageBitmap.java b/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiPageBitmap.java
index 36fe848fb..9f089dce5 100644
--- a/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiPageBitmap.java
+++ b/src/org/thoughtcrime/securesms/components/emoji/parsing/EmojiPageBitmap.java
@@ -67,7 +67,7 @@ public class EmojiPageBitmap {
return task;
}
- private Bitmap loadPage() throws IOException {
+ public Bitmap loadPage() throws IOException {
if (bitmapReference != null && bitmapReference.get() != null) return bitmapReference.get();
try {
diff --git a/src/org/thoughtcrime/securesms/map/GenerateInfoWindowTask.java b/src/org/thoughtcrime/securesms/map/GenerateInfoWindowTask.java
index 6d584690b..0316d0822 100644
--- a/src/org/thoughtcrime/securesms/map/GenerateInfoWindowTask.java
+++ b/src/org/thoughtcrime/securesms/map/GenerateInfoWindowTask.java
@@ -21,6 +21,7 @@ import com.mapbox.geojson.Feature;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.ConversationItemFooter;
+import org.thoughtcrime.securesms.components.emoji.EmojiTextView;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.DateUtils;
@@ -77,7 +78,7 @@ public class GenerateInfoWindowTask extends AsyncTask, HashMa
LinearLayout bubbleLayout = (LinearLayout)
inflater.inflate(R.layout.map_bubble_layout, null);
bubbleLayout.setBackgroundResource(R.drawable.message_bubble_background_received_alone);
- TextView conversationItemBody = bubbleLayout.findViewById(R.id.conversation_item_body);
+ EmojiTextView conversationItemBody = bubbleLayout.findViewById(R.id.conversation_item_body);
Locale locale = DynamicLanguage.getSelectedLocale(callbackRef.get().getContext());
int messageId = (int) feature.getNumberProperty(MESSAGE_ID);
int contactId = (int) feature.getNumberProperty(CONTACT_ID);