From 333c38c64d6fcae1847613ccaabee2df6d0fcc30 Mon Sep 17 00:00:00 2001 From: sk Date: Tue, 7 Feb 2023 15:44:40 +0100 Subject: [PATCH] add alt badge to video/gifs closes sk22#409 --- .../displayitems/ImageStatusDisplayItem.java | 139 ++++++++++++++++++ .../displayitems/PhotoStatusDisplayItem.java | 136 +---------------- mastodon/src/main/res/layout/alt_badge.xml | 79 ++++++++++ .../src/main/res/layout/display_item_gifv.xml | 2 + .../main/res/layout/display_item_photo.xml | 78 +--------- .../main/res/layout/display_item_video.xml | 2 + 6 files changed, 225 insertions(+), 211 deletions(-) create mode 100644 mastodon/src/main/res/layout/alt_badge.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ImageStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ImageStatusDisplayItem.java index 782f94e17..b76cb997b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ImageStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/ImageStatusDisplayItem.java @@ -1,12 +1,21 @@ package org.joinmastodon.android.ui.displayitems; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.app.Activity; import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import android.view.ViewTreeObserver; +import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.TextView; +import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.model.Attachment; @@ -19,6 +28,7 @@ import org.joinmastodon.android.ui.views.ImageAttachmentFrameLayout; import androidx.annotation.LayoutRes; import me.grishka.appkit.imageloader.ImageLoaderViewHolder; import me.grishka.appkit.imageloader.requests.ImageLoaderRequest; +import me.grishka.appkit.utils.CubicBezierInterpolator; public abstract class ImageStatusDisplayItem extends StatusDisplayItem{ public final int index; @@ -56,11 +66,35 @@ public abstract class ImageStatusDisplayItem extends StatusDisplayItem{ private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable(); private boolean didClear; + private AnimatorSet currentAnim; + private final FrameLayout altTextWrapper; + private final TextView altTextButton; + private final ImageView noAltTextButton; + private final View altTextScroller; + private final ImageButton altTextClose; + private final TextView altText, noAltText; + + private View altOrNoAltButton; + private boolean altTextShown; + public Holder(Activity activity, @LayoutRes int layout, ViewGroup parent){ super(activity, layout, parent); photo=findViewById(R.id.photo); photo.setOnClickListener(this::onViewClick); this.layout=(ImageAttachmentFrameLayout)itemView; + + altTextWrapper=findViewById(R.id.alt_text_wrapper); + altTextButton=findViewById(R.id.alt_button); + noAltTextButton=findViewById(R.id.no_alt_button); + altTextScroller=findViewById(R.id.alt_text_scroller); + altTextClose=findViewById(R.id.alt_text_close); + altText=findViewById(R.id.alt_text); + noAltText=findViewById(R.id.no_alt_text); + + altTextButton.setOnClickListener(this::onShowHideClick); + noAltTextButton.setOnClickListener(this::onShowHideClick); + altTextClose.setOnClickListener(this::onShowHideClick); +// altTextScroller.setNestedScrollingEnabled(true); } @Override @@ -73,6 +107,111 @@ public abstract class ImageStatusDisplayItem extends StatusDisplayItem{ photo.setImageDrawable(crossfadeDrawable); photo.setContentDescription(TextUtils.isEmpty(item.attachment.description) ? item.parentFragment.getString(R.string.media_no_description) : item.attachment.description); didClear=false; + + if (currentAnim != null) currentAnim.cancel(); + + boolean altTextMissing = TextUtils.isEmpty(item.attachment.description); + altOrNoAltButton = altTextMissing ? noAltTextButton : altTextButton; + altTextShown=false; + + altTextScroller.setVisibility(View.GONE); + altTextClose.setVisibility(View.GONE); + altTextButton.setVisibility(View.VISIBLE); + noAltTextButton.setVisibility(View.VISIBLE); + altTextButton.setAlpha(1f); + noAltTextButton.setAlpha(1f); + altTextWrapper.setVisibility(View.VISIBLE); + + if (altTextMissing){ + if (GlobalUserPreferences.showNoAltIndicator) { + noAltTextButton.setVisibility(View.VISIBLE); + noAltText.setVisibility(View.VISIBLE); + altTextWrapper.setBackgroundResource(R.drawable.bg_image_no_alt_overlay); + altTextButton.setVisibility(View.GONE); + altText.setVisibility(View.GONE); + } else { + altTextWrapper.setVisibility(View.GONE); + } + }else{ + if (GlobalUserPreferences.showAltIndicator) { + noAltTextButton.setVisibility(View.GONE); + noAltText.setVisibility(View.GONE); + altTextWrapper.setBackgroundResource(R.drawable.bg_image_alt_overlay); + altTextButton.setVisibility(View.VISIBLE); + altTextButton.setText(R.string.sk_alt_button); + altText.setVisibility(View.VISIBLE); + altText.setText(item.attachment.description); + altText.setPadding(0, 0, 0, 0); + } else { + altTextWrapper.setVisibility(View.GONE); + } + } + } + + private void onShowHideClick(View v){ + boolean show=v.getId()==R.id.alt_button || v.getId()==R.id.no_alt_button; + + if(altTextShown==show) + return; + if(currentAnim!=null) + currentAnim.cancel(); + + altTextShown=show; + if(show){ + altTextScroller.setVisibility(View.VISIBLE); + altTextClose.setVisibility(View.VISIBLE); + }else{ + altOrNoAltButton.setVisibility(View.VISIBLE); + // Hide these views temporarily so FrameLayout measures correctly + altTextScroller.setVisibility(View.GONE); + altTextClose.setVisibility(View.GONE); + } + + // This is the current size... + int prevLeft=altTextWrapper.getLeft(); + int prevRight=altTextWrapper.getRight(); + int prevTop=altTextWrapper.getTop(); + altTextWrapper.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){ + @Override + public boolean onPreDraw(){ + altTextWrapper.getViewTreeObserver().removeOnPreDrawListener(this); + + // ...and this is after the layout pass, right now the FrameLayout has its final size, but we animate that change + if(!show){ + // Show these views again so they're visible for the duration of the animation. + // No one would notice they were missing during measure/layout. + altTextScroller.setVisibility(View.VISIBLE); + altTextClose.setVisibility(View.VISIBLE); + } + AnimatorSet set=new AnimatorSet(); + set.playTogether( + ObjectAnimator.ofInt(altTextWrapper, "left", prevLeft, altTextWrapper.getLeft()), + ObjectAnimator.ofInt(altTextWrapper, "right", prevRight, altTextWrapper.getRight()), + ObjectAnimator.ofInt(altTextWrapper, "top", prevTop, altTextWrapper.getTop()), + ObjectAnimator.ofFloat(altOrNoAltButton, View.ALPHA, show ? 1f : 0f, show ? 0f : 1f), + ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f), + ObjectAnimator.ofFloat(altTextClose, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f) + ); + set.setDuration(300); + set.setInterpolator(CubicBezierInterpolator.DEFAULT); + set.addListener(new AnimatorListenerAdapter(){ + @Override + public void onAnimationEnd(Animator animation){ + if(show){ + altOrNoAltButton.setVisibility(View.GONE); + }else{ + altTextScroller.setVisibility(View.GONE); + altTextClose.setVisibility(View.GONE); + } + currentAnim=null; + } + }); + set.start(); + currentAnim=set; + + return true; + } + }); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PhotoStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PhotoStatusDisplayItem.java index bbfc7a082..a0609d10c 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PhotoStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/PhotoStatusDisplayItem.java @@ -37,141 +37,9 @@ public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{ return Type.PHOTO; } - public static class Holder extends ImageStatusDisplayItem.Holder{ - private final FrameLayout altTextWrapper; - private final TextView altTextButton; - private final ImageView noAltTextButton; - private final View altTextScroller; - private final ImageButton altTextClose; - private final TextView altText, noAltText; - - private View altOrNoAltButton; - private boolean altTextShown; - private AnimatorSet currentAnim; - - public Holder(Activity activity, ViewGroup parent){ + public static class Holder extends ImageStatusDisplayItem.Holder { + public Holder(Activity activity, ViewGroup parent) { super(activity, R.layout.display_item_photo, parent); - altTextWrapper=findViewById(R.id.alt_text_wrapper); - altTextButton=findViewById(R.id.alt_button); - noAltTextButton=findViewById(R.id.no_alt_button); - altTextScroller=findViewById(R.id.alt_text_scroller); - altTextClose=findViewById(R.id.alt_text_close); - altText=findViewById(R.id.alt_text); - noAltText=findViewById(R.id.no_alt_text); - - altTextButton.setOnClickListener(this::onShowHideClick); - noAltTextButton.setOnClickListener(this::onShowHideClick); - altTextClose.setOnClickListener(this::onShowHideClick); -// altTextScroller.setNestedScrollingEnabled(true); - } - - @Override - public void onBind(ImageStatusDisplayItem item){ - super.onBind(item); - boolean altTextMissing = TextUtils.isEmpty(item.attachment.description); - altOrNoAltButton = altTextMissing ? noAltTextButton : altTextButton; - altTextShown=false; - if(currentAnim!=null) - currentAnim.cancel(); - - altTextScroller.setVisibility(View.GONE); - altTextClose.setVisibility(View.GONE); - altTextButton.setVisibility(View.VISIBLE); - noAltTextButton.setVisibility(View.VISIBLE); - altTextButton.setAlpha(1f); - noAltTextButton.setAlpha(1f); - altTextWrapper.setVisibility(View.VISIBLE); - - if (altTextMissing){ - if (GlobalUserPreferences.showNoAltIndicator) { - noAltTextButton.setVisibility(View.VISIBLE); - noAltText.setVisibility(View.VISIBLE); - altTextWrapper.setBackgroundResource(R.drawable.bg_image_no_alt_overlay); - altTextButton.setVisibility(View.GONE); - altText.setVisibility(View.GONE); - } else { - altTextWrapper.setVisibility(View.GONE); - } - }else{ - if (GlobalUserPreferences.showAltIndicator) { - noAltTextButton.setVisibility(View.GONE); - noAltText.setVisibility(View.GONE); - altTextWrapper.setBackgroundResource(R.drawable.bg_image_alt_overlay); - altTextButton.setVisibility(View.VISIBLE); - altTextButton.setText(R.string.sk_alt_button); - altText.setVisibility(View.VISIBLE); - altText.setText(item.attachment.description); - altText.setPadding(0, 0, 0, 0); - } else { - altTextWrapper.setVisibility(View.GONE); - } - } - } - - private void onShowHideClick(View v){ - boolean show=v.getId()==R.id.alt_button || v.getId()==R.id.no_alt_button; - - if(altTextShown==show) - return; - if(currentAnim!=null) - currentAnim.cancel(); - - altTextShown=show; - if(show){ - altTextScroller.setVisibility(View.VISIBLE); - altTextClose.setVisibility(View.VISIBLE); - }else{ - altOrNoAltButton.setVisibility(View.VISIBLE); - // Hide these views temporarily so FrameLayout measures correctly - altTextScroller.setVisibility(View.GONE); - altTextClose.setVisibility(View.GONE); - } - - // This is the current size... - int prevLeft=altTextWrapper.getLeft(); - int prevRight=altTextWrapper.getRight(); - int prevTop=altTextWrapper.getTop(); - altTextWrapper.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener(){ - @Override - public boolean onPreDraw(){ - altTextWrapper.getViewTreeObserver().removeOnPreDrawListener(this); - - // ...and this is after the layout pass, right now the FrameLayout has its final size, but we animate that change - if(!show){ - // Show these views again so they're visible for the duration of the animation. - // No one would notice they were missing during measure/layout. - altTextScroller.setVisibility(View.VISIBLE); - altTextClose.setVisibility(View.VISIBLE); - } - AnimatorSet set=new AnimatorSet(); - set.playTogether( - ObjectAnimator.ofInt(altTextWrapper, "left", prevLeft, altTextWrapper.getLeft()), - ObjectAnimator.ofInt(altTextWrapper, "right", prevRight, altTextWrapper.getRight()), - ObjectAnimator.ofInt(altTextWrapper, "top", prevTop, altTextWrapper.getTop()), - ObjectAnimator.ofFloat(altOrNoAltButton, View.ALPHA, show ? 1f : 0f, show ? 0f : 1f), - ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f), - ObjectAnimator.ofFloat(altTextClose, View.ALPHA, show ? 0f : 1f, show ? 1f : 0f) - ); - set.setDuration(300); - set.setInterpolator(CubicBezierInterpolator.DEFAULT); - set.addListener(new AnimatorListenerAdapter(){ - @Override - public void onAnimationEnd(Animator animation){ - if(show){ - altOrNoAltButton.setVisibility(View.GONE); - }else{ - altTextScroller.setVisibility(View.GONE); - altTextClose.setVisibility(View.GONE); - } - currentAnim=null; - } - }); - set.start(); - currentAnim=set; - - return true; - } - }); } } } diff --git a/mastodon/src/main/res/layout/alt_badge.xml b/mastodon/src/main/res/layout/alt_badge.xml new file mode 100644 index 000000000..f165466cf --- /dev/null +++ b/mastodon/src/main/res/layout/alt_badge.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mastodon/src/main/res/layout/display_item_gifv.xml b/mastodon/src/main/res/layout/display_item_gifv.xml index 4dccf3eff..a3575ab06 100644 --- a/mastodon/src/main/res/layout/display_item_gifv.xml +++ b/mastodon/src/main/res/layout/display_item_gifv.xml @@ -25,4 +25,6 @@ android:layout_margin="8dp" android:background="@drawable/ic_gif"/> + + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/display_item_photo.xml b/mastodon/src/main/res/layout/display_item_photo.xml index d3129d379..462dab84a 100644 --- a/mastodon/src/main/res/layout/display_item_photo.xml +++ b/mastodon/src/main/res/layout/display_item_photo.xml @@ -1,6 +1,5 @@ @@ -11,81 +10,6 @@ android:layout_gravity="center" android:scaleType="centerCrop"/> - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/mastodon/src/main/res/layout/display_item_video.xml b/mastodon/src/main/res/layout/display_item_video.xml index 83e8112d9..1f1283fab 100644 --- a/mastodon/src/main/res/layout/display_item_video.xml +++ b/mastodon/src/main/res/layout/display_item_video.xml @@ -18,4 +18,6 @@ android:elevation="3dp" android:background="@drawable/play_button"/> + + \ No newline at end of file