kopia lustrzana https://github.com/ryukoposting/Signal-Android
Fix issue where emojis would not appear on app launch.
rodzic
5fef0494b1
commit
f6b46f921c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue