From 4707efb26ae48be2087c0a175efde33bc6b1fb11 Mon Sep 17 00:00:00 2001 From: cyBerta Date: Sat, 30 Mar 2019 19:53:29 +0100 Subject: [PATCH] fix #793 partially: allow to create EmojiTextViews in background if statically declared in xml --- res/layout/map_bubble_layout.xml | 1 + res/values/attrs.xml | 1 + .../components/emoji/EmojiProvider.java | 48 +++++++++++++------ .../components/emoji/EmojiTextView.java | 6 ++- .../emoji/parsing/EmojiPageBitmap.java | 2 +- .../securesms/map/GenerateInfoWindowTask.java | 3 +- 6 files changed, 42 insertions(+), 19 deletions(-) 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);