Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
add alt badge to video/gifs
Browse files Browse the repository at this point in the history
closes #409
  • Loading branch information
sk22 committed Feb 7, 2023
1 parent ca5827e commit 333c38c
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 211 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -19,6 +28,7 @@
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;
Expand Down Expand Up @@ -56,11 +66,35 @@ public static abstract class Holder<T extends ImageStatusDisplayItem> extends St
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
Expand All @@ -73,6 +107,111 @@ public void onBind(ImageStatusDisplayItem item){
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,141 +37,9 @@ public Type getType(){
return Type.PHOTO;
}

public static class Holder extends ImageStatusDisplayItem.Holder<PhotoStatusDisplayItem>{
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<PhotoStatusDisplayItem> {
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;
}
});
}
}
}
Loading

0 comments on commit 333c38c

Please sign in to comment.