diff --git a/app/build.gradle b/app/build.gradle index 8518e1c0..484b435e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -119,7 +119,7 @@ dependencies { implementation "org.conscrypt:conscrypt-android:2.5.2" implementation 'com.vanniktech:emoji-one:0.6.0' implementation 'com.github.GrenderG:Toasty:1.5.2' - implementation "com.github.bumptech.glide:glide:4.14.2" + implementation "com.github.bumptech.glide:glide:4.16.0" implementation "com.github.bumptech.glide:okhttp3-integration:4.14.2" implementation("com.github.bumptech.glide:recyclerview-integration:4.14.2") { // Excludes the support library because it's already included by Glide. diff --git a/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java index f0ca476e..f4745095 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/mastodon/activities/ProfileActivity.java @@ -540,7 +540,12 @@ public class ProfileActivity extends BaseActivity { }); binding.accountNote.setText( account.getSpanNote(ProfileActivity.this, - binding.accountNote), + binding.accountNote, () -> { + //TODO: replace this hack + binding.accountNote.setText( + account.getSpanNote(ProfileActivity.this, binding.accountNote, null), TextView.BufferType.SPANNABLE); + + }), TextView.BufferType.SPANNABLE); binding.accountNote.setMovementMethod(LinkMovementMethod.getInstance()); diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java index 7e2474f6..b2b9d185 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Account.java @@ -95,7 +95,7 @@ public class Account implements Serializable { if (display_name == null || display_name.isEmpty()) { display_name = username; } - return SpannableHelper.convert(context, display_name, null, this, null, view, true, false); + return SpannableHelper.convert(context, display_name, null, this, null, view, true, false, null); } public synchronized Spannable getSpanDisplayNameEmoji(Activity activity, View view) { @@ -106,11 +106,11 @@ public class Account implements Serializable { } public synchronized Spannable getSpanDisplayNameTitle(Context context, View view, String title) { - return SpannableHelper.convert(context, title, null, this, null, view, true, false); + return SpannableHelper.convert(context, title, null, this, null, view, true, false, null); } - public synchronized Spannable getSpanNote(Context context, View view) { - return SpannableHelper.convert(context, note, null, this, null, view, true, false); + public synchronized Spannable getSpanNote(Context context, View view, SpannableHelper.Callback callback) { + return SpannableHelper.convert(context, note, null, this, null, view, true, false, callback); } diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Announcement.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Announcement.java index c18c2f2b..4f9a9efe 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Announcement.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Announcement.java @@ -56,7 +56,7 @@ public class Announcement { public synchronized Spannable getSpanContent(Context context, View view) { - return SpannableHelper.convert(context, content, null, null, this, view, true, false); + return SpannableHelper.convert(context, content, null, null, this, view, true, false, null); } } diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Field.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Field.java index f06588f9..1977f8a8 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Field.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Field.java @@ -47,7 +47,7 @@ public class Field implements Serializable { if (verified_at != null && value != null) { value_span = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.verified_text)); } - Spannable spannable = SpannableHelper.convert(context, value, null, account, null, view, true, false); + Spannable spannable = SpannableHelper.convert(context, value, null, account, null, view, true, false, null); if (value_span != null && spannable != null) { spannable.setSpan(value_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } @@ -57,7 +57,7 @@ public class Field implements Serializable { public synchronized Spannable getLabelSpan(Context context, Account account, View view) { - Spannable spannable = SpannableHelper.convert(context, name, null, account, null, view, true, false); + Spannable spannable = SpannableHelper.convert(context, name, null, account, null, view, true, false, null); if (name_span != null && spannable != null) { spannable.setSpan(name_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Poll.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Poll.java index ab29a330..00be9311 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Poll.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Poll.java @@ -61,7 +61,7 @@ public class Poll implements Serializable { public transient Spannable span_title; public Spannable getSpanTitle(Context context, Status status,View view) { - span_title = SpannableHelper.convert(context, title, status, null, null, view, false, false); + span_title = SpannableHelper.convert(context, title, status, null, null, view, false, false, null); return span_title; } } diff --git a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Status.java b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Status.java index be1b69fd..1ff4492a 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Status.java +++ b/app/src/main/java/app/fedilab/android/mastodon/client/entities/api/Status.java @@ -155,23 +155,23 @@ public class Status implements Serializable, Cloneable { return same; } - public synchronized Spannable getSpanContent(Context context, boolean checkRemotely, View view) { + public synchronized Spannable getSpanContent(Context context, boolean checkRemotely, View view, SpannableHelper.Callback callback) { if (contentSpan == null) { - contentSpan = SpannableHelper.convert(context, content, this, null, null, checkRemotely, view, true, true); + contentSpan = SpannableHelper.convert(context, content, this, null, null, checkRemotely, view, true, true, callback); } return contentSpan; } - public synchronized Spannable getSpanSpoiler(Context context, View view) { + public synchronized Spannable getSpanSpoiler(Context context, View view, SpannableHelper.Callback callback) { if (contentSpoilerSpan == null) { - contentSpoilerSpan = SpannableHelper.convert(context, spoiler_text, this, null, null, view, true, false); + contentSpoilerSpan = SpannableHelper.convert(context, spoiler_text, this, null, null, view, true, false, callback); } return contentSpoilerSpan; } - public synchronized Spannable getSpanTranslate(Context context, View view) { + public synchronized Spannable getSpanTranslate(Context context, View view, SpannableHelper.Callback callback) { if (contentTranslateSpan == null) { - contentTranslateSpan = SpannableHelper.convert(context, translationContent, this, null, null, view, true, true); + contentTranslateSpan = SpannableHelper.convert(context, translationContent, this, null, null, view, true, true, callback); } return contentTranslateSpan; } @@ -186,8 +186,6 @@ public class Status implements Serializable, Cloneable { BOTTOM } - public interface Callback { - void emojiFetched(); - } + } diff --git a/app/src/main/java/app/fedilab/android/mastodon/helper/CustomImageSpan.java b/app/src/main/java/app/fedilab/android/mastodon/helper/CustomImageSpan.java index 5833e86f..c4a242ba 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/helper/CustomImageSpan.java +++ b/app/src/main/java/app/fedilab/android/mastodon/helper/CustomImageSpan.java @@ -62,7 +62,7 @@ public class CustomImageSpan extends ReplacementSpan { } } - public Target getTarget(View view, boolean animate) { + public Target getTarget(View view, boolean animate, SpannableHelper.Callback callback) { return new CustomTarget<>() { @Override @@ -104,10 +104,19 @@ public class CustomImageSpan extends ReplacementSpan { } imageDrawable = resource; view.invalidate(); + if(callback != null) { + callback.emojiFetched(); + } } @Override public void onLoadCleared(@Nullable Drawable placeholder) { + if(imageDrawable != null && imageDrawable instanceof Animatable) { + ((Animatable) imageDrawable).stop(); + imageDrawable.setCallback(null); + } + imageDrawable = null; + view.invalidate(); } }; } diff --git a/app/src/main/java/app/fedilab/android/mastodon/helper/SpannableHelper.java b/app/src/main/java/app/fedilab/android/mastodon/helper/SpannableHelper.java index 22d1f1e1..a8d1cbff 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/helper/SpannableHelper.java +++ b/app/src/main/java/app/fedilab/android/mastodon/helper/SpannableHelper.java @@ -103,19 +103,22 @@ import io.noties.prism4j.Prism4j; public class SpannableHelper { + public interface Callback { + void emojiFetched(); + } public static final String CLICKABLE_SPAN = "CLICKABLE_SPAN"; private static int linkColor; private static boolean underlineLinks; public static Spannable convert(Context context, String text, Status status, Account account, Announcement announcement, - View view, boolean convertHtml, boolean convertMarkdown) { - return convert(context, text, status, account, announcement, false, view, convertHtml, convertMarkdown); + View view, boolean convertHtml, boolean convertMarkdown, Callback callback) { + return convert(context, text, status, account, announcement, false, view, convertHtml, convertMarkdown, callback); } public static Spannable convert(Context context, String text, Status status, Account account, Announcement announcement, boolean checkRemotely, - View view, boolean convertHtml, boolean convertMarkdown) { + View view, boolean convertHtml, boolean convertMarkdown, Callback callback) { if (text == null) { return null; } @@ -385,7 +388,7 @@ public class SpannableHelper { Glide.with(context) .asDrawable() .load(animate ? emoji.url : emoji.static_url) - .into(customImageSpan.getTarget(view, animate)); + .into(customImageSpan.getTarget(view, animate, callback)); } } } @@ -402,7 +405,7 @@ public class SpannableHelper { Glide.with(context) .asDrawable() .load(url) - .into(customImageSpan.getTarget(view, false)); + .into(customImageSpan.getTarget(view, false, null)); } } @@ -1014,7 +1017,7 @@ public class SpannableHelper { Glide.with(view.getContext()) .asDrawable() .load(animate ? emoji.url : emoji.static_url) - .into(customImageSpan.getTarget(view, animate)); + .into(customImageSpan.getTarget(view, animate, null)); } } } diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/AccountAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/AccountAdapter.java index e65f9f41..6502278f 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/AccountAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/AccountAdapter.java @@ -314,7 +314,7 @@ public class AccountAdapter extends RecyclerView.AdaptermRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); holder.binding.statusContent.setMovementMethod(LongClickLinkMovementMethod.getInstance()); MastodonHelper.loadPPMastodon(holder.binding.avatar, status.account); @@ -1434,7 +1434,7 @@ public class ComposeAdapter extends RecyclerView.AdaptermRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); } else { holder.binding.spoiler.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ConversationAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ConversationAdapter.java index 41763b68..98345407 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ConversationAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/ConversationAdapter.java @@ -199,7 +199,7 @@ public class ConversationAdapter extends RecyclerView.AdaptermRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); } else { holder.binding.spoiler.setVisibility(View.GONE); @@ -209,7 +209,7 @@ public class ConversationAdapter extends RecyclerView.AdaptermRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); //--- DATE --- holder.binding.lastMessageDate.setText(Helper.dateDiff(context, conversation.last_status.created_at)); diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java index 7e25c11b..058169c3 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusAdapter.java @@ -604,7 +604,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.quotedMessage.cardviewContainer.setStrokeColor(ThemeHelper.getAttColor(context, R.attr.colorPrimary)); holder.binding.quotedMessage.statusContent.setText( statusToDeal.quote.getSpanContent(context, remote, - holder.binding.quotedMessage.statusContent), + holder.binding.quotedMessage.statusContent, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); MastodonHelper.loadPPMastodon(holder.binding.quotedMessage.avatar, statusToDeal.quote.account); if (statusToDeal.quote.account != null) { @@ -619,7 +619,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.quotedMessage.spoiler.setVisibility(View.VISIBLE); holder.binding.quotedMessage.spoiler.setText( statusToDeal.quote.getSpanSpoiler(context, - holder.binding.quotedMessage.spoiler), + holder.binding.quotedMessage.spoiler, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); } else { holder.binding.quotedMessage.spoiler.setVisibility(View.GONE); @@ -1440,7 +1440,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.spoiler.setVisibility(View.VISIBLE); holder.binding.spoiler.setText( statusToDeal.getSpanSpoiler(context, - holder.binding.spoiler), + holder.binding.spoiler, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); statusToDeal.isExpended = true; } else { @@ -1453,7 +1453,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.spoiler.setText( statusToDeal.getSpanSpoiler(context, - holder.binding.spoiler), + holder.binding.spoiler, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); } if (statusToDeal.isExpended) { @@ -1506,7 +1506,7 @@ public class StatusAdapter extends RecyclerView.Adapter //--- MAIN CONTENT --- holder.binding.statusContent.setText( statusToDeal.getSpanContent(context, remote, - holder.binding.statusContent), + holder.binding.statusContent, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); if (truncate_toots_size > 0) { holder.binding.statusContent.setMaxLines(truncate_toots_size); @@ -1531,7 +1531,7 @@ public class StatusAdapter extends RecyclerView.Adapter holder.binding.containerTrans.setVisibility(View.VISIBLE); holder.binding.statusContentTranslated.setText( statusToDeal.getSpanTranslate(context, - holder.binding.statusContentTranslated), + holder.binding.statusContentTranslated, ()->recyclerView.post(() -> adapter.notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); } else { holder.binding.containerTrans.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java index 86f1c0f1..d1711662 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusDirectMessageAdapter.java @@ -241,7 +241,7 @@ public class StatusDirectMessageAdapter extends RecyclerView.AdaptermRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), TextView.BufferType.SPANNABLE); holder.binding.messageContent.setMovementMethod(LongClickLinkMovementMethod.getInstance()); if (measuredWidth <= 0 && status.media_attachments != null && status.media_attachments.size() > 0) { diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusHistoryAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusHistoryAdapter.java index 5ffbd83c..6036b22b 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusHistoryAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/StatusHistoryAdapter.java @@ -56,13 +56,13 @@ public class StatusHistoryAdapter extends RecyclerView.Adapter notifyItemChanged(holder.getBindingAdapterPosition())), TextView.BufferType.SPANNABLE); if (status.spoiler_text != null && !status.spoiler_text.trim().isEmpty()) { holder.binding.spoiler.setVisibility(View.VISIBLE); holder.binding.spoiler.setText( status.getSpanSpoiler(context, - holder.binding.spoiler), + holder.binding.spoiler, ()-> notifyItemChanged(holder.getBindingAdapterPosition())), TextView.BufferType.SPANNABLE); } else { holder.binding.spoiler.setVisibility(View.GONE); diff --git a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/SuggestionAdapter.java b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/SuggestionAdapter.java index 12b62348..7f67ba27 100644 --- a/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/SuggestionAdapter.java +++ b/app/src/main/java/app/fedilab/android/mastodon/ui/drawer/SuggestionAdapter.java @@ -106,7 +106,7 @@ public class SuggestionAdapter extends RecyclerView.Adapter {