Fix layout designer deadlock.
This commit is contained in:
parent
dd934e0095
commit
d672857e82
11 changed files with 44 additions and 62 deletions
|
@ -19,7 +19,7 @@ public class EmojiFilter implements InputFilter {
|
|||
char[] v = new char[end - start];
|
||||
TextUtils.getChars(source, start, end, v, 0);
|
||||
|
||||
Spannable emojified = EmojiProvider.getInstance(view.getContext()).emojify(new String(v), view);
|
||||
Spannable emojified = EmojiProvider.emojify(new String(v), view);
|
||||
|
||||
if (source instanceof Spanned && emojified != null) {
|
||||
TextUtils.copySpansFrom((Spanned) source, start, end, null, emojified, 0);
|
||||
|
|
|
@ -5,6 +5,8 @@ import android.util.AttributeSet;
|
|||
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class EmojiImageView extends AppCompatImageView {
|
||||
public EmojiImageView(Context context) {
|
||||
super(context);
|
||||
|
@ -15,6 +17,10 @@ public class EmojiImageView extends AppCompatImageView {
|
|||
}
|
||||
|
||||
public void setImageEmoji(CharSequence emoji) {
|
||||
setImageDrawable(EmojiProvider.getInstance(getContext()).getEmojiDrawable(emoji));
|
||||
if (isInEditMode()) {
|
||||
setImageResource(R.drawable.ic_emoji);
|
||||
} else {
|
||||
setImageDrawable(EmojiProvider.getEmojiDrawable(getContext(), emoji));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,7 @@ public class EmojiPageView extends FrameLayout implements VariationSelectorListe
|
|||
layoutManager = new GridLayoutManager(context, 8);
|
||||
scrollDisabler = new ScrollDisabler();
|
||||
popup = new EmojiVariationSelectorPopup(context, emojiSelectionListener);
|
||||
adapter = new EmojiPageViewGridAdapter(EmojiProvider.getInstance(context),
|
||||
popup,
|
||||
adapter = new EmojiPageViewGridAdapter(popup,
|
||||
emojiSelectionListener,
|
||||
this,
|
||||
allowVariations);
|
||||
|
|
|
@ -19,20 +19,17 @@ import java.util.List;
|
|||
public class EmojiPageViewGridAdapter extends RecyclerView.Adapter<EmojiPageViewGridAdapter.EmojiViewHolder> implements PopupWindow.OnDismissListener {
|
||||
|
||||
private final List<Emoji> emojiList;
|
||||
private final EmojiProvider emojiProvider;
|
||||
private final EmojiVariationSelectorPopup popup;
|
||||
private final VariationSelectorListener variationSelectorListener;
|
||||
private final EmojiEventListener emojiEventListener;
|
||||
private final boolean allowVariations;
|
||||
|
||||
public EmojiPageViewGridAdapter(@NonNull EmojiProvider emojiProvider,
|
||||
@NonNull EmojiVariationSelectorPopup popup,
|
||||
public EmojiPageViewGridAdapter(@NonNull EmojiVariationSelectorPopup popup,
|
||||
@NonNull EmojiEventListener emojiEventListener,
|
||||
@NonNull VariationSelectorListener variationSelectorListener,
|
||||
boolean allowVariations)
|
||||
{
|
||||
this.emojiList = new ArrayList<>();
|
||||
this.emojiProvider = emojiProvider;
|
||||
this.popup = popup;
|
||||
this.emojiEventListener = emojiEventListener;
|
||||
this.variationSelectorListener = variationSelectorListener;
|
||||
|
@ -51,7 +48,7 @@ public class EmojiPageViewGridAdapter extends RecyclerView.Adapter<EmojiPageView
|
|||
public void onBindViewHolder(@NonNull EmojiViewHolder viewHolder, int i) {
|
||||
Emoji emoji = emojiList.get(i);
|
||||
|
||||
Drawable drawable = emojiProvider.getEmojiDrawable(emoji.getValue());
|
||||
final Drawable drawable = EmojiProvider.getEmojiDrawable(viewHolder.imageView.getContext(), emoji.getValue());
|
||||
|
||||
if (drawable != null) {
|
||||
viewHolder.textView.setVisibility(View.GONE);
|
||||
|
|
|
@ -28,45 +28,31 @@ import java.util.concurrent.ExecutionException;
|
|||
|
||||
class EmojiProvider {
|
||||
|
||||
private static final String TAG = Log.tag(EmojiProvider.class);
|
||||
private static volatile EmojiProvider instance = null;
|
||||
private static final Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
|
||||
private static final String TAG = Log.tag(EmojiProvider.class);
|
||||
private static final Paint PAINT = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private final Context context;
|
||||
|
||||
public static EmojiProvider getInstance(Context context) {
|
||||
if (instance == null) {
|
||||
synchronized (EmojiProvider.class) {
|
||||
if (instance == null) {
|
||||
instance = new EmojiProvider(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private EmojiProvider(Context context) {
|
||||
this.context = context.getApplicationContext();
|
||||
}
|
||||
|
||||
@Nullable EmojiParser.CandidateList getCandidates(@Nullable CharSequence text) {
|
||||
static @Nullable EmojiParser.CandidateList getCandidates(@Nullable CharSequence text) {
|
||||
if (text == null) return null;
|
||||
return new EmojiParser(EmojiSource.getLatest().getEmojiTree()).findCandidates(text);
|
||||
}
|
||||
|
||||
@Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
|
||||
return emojify(getCandidates(text), text, tv);
|
||||
static @Nullable Spannable emojify(@Nullable CharSequence text, @NonNull TextView tv) {
|
||||
if (tv.isInEditMode()) {
|
||||
return null;
|
||||
} else {
|
||||
return emojify(getCandidates(text), text, tv);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable Spannable emojify(@Nullable EmojiParser.CandidateList matches,
|
||||
@Nullable CharSequence text,
|
||||
@NonNull TextView tv)
|
||||
static @Nullable Spannable emojify(@Nullable EmojiParser.CandidateList matches,
|
||||
@Nullable CharSequence text,
|
||||
@NonNull TextView tv)
|
||||
{
|
||||
if (matches == null || text == null) return null;
|
||||
if (matches == null || text == null || tv.isInEditMode()) return null;
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||
|
||||
for (EmojiParser.Candidate candidate : matches) {
|
||||
Drawable drawable = getEmojiDrawable(candidate.getDrawInfo());
|
||||
Drawable drawable = getEmojiDrawable(tv.getContext(), candidate.getDrawInfo());
|
||||
|
||||
if (drawable != null) {
|
||||
builder.setSpan(new EmojiSpan(drawable, tv), candidate.getStartIndex(), candidate.getEndIndex(),
|
||||
|
@ -77,12 +63,12 @@ class EmojiProvider {
|
|||
return builder;
|
||||
}
|
||||
|
||||
@Nullable Drawable getEmojiDrawable(CharSequence emoji) {
|
||||
static @Nullable Drawable getEmojiDrawable(@NonNull Context context, @Nullable CharSequence emoji) {
|
||||
EmojiDrawInfo drawInfo = EmojiSource.getLatest().getEmojiTree().getEmoji(emoji, 0, emoji.length());
|
||||
return getEmojiDrawable(drawInfo);
|
||||
return getEmojiDrawable(context, drawInfo);
|
||||
}
|
||||
|
||||
private @Nullable Drawable getEmojiDrawable(@Nullable EmojiDrawInfo drawInfo) {
|
||||
private static @Nullable Drawable getEmojiDrawable(@NonNull Context context, @Nullable EmojiDrawInfo drawInfo) {
|
||||
if (drawInfo == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -151,7 +137,7 @@ class EmojiProvider {
|
|||
canvas.drawBitmap(bmp,
|
||||
emojiBounds,
|
||||
getBounds(),
|
||||
paint);
|
||||
PAINT);
|
||||
}
|
||||
|
||||
public void setBitmap(Bitmap bitmap) {
|
||||
|
|
|
@ -91,8 +91,7 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
}
|
||||
|
||||
@Override public void setText(@Nullable CharSequence text, BufferType type) {
|
||||
EmojiProvider provider = EmojiProvider.getInstance(getContext());
|
||||
EmojiParser.CandidateList candidates = !isInEditMode() ? provider.getCandidates(text) : null;
|
||||
EmojiParser.CandidateList candidates = isInEditMode() ? null : EmojiProvider.getCandidates(text);
|
||||
|
||||
if (scaleEmojis && candidates != null && candidates.allEmojis) {
|
||||
int emojis = candidates.size();
|
||||
|
@ -124,7 +123,7 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
ellipsizeAnyTextForMaxLength();
|
||||
}
|
||||
} else {
|
||||
CharSequence emojified = provider.emojify(candidates, text, this);
|
||||
CharSequence emojified = EmojiProvider.emojify(candidates, text, this);
|
||||
super.setText(new SpannableStringBuilder(emojified).append(Optional.fromNullable(overflowText).or("")), BufferType.SPANNABLE);
|
||||
|
||||
// Android fails to ellipsize spannable strings. (https://issuetracker.google.com/issues/36991688)
|
||||
|
@ -165,12 +164,12 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
.append(ELLIPSIS)
|
||||
.append(Util.emptyIfNull(overflowText));
|
||||
|
||||
EmojiParser.CandidateList newCandidates = EmojiProvider.getInstance(getContext()).getCandidates(newContent);
|
||||
EmojiParser.CandidateList newCandidates = isInEditMode() ? null : EmojiProvider.getCandidates(newContent);
|
||||
|
||||
if (useSystemEmoji || newCandidates == null || newCandidates.size() == 0) {
|
||||
super.setText(newContent, BufferType.NORMAL);
|
||||
} else {
|
||||
CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this);
|
||||
CharSequence emojified = EmojiProvider.emojify(newCandidates, newContent, this);
|
||||
super.setText(emojified, BufferType.SPANNABLE);
|
||||
}
|
||||
}
|
||||
|
@ -199,8 +198,8 @@ public class EmojiTextView extends AppCompatTextView {
|
|||
.append(ellipsized.subSequence(0, ellipsized.length()))
|
||||
.append(Optional.fromNullable(overflowText).or(""));
|
||||
|
||||
EmojiParser.CandidateList newCandidates = EmojiProvider.getInstance(getContext()).getCandidates(newContent);
|
||||
CharSequence emojified = EmojiProvider.getInstance(getContext()).emojify(newCandidates, newContent, this);
|
||||
EmojiParser.CandidateList newCandidates = isInEditMode() ? null : EmojiProvider.getCandidates(newContent);
|
||||
CharSequence emojified = EmojiProvider.emojify(newCandidates, newContent, this);
|
||||
|
||||
super.setText(emojified, BufferType.SPANNABLE);
|
||||
}
|
||||
|
|
|
@ -12,10 +12,7 @@ import org.thoughtcrime.securesms.emoji.ObsoleteEmoji;
|
|||
import org.thoughtcrime.securesms.util.StringUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -63,7 +60,7 @@ public final class EmojiUtil {
|
|||
if (Util.isEmpty(emoji)) {
|
||||
return null;
|
||||
} else {
|
||||
return EmojiProvider.getInstance(context).getEmojiDrawable(emoji);
|
||||
return EmojiProvider.getEmojiDrawable(context, emoji);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +71,7 @@ public final class EmojiUtil {
|
|||
* followed by a more wide check for all of the valid emoji unicode ranges (which could lead to
|
||||
* some false positives). YMMV.
|
||||
*/
|
||||
public static boolean isEmoji(@NonNull Context context, @Nullable String text) {
|
||||
public static boolean isEmoji(@Nullable String text) {
|
||||
if (Util.isEmpty(text)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -83,7 +80,7 @@ public final class EmojiUtil {
|
|||
return false;
|
||||
}
|
||||
|
||||
EmojiParser.CandidateList candidates = EmojiProvider.getInstance(context).getCandidates(text);
|
||||
EmojiParser.CandidateList candidates = EmojiProvider.getCandidates(text);
|
||||
|
||||
return (candidates != null && candidates.size() > 0) || EMOJI_PATTERN.matcher(text).matches();
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ public class EmojiVariationSelectorPopup extends PopupWindow {
|
|||
|
||||
for (String variation : variations) {
|
||||
ImageView imageView = (ImageView) LayoutInflater.from(context).inflate(R.layout.emoji_variation_selector_item, list, false);
|
||||
imageView.setImageDrawable(EmojiProvider.getInstance(context).getEmojiDrawable(variation));
|
||||
imageView.setImageDrawable(EmojiProvider.getEmojiDrawable(context, variation));
|
||||
imageView.setOnClickListener(v -> {
|
||||
listener.onEmojiSelected(variation);
|
||||
dismiss();
|
||||
|
|
|
@ -106,7 +106,6 @@ import org.thoughtcrime.securesms.util.GroupUtil;
|
|||
import org.thoughtcrime.securesms.util.Hex;
|
||||
import org.thoughtcrime.securesms.util.IdentityUtil;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.MessageRecordUtil;
|
||||
import org.thoughtcrime.securesms.util.RemoteDeleteUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
@ -154,7 +153,6 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
@ -719,7 +717,7 @@ public final class MessageContentProcessor {
|
|||
private void handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
|
||||
SignalServiceDataMessage.Reaction reaction = message.getReaction().get();
|
||||
|
||||
if (!EmojiUtil.isEmoji(context, reaction.getEmoji())) {
|
||||
if (!EmojiUtil.isEmoji(reaction.getEmoji())) {
|
||||
Log.w(TAG, "Reaction text is not a valid emoji! Ignoring the message.");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ public class EditAboutFragment extends Fragment implements ManageProfileActivity
|
|||
}
|
||||
|
||||
public void bind(@NonNull AboutPreset preset) {
|
||||
this.emoji.setImageDrawable(EmojiUtil.convertToDrawable(itemView.getContext(), preset.getEmoji()));
|
||||
this.emoji.setImageDrawable(EmojiUtil.convertToDrawable(requireContext(), preset.getEmoji()));
|
||||
this.body.setText(preset.getBodyRes());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,10 +71,10 @@ public class EmojiUtilTest_isEmoji {
|
|||
|
||||
@Test
|
||||
public void isEmoji() throws Exception {
|
||||
Context context = ApplicationProvider.getApplicationContext();
|
||||
Application application = ApplicationProvider.getApplicationContext();
|
||||
|
||||
PowerMockito.mockStatic(ApplicationDependencies.class);
|
||||
PowerMockito.when(ApplicationDependencies.getApplication()).thenReturn((Application) context);
|
||||
PowerMockito.when(ApplicationDependencies.getApplication()).thenReturn(application);
|
||||
PowerMockito.mockStatic(AttachmentSecretProvider.class);
|
||||
PowerMockito.when(AttachmentSecretProvider.getInstance(any())).thenThrow(IOException.class);
|
||||
PowerMockito.whenNew(SignalStore.class).withAnyArguments().thenReturn(null);
|
||||
|
@ -82,6 +82,6 @@ public class EmojiUtilTest_isEmoji {
|
|||
PowerMockito.when(SignalStore.internalValues()).thenReturn(PowerMockito.mock(InternalValues.class));
|
||||
EmojiSource.refresh();
|
||||
|
||||
assertEquals(output, EmojiUtil.isEmoji(context, input));
|
||||
assertEquals(output, EmojiUtil.isEmoji(input));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue