|
|
|
|
@@ -5,8 +5,11 @@ import android.animation.AnimatorListenerAdapter;
|
|
|
|
|
import android.animation.AnimatorSet;
|
|
|
|
|
import android.animation.ObjectAnimator;
|
|
|
|
|
import android.app.Activity;
|
|
|
|
|
import android.graphics.drawable.ColorDrawable;
|
|
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
|
import android.graphics.drawable.LayerDrawable;
|
|
|
|
|
import android.text.TextUtils;
|
|
|
|
|
import android.view.Gravity;
|
|
|
|
|
import android.view.View;
|
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
|
import android.view.ViewTreeObserver;
|
|
|
|
|
@@ -19,9 +22,11 @@ import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
|
|
|
|
import org.joinmastodon.android.model.Attachment;
|
|
|
|
|
import org.joinmastodon.android.model.Status;
|
|
|
|
|
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
|
|
|
|
import org.joinmastodon.android.ui.drawables.SpoilerStripesDrawable;
|
|
|
|
|
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
|
|
|
|
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
|
|
|
|
import org.joinmastodon.android.ui.views.FrameLayoutThatOnlyMeasuresFirstChild;
|
|
|
|
|
import org.joinmastodon.android.ui.views.MaxWidthFrameLayout;
|
|
|
|
|
import org.joinmastodon.android.ui.views.MediaGridLayout;
|
|
|
|
|
import org.joinmastodon.android.utils.TypedObjectPool;
|
|
|
|
|
|
|
|
|
|
@@ -42,6 +47,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
private final List<Attachment> attachments;
|
|
|
|
|
private final ArrayList<ImageLoaderRequest> requests=new ArrayList<>();
|
|
|
|
|
public final Status status;
|
|
|
|
|
public boolean sensitiveRevealed;
|
|
|
|
|
|
|
|
|
|
public MediaGridStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, PhotoLayoutHelper.TiledLayoutResult tiledLayout, List<Attachment> attachments, Status status){
|
|
|
|
|
super(parentID, parentFragment);
|
|
|
|
|
@@ -49,6 +55,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
this.viewPool=parentFragment.getAttachmentViewsPool();
|
|
|
|
|
this.attachments=attachments;
|
|
|
|
|
this.status=status;
|
|
|
|
|
sensitiveRevealed=!status.sensitive;
|
|
|
|
|
for(Attachment att:attachments){
|
|
|
|
|
requests.add(new UrlImageLoaderRequest(switch(att.type){
|
|
|
|
|
case IMAGE -> att.url;
|
|
|
|
|
@@ -85,12 +92,18 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
private final View.OnClickListener clickListener=this::onViewClick, altTextClickListener=this::onAltTextClick;
|
|
|
|
|
private final ArrayList<MediaAttachmentViewController> controllers=new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
private final MaxWidthFrameLayout overlays;
|
|
|
|
|
private final FrameLayout altTextWrapper;
|
|
|
|
|
private final TextView altTextButton;
|
|
|
|
|
private final View altTextScroller;
|
|
|
|
|
private final ImageButton altTextClose;
|
|
|
|
|
private final TextView altText;
|
|
|
|
|
|
|
|
|
|
private final View sensitiveOverlay;
|
|
|
|
|
private final LayerDrawable sensitiveOverlayBG;
|
|
|
|
|
private static final ColorDrawable drawableForWhenThereIsNoBlurhash=new ColorDrawable(0xffffffff);
|
|
|
|
|
private final TextView hideSensitiveButton;
|
|
|
|
|
|
|
|
|
|
private int altTextIndex=-1;
|
|
|
|
|
private Animator altTextAnimator;
|
|
|
|
|
|
|
|
|
|
@@ -100,15 +113,34 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
layout=new MediaGridLayout(activity);
|
|
|
|
|
wrapper.addView(layout);
|
|
|
|
|
wrapper.setPadding(0, 0, 0, V.dp(8));
|
|
|
|
|
wrapper.setClipToPadding(false);
|
|
|
|
|
|
|
|
|
|
activity.getLayoutInflater().inflate(R.layout.overlay_image_alt_text, wrapper);
|
|
|
|
|
overlays=new MaxWidthFrameLayout(activity);
|
|
|
|
|
overlays.setMaxWidth(V.dp(MediaGridLayout.MAX_WIDTH));
|
|
|
|
|
wrapper.addView(overlays, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER_HORIZONTAL));
|
|
|
|
|
|
|
|
|
|
activity.getLayoutInflater().inflate(R.layout.overlay_image_alt_text, overlays);
|
|
|
|
|
altTextWrapper=findViewById(R.id.alt_text_wrapper);
|
|
|
|
|
altTextButton=findViewById(R.id.alt_button);
|
|
|
|
|
altTextScroller=findViewById(R.id.alt_text_scroller);
|
|
|
|
|
altTextClose=findViewById(R.id.alt_text_close);
|
|
|
|
|
altText=findViewById(R.id.alt_text);
|
|
|
|
|
altTextClose.setOnClickListener(this::onAltTextCloseClick);
|
|
|
|
|
wrapper.setClipToPadding(false);
|
|
|
|
|
|
|
|
|
|
hideSensitiveButton=(TextView) activity.getLayoutInflater().inflate(R.layout.alt_text_badge, overlays, false);
|
|
|
|
|
hideSensitiveButton.setText(R.string.hide);
|
|
|
|
|
FrameLayout.LayoutParams lp;
|
|
|
|
|
overlays.addView(hideSensitiveButton, lp=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, V.dp(24), Gravity.END | Gravity.BOTTOM));
|
|
|
|
|
int margin=V.dp(8);
|
|
|
|
|
lp.setMargins(margin, margin, margin, margin);
|
|
|
|
|
|
|
|
|
|
activity.getLayoutInflater().inflate(R.layout.overlay_image_sensitive, overlays);
|
|
|
|
|
sensitiveOverlay=findViewById(R.id.sensitive_overlay);
|
|
|
|
|
sensitiveOverlayBG=(LayerDrawable) sensitiveOverlay.getBackground();
|
|
|
|
|
sensitiveOverlayBG.setDrawableByLayerId(R.id.left_drawable, new SpoilerStripesDrawable(false));
|
|
|
|
|
sensitiveOverlayBG.setDrawableByLayerId(R.id.right_drawable, new SpoilerStripesDrawable(true));
|
|
|
|
|
sensitiveOverlay.setOnClickListener(v->revealSensitive());
|
|
|
|
|
hideSensitiveButton.setOnClickListener(v->hideSensitive());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -148,6 +180,16 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
}
|
|
|
|
|
altTextWrapper.setVisibility(View.GONE);
|
|
|
|
|
altTextIndex=-1;
|
|
|
|
|
|
|
|
|
|
if(!item.sensitiveRevealed){
|
|
|
|
|
sensitiveOverlay.setVisibility(View.VISIBLE);
|
|
|
|
|
layout.setVisibility(View.INVISIBLE);
|
|
|
|
|
updateBlurhashInSensitiveOverlay();
|
|
|
|
|
}else{
|
|
|
|
|
sensitiveOverlay.setVisibility(View.GONE);
|
|
|
|
|
layout.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
hideSensitiveButton.setVisibility(item.status.sensitive ? View.VISIBLE : View.GONE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@@ -182,7 +224,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
int[] loc={0, 0};
|
|
|
|
|
v.getLocationInWindow(loc);
|
|
|
|
|
int btnL=loc[0], btnT=loc[1];
|
|
|
|
|
wrapper.getLocationInWindow(loc);
|
|
|
|
|
overlays.getLocationInWindow(loc);
|
|
|
|
|
btnL-=loc[0];
|
|
|
|
|
btnT-=loc[1];
|
|
|
|
|
|
|
|
|
|
@@ -240,7 +282,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
int[] loc={0, 0};
|
|
|
|
|
btn.getLocationInWindow(loc);
|
|
|
|
|
int btnL=loc[0], btnT=loc[1];
|
|
|
|
|
wrapper.getLocationInWindow(loc);
|
|
|
|
|
overlays.getLocationInWindow(loc);
|
|
|
|
|
btnL-=loc[0];
|
|
|
|
|
btnT-=loc[1];
|
|
|
|
|
|
|
|
|
|
@@ -276,12 +318,6 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
set.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setRevealed(boolean revealed){
|
|
|
|
|
for(MediaAttachmentViewController c:controllers){
|
|
|
|
|
c.setRevealed(revealed);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MediaAttachmentViewController getViewController(int index){
|
|
|
|
|
return controllers.get(index);
|
|
|
|
|
}
|
|
|
|
|
@@ -290,5 +326,25 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|
|
|
|
layout.setClipChildren(clip);
|
|
|
|
|
wrapper.setClipChildren(clip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateBlurhashInSensitiveOverlay(){
|
|
|
|
|
Drawable d=item.attachments.get(0).blurhashPlaceholder;
|
|
|
|
|
sensitiveOverlayBG.setDrawableByLayerId(R.id.blurhash, d==null ? drawableForWhenThereIsNoBlurhash : d.mutate());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void revealSensitive(){
|
|
|
|
|
if(item.sensitiveRevealed)
|
|
|
|
|
return;
|
|
|
|
|
item.sensitiveRevealed=true;
|
|
|
|
|
V.setVisibilityAnimated(sensitiveOverlay, View.GONE);
|
|
|
|
|
layout.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void hideSensitive(){
|
|
|
|
|
if(!item.sensitiveRevealed)
|
|
|
|
|
return;
|
|
|
|
|
item.sensitiveRevealed=false;
|
|
|
|
|
V.setVisibilityAnimated(sensitiveOverlay, View.VISIBLE, ()->layout.setVisibility(View.INVISIBLE));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|