download control details

Closes #4063
// FREEBIE
This commit is contained in:
Jake McGinty
2015-09-09 18:05:21 -10:00
committed by Moxie Marlinspike
parent 0794380ca8
commit 92b2da0286
17 changed files with 177 additions and 84 deletions

View File

@@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@@ -12,21 +11,27 @@ import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ViewUtil;
public class AnimatingToggle extends FrameLayout {
private View current;
private final Animation inAnimation;
private final Animation outAnimation;
public AnimatingToggle(Context context) {
super(context);
this(context, null);
}
public AnimatingToggle(Context context, AttributeSet attrs) {
super(context, attrs);
this(context, attrs, 0);
}
public AnimatingToggle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.outAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_out);
this.inAnimation = AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_in);
}
@Override
@@ -43,45 +48,10 @@ public class AnimatingToggle extends FrameLayout {
}
public void display(@Nullable View view) {
display(view, true);
}
protected void display(@Nullable View view, boolean animated) {
if (view == current) return;
if (animated) {
if (current != null) animateOut(current, AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_out));
if (view != null) animateIn(view, AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_in));
} else {
if (current != null) current.setVisibility(GONE);
if (view != null) view.setVisibility(VISIBLE);
}
if (current != null) ViewUtil.animateOut(current, outAnimation);
if (view != null) ViewUtil.animateIn(view, inAnimation);
current = view;
}
private void animateOut(final View view, Animation animation) {
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(animation);
}
private void animateIn(View view, Animation animation) {
animation.setInterpolator(new FastOutSlowInInterpolator());
view.setVisibility(View.VISIBLE);
view.startAnimation(animation);
}
}

View File

@@ -91,7 +91,6 @@ public class ThumbnailView extends FrameLayout {
private TransferControlView getTransferControls() {
if (transferControls == null) transferControls = ViewUtil.inflateStub(this, R.id.transfer_controls_stub);
return transferControls;
}
@@ -99,9 +98,10 @@ public class ThumbnailView extends FrameLayout {
this.backgroundColorHint = color;
}
public void setImageResource(@Nullable MasterSecret masterSecret,
long id, long timestamp,
@NonNull ListenableFutureTask<SlideDeck> slideDeckFuture)
public void setImageResource(@Nullable MasterSecret masterSecret,
long id,
long timestamp,
@NonNull ListenableFutureTask<SlideDeck> slideDeckFuture)
{
if (this.slideDeckFuture != null && this.slideDeckListener != null) {
this.slideDeckFuture.removeListener(this.slideDeckListener);
@@ -126,15 +126,17 @@ public class ThumbnailView extends FrameLayout {
Log.w(TAG, "Not re-loading slide " + slide.getPart().getPartId());
return;
}
if (!isContextValid()) {
Log.w(TAG, "Not loading slide, context is invalid");
return;
}
Log.w(TAG, "loading part with id " + slide.getPart().getPartId() + ", progress " + slide.getTransferProgress());
Log.w(TAG, "loading part with id " + slide.getPart().getPartId()
+ ", progress " + slide.getTransferProgress());
this.slide = slide;
buildGlideRequest(slide, masterSecret).into(image);
loadInto(slide, masterSecret, image);
if (this.slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_DONE) {
setOnClickListener(new ThumbnailClickDispatcher());
@@ -145,7 +147,6 @@ public class ThumbnailView extends FrameLayout {
if (!hideControls) {
getTransferControls().setSlide(slide);
getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
getTransferControls().setVisibility(View.VISIBLE);
}
}
@@ -189,29 +190,27 @@ public class ThumbnailView extends FrameLayout {
!((Activity)getContext()).isDestroyed();
}
private GenericRequestBuilder buildGlideRequest(@NonNull Slide slide,
@Nullable MasterSecret masterSecret)
private void loadInto(@NonNull Slide slide,
@Nullable MasterSecret masterSecret,
@NonNull ImageView view)
{
final GenericRequestBuilder builder;
if (slide.getThumbnailUri() != null) {
builder = buildThumbnailGlideRequest(slide, masterSecret);
buildThumbnailGlideRequest(slide, masterSecret).into(view);
} else if (!slide.isInProgress()) {
buildPlaceholderGlideRequest(slide).into(view);
} else {
builder = buildPlaceholderGlideRequest(slide);
}
if (slide.getTransferProgress() != PartDatabase.TRANSFER_PROGRESS_DONE && !hideControls) {
return builder;
} else {
return builder.error(R.drawable.ic_missing_thumbnail_picture);
Glide.clear(view);
}
}
private GenericRequestBuilder buildThumbnailGlideRequest(Slide slide, MasterSecret masterSecret) {
final GenericRequestBuilder builder;
if (slide.isDraft()) builder = buildDraftGlideRequest(slide, masterSecret);
else builder = buildPartGlideRequest(slide, masterSecret);
return builder;
if (slide.isInProgress()) return builder;
else return builder.error(R.drawable.ic_missing_thumbnail_picture);
}
private GenericRequestBuilder buildDraftGlideRequest(Slide slide, MasterSecret masterSecret) {

View File

@@ -3,9 +3,18 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.widget.ImageButton;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.pnikosis.materialishprogress.ProgressWheel;
import org.thoughtcrime.securesms.R;
@@ -17,10 +26,18 @@ import org.thoughtcrime.securesms.util.ViewUtil;
import de.greenrobot.event.EventBus;
public class TransferControlView extends AnimatingToggle {
private Slide slide;
private ProgressWheel progressWheel;
private ImageButton downloadButton;
public class TransferControlView extends FrameLayout {
private static final int TRANSITION_MS = 300;
@Nullable private Slide slide;
@Nullable private View current;
private final ProgressWheel progressWheel;
private final TextView downloadDetails;
private final Animation inAnimation;
private final Animation outAnimation;
private final int contractedWidth;
private final int expandedWidth;
public TransferControlView(Context context) {
this(context, null);
@@ -33,8 +50,18 @@ public class TransferControlView extends AnimatingToggle {
public TransferControlView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflate(context, R.layout.transfer_controls_view, this);
this.progressWheel = ViewUtil.findById(this, R.id.progress_wheel);
this.downloadButton = ViewUtil.findById(this, R.id.download_button);
setBackgroundResource(R.drawable.transfer_controls_background);
setVisibility(GONE);
this.progressWheel = ViewUtil.findById(this, R.id.progress_wheel);
this.downloadDetails = ViewUtil.findById(this, R.id.download_details);
this.contractedWidth = getResources().getDimensionPixelSize(R.dimen.transfer_controls_contracted_width);
this.expandedWidth = getResources().getDimensionPixelSize(R.dimen.transfer_controls_expanded_width);
this.outAnimation = new AlphaAnimation(1f, 0f);
this.inAnimation = new AlphaAnimation(0f, 1f);
this.outAnimation.setInterpolator(new FastOutSlowInInterpolator());
this.inAnimation.setInterpolator(new FastOutSlowInInterpolator());
this.outAnimation.setDuration(TRANSITION_MS);
this.inAnimation.setDuration(TRANSITION_MS);
}
@Override protected void onAttachedToWindow() {
@@ -49,13 +76,13 @@ public class TransferControlView extends AnimatingToggle {
public void setSlide(final @NonNull Slide slide) {
this.slide = slide;
if (slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_STARTED) {
showProgressSpinner();
} else if (slide.isPendingDownload()) {
display(downloadButton);
downloadDetails.setText(slide.getContentDescription());
display(downloadDetails);
} else {
display(null, false);
display(null);
}
}
@@ -65,12 +92,57 @@ public class TransferControlView extends AnimatingToggle {
}
public void setDownloadClickListener(final @Nullable OnClickListener listener) {
downloadButton.setOnClickListener(listener);
downloadDetails.setOnClickListener(listener);
}
public void clear() {
display(null, false);
slide = null;
clearAnimation();
setVisibility(GONE);
if (current != null) {
current.clearAnimation();
current.setVisibility(GONE);
}
current = null;
slide = null;
}
private void display(@Nullable final View view) {
final int sourceWidth = current == downloadDetails ? expandedWidth : contractedWidth;
final int targetWidth = view == downloadDetails ? expandedWidth : contractedWidth;
if (current == view || current == null) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.width = targetWidth;
setLayoutParams(layoutParams);
} else {
ViewUtil.animateOut(current, outAnimation);
Animator anim = getWidthAnimator(sourceWidth, targetWidth);
anim.start();
}
if (view == null) {
ViewUtil.animateOut(this, outAnimation);
} else {
ViewUtil.animateIn(this, inAnimation);
ViewUtil.animateIn(view, inAnimation);
}
current = view;
}
private Animator getWidthAnimator(final int from, final int to) {
final ValueAnimator anim = ValueAnimator.ofInt(from, to);
anim.addUpdateListener(new AnimatorUpdateListener() {
@Override public void onAnimationUpdate(ValueAnimator animation) {
final int val = (Integer)animation.getAnimatedValue();
final ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.width = val;
setLayoutParams(layoutParams);
}
});
anim.setInterpolator(new FastOutSlowInInterpolator());
anim.setDuration(TRANSITION_MS);
return anim;
}
@SuppressWarnings("unused")
@@ -79,7 +151,6 @@ public class TransferControlView extends AnimatingToggle {
Util.runOnMain(new Runnable() {
@Override public void run() {
progressWheel.setInstantProgress(((float)event.progress) / event.total);
if (event.progress >= event.total) display(null);
}
});
}