Loading app/src/main/java/app/fedilab/android/helper/CustomEmoji.java +21 −10 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.text.Spannable; import android.text.style.ReplacementSpan; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; Loading @@ -18,7 +19,6 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.github.penfeizhou.animation.apng.APNGDrawable; import java.lang.ref.WeakReference; import java.util.List; Loading @@ -34,30 +34,32 @@ public class CustomEmoji extends ReplacementSpan { private final View view; private final float scale; private Drawable imageDrawable; private final WeakReference<View> viewWeakReference; CustomEmoji(WeakReference<View> viewWeakReference) { Context mContext = viewWeakReference.get().getContext(); this.viewWeakReference = viewWeakReference; view = viewWeakReference.get(); SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(mContext); scale = sharedpreferences.getFloat(mContext.getString(R.string.SET_FONT_SCALE), 1.0f); } public static void displayEmoji(List<Emoji> emojis, Spannable spannableString, WeakReference<View> viewWeakReference) { View view = viewWeakReference.get(); public static void displayEmoji(List<Emoji> emojis, Spannable spannableString, View view) { SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(view.getContext()); boolean animate = !sharedpreferences.getBoolean(view.getContext().getString(R.string.SET_DISABLE_GIF), false); for (Emoji emoji : emojis) { Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL) .matcher(spannableString); while (matcher.find()) { CustomEmoji customEmoji = new CustomEmoji(viewWeakReference); CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view)); spannableString.setSpan(customEmoji, matcher.start(), matcher.end(), 0); Glide.with(view) .asDrawable() .load(animate ? emoji.url : emoji.static_url) .into(customEmoji.getTarget(animate)); } } } Loading Loading @@ -93,30 +95,39 @@ public class CustomEmoji extends ReplacementSpan { return new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { Log.v(Helper.TAG, "resource: " + resource); Log.v(Helper.TAG, "instanceof: " + (resource instanceof Animatable)); View view = viewWeakReference.get(); if (animate && resource instanceof Animatable) { Drawable.Callback callback = resource.getCallback(); resource.setCallback(new Drawable.Callback() { @Override public void invalidateDrawable(@NonNull Drawable drawable) { if (callback != null) { callback.invalidateDrawable(drawable); } view.invalidate(); } @Override public void scheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable, long l) { if (callback != null) { callback.scheduleDrawable(drawable, runnable, l); } } @Override public void unscheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable) { if (callback != null) { callback.unscheduleDrawable(drawable, runnable); } } }); ((APNGDrawable) resource).start(); ((Animatable) resource).start(); } imageDrawable = resource; view.invalidate(); } } @Override public void onLoadCleared(@Nullable Drawable placeholder) { Loading app/src/main/java/app/fedilab/android/helper/MyAppGlideModule.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.module.AppGlideModule; @GlideModule public final class MyAppGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled() { return false; } } No newline at end of file app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +3 −25 Original line number Diff line number Diff line Loading @@ -82,13 +82,10 @@ import com.github.stom79.mytransl.translate.Params; import com.github.stom79.mytransl.translate.Translate; import com.varunest.sparkbutton.SparkButton; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -372,9 +369,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon); holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon); if (statusToDeal.emojis != null && statusToDeal.emojis.size() > 0) { CustomEmoji.displayEmoji(statusToDeal.emojis, statusToDeal.span_content, new WeakReference<>(holder.binding.statusContent)); CustomEmoji.displayEmoji(statusToDeal.emojis, statusToDeal.span_content, holder.binding.statusContent); } if (status.pinned) { Loading Loading @@ -930,6 +926,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.binding.statusContent.setVisibility(View.GONE); holder.binding.mediaContainer.setVisibility(View.GONE); } LayoutInflater inflater = ((Activity) context).getLayoutInflater(); //--- MEDIA ATTACHMENT --- if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) { Loading Loading @@ -1660,6 +1657,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.bindingReport.checkbox.setChecked(status.isChecked); holder.bindingReport.checkbox.setOnClickListener(v -> status.isChecked = !status.isChecked); } } private static boolean mediaObfuscated(Status status) { Loading Loading @@ -1786,22 +1784,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); statusManagement(context, statusesVM, searchVM, holder, this, statusList, null, status, timelineType, minified, canBeFederated); if (holder.timer != null) { holder.timer.cancel(); holder.timer = null; } if (status.emojis != null && status.emojis.size() > 0) { holder.timer = new Timer(); holder.timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = () -> holder.binding.statusContent.invalidate(); mainHandler.post(myRunnable); } }, 100, 100); } } else if (viewHolder.getItemViewType() == STATUS_ART) { StatusViewHolder holder = (StatusViewHolder) viewHolder; MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account); Loading Loading @@ -1867,9 +1849,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { super.onViewRecycled(holder); if (holder instanceof StatusViewHolder && ((StatusViewHolder) holder).timer != null) { ((StatusViewHolder) holder).timer.cancel(); } } public interface FetchMoreCallBack { Loading @@ -1885,7 +1864,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> DrawerFetchMoreBinding bindingFetchMore; DrawerStatusNotificationBinding bindingNotification; DrawerStatusArtBinding bindingArt; Timer timer; StatusViewHolder(DrawerStatusBinding itemView) { super(itemView.getRoot()); Loading Loading
app/src/main/java/app/fedilab/android/helper/CustomEmoji.java +21 −10 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.text.Spannable; import android.text.style.ReplacementSpan; import android.util.Log; import android.view.View; import androidx.annotation.NonNull; Loading @@ -18,7 +19,6 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.github.penfeizhou.animation.apng.APNGDrawable; import java.lang.ref.WeakReference; import java.util.List; Loading @@ -34,30 +34,32 @@ public class CustomEmoji extends ReplacementSpan { private final View view; private final float scale; private Drawable imageDrawable; private final WeakReference<View> viewWeakReference; CustomEmoji(WeakReference<View> viewWeakReference) { Context mContext = viewWeakReference.get().getContext(); this.viewWeakReference = viewWeakReference; view = viewWeakReference.get(); SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(mContext); scale = sharedpreferences.getFloat(mContext.getString(R.string.SET_FONT_SCALE), 1.0f); } public static void displayEmoji(List<Emoji> emojis, Spannable spannableString, WeakReference<View> viewWeakReference) { View view = viewWeakReference.get(); public static void displayEmoji(List<Emoji> emojis, Spannable spannableString, View view) { SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(view.getContext()); boolean animate = !sharedpreferences.getBoolean(view.getContext().getString(R.string.SET_DISABLE_GIF), false); for (Emoji emoji : emojis) { Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL) .matcher(spannableString); while (matcher.find()) { CustomEmoji customEmoji = new CustomEmoji(viewWeakReference); CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view)); spannableString.setSpan(customEmoji, matcher.start(), matcher.end(), 0); Glide.with(view) .asDrawable() .load(animate ? emoji.url : emoji.static_url) .into(customEmoji.getTarget(animate)); } } } Loading Loading @@ -93,30 +95,39 @@ public class CustomEmoji extends ReplacementSpan { return new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { Log.v(Helper.TAG, "resource: " + resource); Log.v(Helper.TAG, "instanceof: " + (resource instanceof Animatable)); View view = viewWeakReference.get(); if (animate && resource instanceof Animatable) { Drawable.Callback callback = resource.getCallback(); resource.setCallback(new Drawable.Callback() { @Override public void invalidateDrawable(@NonNull Drawable drawable) { if (callback != null) { callback.invalidateDrawable(drawable); } view.invalidate(); } @Override public void scheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable, long l) { if (callback != null) { callback.scheduleDrawable(drawable, runnable, l); } } @Override public void unscheduleDrawable(@NonNull Drawable drawable, @NonNull Runnable runnable) { if (callback != null) { callback.unscheduleDrawable(drawable, runnable); } } }); ((APNGDrawable) resource).start(); ((Animatable) resource).start(); } imageDrawable = resource; view.invalidate(); } } @Override public void onLoadCleared(@Nullable Drawable placeholder) { Loading
app/src/main/java/app/fedilab/android/helper/MyAppGlideModule.java 0 → 100644 +12 −0 Original line number Diff line number Diff line package app.fedilab.android.helper; import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.module.AppGlideModule; @GlideModule public final class MyAppGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled() { return false; } } No newline at end of file
app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +3 −25 Original line number Diff line number Diff line Loading @@ -82,13 +82,10 @@ import com.github.stom79.mytransl.translate.Params; import com.github.stom79.mytransl.translate.Translate; import com.varunest.sparkbutton.SparkButton; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Timer; import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern; Loading Loading @@ -372,9 +369,8 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.binding.actionButtonBoost.setActiveImageTint(R.color.boost_icon); holder.binding.actionButtonBookmark.setActiveImageTint(R.color.marked_icon); if (statusToDeal.emojis != null && statusToDeal.emojis.size() > 0) { CustomEmoji.displayEmoji(statusToDeal.emojis, statusToDeal.span_content, new WeakReference<>(holder.binding.statusContent)); CustomEmoji.displayEmoji(statusToDeal.emojis, statusToDeal.span_content, holder.binding.statusContent); } if (status.pinned) { Loading Loading @@ -930,6 +926,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.binding.statusContent.setVisibility(View.GONE); holder.binding.mediaContainer.setVisibility(View.GONE); } LayoutInflater inflater = ((Activity) context).getLayoutInflater(); //--- MEDIA ATTACHMENT --- if (statusToDeal.media_attachments != null && statusToDeal.media_attachments.size() > 0) { Loading Loading @@ -1660,6 +1657,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> holder.bindingReport.checkbox.setChecked(status.isChecked); holder.bindingReport.checkbox.setOnClickListener(v -> status.isChecked = !status.isChecked); } } private static boolean mediaObfuscated(Status status) { Loading Loading @@ -1786,22 +1784,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class); SearchVM searchVM = new ViewModelProvider((ViewModelStoreOwner) context).get(SearchVM.class); statusManagement(context, statusesVM, searchVM, holder, this, statusList, null, status, timelineType, minified, canBeFederated); if (holder.timer != null) { holder.timer.cancel(); holder.timer = null; } if (status.emojis != null && status.emojis.size() > 0) { holder.timer = new Timer(); holder.timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { Handler mainHandler = new Handler(Looper.getMainLooper()); Runnable myRunnable = () -> holder.binding.statusContent.invalidate(); mainHandler.post(myRunnable); } }, 100, 100); } } else if (viewHolder.getItemViewType() == STATUS_ART) { StatusViewHolder holder = (StatusViewHolder) viewHolder; MastodonHelper.loadPPMastodon(holder.bindingArt.artPp, status.account); Loading Loading @@ -1867,9 +1849,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> @Override public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { super.onViewRecycled(holder); if (holder instanceof StatusViewHolder && ((StatusViewHolder) holder).timer != null) { ((StatusViewHolder) holder).timer.cancel(); } } public interface FetchMoreCallBack { Loading @@ -1885,7 +1864,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> DrawerFetchMoreBinding bindingFetchMore; DrawerStatusNotificationBinding bindingNotification; DrawerStatusArtBinding bindingArt; Timer timer; StatusViewHolder(DrawerStatusBinding itemView) { super(itemView.getRoot()); Loading