Fix issue where emojis would not appear on app launch.

fork-5.53.8
Alex Hart 2021-08-02 12:01:14 -03:00 zatwierdzone przez Greyson Parrelli
rodzic 5fef0494b1
commit f6b46f921c
2 zmienionych plików z 43 dodań i 19 usunięć

Wyświetl plik

@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.emoji.EmojiPageCache;
import org.thoughtcrime.securesms.emoji.EmojiSource;
import org.thoughtcrime.securesms.util.DeviceProperties;
import org.thoughtcrime.securesms.util.FutureTaskListener;
import org.thoughtcrime.securesms.util.ListenableFutureTask;
import java.util.concurrent.ExecutionException;
@ -52,7 +53,7 @@ class EmojiProvider {
SpannableStringBuilder builder = new SpannableStringBuilder(text);
for (EmojiParser.Candidate candidate : matches) {
Drawable drawable = getEmojiDrawable(tv.getContext(), candidate.getDrawInfo());
Drawable drawable = getEmojiDrawable(tv.getContext(), candidate.getDrawInfo(), tv::requestLayout);
if (drawable != null) {
builder.setSpan(new EmojiSpan(drawable, tv), candidate.getStartIndex(), candidate.getEndIndex(),
@ -65,10 +66,17 @@ class EmojiProvider {
static @Nullable Drawable getEmojiDrawable(@NonNull Context context, @Nullable CharSequence emoji) {
EmojiDrawInfo drawInfo = EmojiSource.getLatest().getEmojiTree().getEmoji(emoji, 0, emoji.length());
return getEmojiDrawable(context, drawInfo);
return getEmojiDrawable(context, drawInfo, null);
}
private static @Nullable Drawable getEmojiDrawable(@NonNull Context context, @Nullable EmojiDrawInfo drawInfo) {
/**
* Gets an EmojiDrawable from the Page Cache
*
* @param context Context object used in reading and writing from disk
* @param drawInfo Information about the emoji being displayed
* @param onEmojiLoaded Runnable which will trigger when an emoji is loaded from disk
*/
private static @Nullable Drawable getEmojiDrawable(@NonNull Context context, @Nullable EmojiDrawInfo drawInfo, @Nullable Runnable onEmojiLoaded) {
if (drawInfo == null) {
return null;
}
@ -77,19 +85,30 @@ class EmojiProvider {
final EmojiSource source = EmojiSource.getLatest();
final EmojiDrawable drawable = new EmojiDrawable(source, drawInfo, lowMemoryDecodeScale);
EmojiPageCache.INSTANCE
.load(context, drawInfo.getPage(), lowMemoryDecodeScale)
.addListener(new FutureTaskListener<Bitmap>() {
@Override
public void onSuccess(Bitmap result) {
ThreadUtil.runOnMain(() -> drawable.setBitmap(result));
}
EmojiPageCache.LoadResult loadResult = EmojiPageCache.INSTANCE.load(context, drawInfo.getPage(), lowMemoryDecodeScale);
@Override
public void onFailure(ExecutionException exception) {
Log.d(TAG, "Failed to load emoji bitmap resource", exception);
}
});
if (loadResult instanceof EmojiPageCache.LoadResult.Immediate) {
ThreadUtil.runOnMain(() -> drawable.setBitmap(((EmojiPageCache.LoadResult.Immediate) loadResult).getBitmap()));
} else if (loadResult instanceof EmojiPageCache.LoadResult.Async) {
((EmojiPageCache.LoadResult.Async) loadResult).getTask().addListener(new FutureTaskListener<Bitmap>() {
@Override
public void onSuccess(Bitmap result) {
ThreadUtil.runOnMain(() -> {
drawable.setBitmap(result);
if (onEmojiLoaded != null) {
onEmojiLoaded.run();
}
});
}
@Override
public void onFailure(ExecutionException exception) {
Log.d(TAG, "Failed to load emoji bitmap resource", exception);
}
});
} else {
throw new IllegalStateException("Unexpected subclass " + loadResult.getClass());
}
return drawable;
}

Wyświetl plik

@ -21,15 +21,15 @@ object EmojiPageCache {
private val tasks: HashMap<EmojiPageRequest, ListenableFutureTask<Bitmap>> = hashMapOf()
@MainThread
fun load(context: Context, emojiPage: EmojiPage, inSampleSize: Int): ListenableFutureTask<Bitmap> {
fun load(context: Context, emojiPage: EmojiPage, inSampleSize: Int): LoadResult {
val applicationContext = context.applicationContext
val emojiPageRequest = EmojiPageRequest(emojiPage, inSampleSize)
val bitmap: Bitmap? = cache[emojiPageRequest]
val task: ListenableFutureTask<Bitmap>? = tasks[emojiPageRequest]
return when {
bitmap != null -> ListenableFutureTask(bitmap)
task != null -> task
bitmap != null -> LoadResult.Immediate(bitmap)
task != null -> LoadResult.Async(task)
else -> {
val newTask = ListenableFutureTask<Bitmap> {
try {
@ -56,7 +56,7 @@ object EmojiPageCache {
}
}
newTask
LoadResult.Async(newTask)
}
}
}
@ -75,4 +75,9 @@ object EmojiPageCache {
}
private data class EmojiPageRequest(val emojiPage: EmojiPage, val inSampleSize: Int)
sealed class LoadResult {
data class Immediate(val bitmap: Bitmap) : LoadResult()
data class Async(val task: ListenableFutureTask<Bitmap>) : LoadResult()
}
}