diff --git a/res/layout/thumbnail_view.xml b/res/layout/thumbnail_view.xml
index 80590293d..58b8325d1 100644
--- a/res/layout/thumbnail_view.xml
+++ b/res/layout/thumbnail_view.xml
@@ -9,23 +9,15 @@
android:contentDescription="@string/conversation_item__mms_image_description"
android:layout_margin="@dimen/media_bubble_border_width" />
-
+ android:layout="@layout/transfer_controls_stub" />
-
-
diff --git a/res/layout/thumbnail_view_progress_wheel.xml b/res/layout/thumbnail_view_progress_wheel.xml
deleted file mode 100644
index 6aeefdf7b..000000000
--- a/res/layout/thumbnail_view_progress_wheel.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
diff --git a/res/layout/transfer_controls_stub.xml b/res/layout/transfer_controls_stub.xml
new file mode 100644
index 000000000..63c6545c1
--- /dev/null
+++ b/res/layout/transfer_controls_stub.xml
@@ -0,0 +1,8 @@
+
+
+
diff --git a/res/layout/transfer_controls_view.xml b/res/layout/transfer_controls_view.xml
new file mode 100644
index 000000000..2a8888929
--- /dev/null
+++ b/res/layout/transfer_controls_view.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/components/AnimatingToggle.java b/src/org/thoughtcrime/securesms/components/AnimatingToggle.java
index 01f45faeb..03a13f73b 100644
--- a/src/org/thoughtcrime/securesms/components/AnimatingToggle.java
+++ b/src/org/thoughtcrime/securesms/components/AnimatingToggle.java
@@ -2,22 +2,19 @@ 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;
import android.view.animation.Animation;
-import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
-import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import org.thoughtcrime.securesms.R;
public class AnimatingToggle extends FrameLayout {
- private static final int SPEED_MILLIS = 200;
-
private View current;
public AnimatingToggle(Context context) {
@@ -45,11 +42,20 @@ public class AnimatingToggle extends FrameLayout {
child.setClickable(false);
}
- public void display(View view) {
+ public void display(@Nullable View view) {
+ display(view, true);
+ }
+
+ protected void display(@Nullable View view, boolean animated) {
if (view == current) return;
- animateOut(current, AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_out));
- animateIn(view, AnimationUtils.loadAnimation(getContext(), R.anim.animation_toggle_in));
+ 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);
+ }
current = view;
}
@@ -78,12 +84,4 @@ public class AnimatingToggle extends FrameLayout {
view.setVisibility(View.VISIBLE);
view.startAnimation(animation);
}
-
- private int getViewIndex(View view) {
- for (int i=0;i slideDeckFuture = null;
private SlideDeckListener slideDeckListener = null;
@@ -73,13 +65,8 @@ public class ThumbnailView extends FrameLayout {
public ThumbnailView(final Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inflate(context, R.layout.thumbnail_view, this);
- radius = getResources().getDimensionPixelSize(R.dimen.message_bubble_corner_radius);
- image = (ImageView) findViewById(R.id.thumbnail_image);
- progress = (ProgressWheel) findViewById(R.id.progress_wheel);
- downloadButton = (ImageButton) findViewById(R.id.download_button);
-
- setOnClickListener(new ThumbnailClickDispatcher());
- downloadButton.setOnClickListener(new DownloadClickDispatcher());
+ radius = getResources().getDimensionPixelSize(R.dimen.message_bubble_corner_radius);
+ image = (ImageView) findViewById(R.id.thumbnail_image);
if (attrs != null) {
TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ThumbnailView, 0, 0);
@@ -97,40 +84,15 @@ public class ThumbnailView extends FrameLayout {
}
}
- @Override protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().registerSticky(this);
- }
-
- @Override protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- EventBus.getDefault().unregister(this);
- }
-
- private ProgressWheel getProgressWheel() {
- if (progress == null) progress = ViewUtil.inflateStub(this, R.id.progress_wheel_stub);
- return progress;
- }
-
- private void hideProgressWheel() {
- if (progress != null) progress.setVisibility(GONE);
- }
-
private ImageView getRemoveButton() {
if (removeButton == null) removeButton = ViewUtil.inflateStub(this, R.id.remove_button_stub);
return removeButton;
}
- @SuppressWarnings("unused")
- public void onEventAsync(final PartProgressEvent event) {
- if (this.slide != null && event.partId.equals(this.slide.getPart().getPartId())) {
- Util.runOnMain(new Runnable() {
- @Override public void run() {
- getProgressWheel().setInstantProgress(((float)event.progress) / event.total);
- if (event.progress >= event.total) animateOutProgress();
- }
- });
- }
+ private TransferControlView getTransferControls() {
+ if (transferControls == null) transferControls = ViewUtil.inflateStub(this, R.id.transfer_controls_stub);
+
+ return transferControls;
}
public void setBackgroundColorHint(int color) {
@@ -148,7 +110,7 @@ public class ThumbnailView extends FrameLayout {
String slideId = id + "::" + timestamp;
if (!slideId.equals(this.slideId)) {
- hideProgressWheel();
+ if (transferControls != null) transferControls.clear();
image.setImageDrawable(null);
this.slide = null;
this.slideId = slideId;
@@ -170,22 +132,21 @@ public class ThumbnailView extends FrameLayout {
}
Log.w(TAG, "loading part with id " + slide.getPart().getPartId() + ", progress " + slide.getTransferProgress());
- if (!hideControls && slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_STARTED) {
- getProgressWheel().spin();
- getProgressWheel().setVisibility(VISIBLE);
- downloadButton.setVisibility(GONE);
- } else if (!hideControls && slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_AUTO_PENDING ||
- slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_FAILED)
- {
- hideProgressWheel();
- downloadButton.setVisibility(VISIBLE);
- } else {
- hideProgressWheel();
- downloadButton.setVisibility(GONE);
- }
this.slide = slide;
buildGlideRequest(slide, masterSecret).into(image);
+
+ if (this.slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_DONE) {
+ setOnClickListener(new ThumbnailClickDispatcher());
+ } else {
+ setOnClickListener(null);
+ }
+
+ if (!hideControls) {
+ getTransferControls().setSlide(slide);
+ getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
+ getTransferControls().setVisibility(View.VISIBLE);
+ }
}
public void setThumbnailClickListener(ThumbnailClickListener listener) {
@@ -201,8 +162,9 @@ public class ThumbnailView extends FrameLayout {
}
public void clear() {
- if (isContextValid()) Glide.clear(image);
- if (slideDeckFuture != null) slideDeckFuture.removeListener(slideDeckListener);
+ if (isContextValid()) Glide.clear(image);
+ if (slideDeckFuture != null) slideDeckFuture.removeListener(slideDeckListener);
+ if (transferControls != null) transferControls.clear();
slide = null;
slideId = null;
slideDeckFuture = null;
@@ -211,12 +173,11 @@ public class ThumbnailView extends FrameLayout {
public void hideControls(boolean hideControls) {
this.hideControls = hideControls;
- if (hideControls) hideProgressWheel();
+ if (hideControls && transferControls != null) transferControls.setVisibility(View.GONE);
}
public void showProgressSpinner() {
- getProgressWheel().spin();
- getProgressWheel().setVisibility(VISIBLE);
+ getTransferControls().showProgressSpinner();
}
@TargetApi(VERSION_CODES.JELLY_BEAN_MR1)
@@ -276,20 +237,6 @@ public class ThumbnailView extends FrameLayout {
.fitCenter();
}
- private void animateOutProgress() {
- if (progress == null) return;
- AlphaAnimation animation = new AlphaAnimation(1f, 0f);
- animation.setDuration(200);
- animation.setAnimationListener(new AnimationListener() {
- @Override public void onAnimationStart(Animation animation) { }
- @Override public void onAnimationRepeat(Animation animation) { }
- @Override public void onAnimationEnd(Animation animation) {
- getProgressWheel().setVisibility(View.GONE);
- }
- });
- getProgressWheel().startAnimation(animation);
- }
-
private class SlideDeckListener implements FutureTaskListener {
private final MasterSecret masterSecret;
diff --git a/src/org/thoughtcrime/securesms/components/TransferControlView.java b/src/org/thoughtcrime/securesms/components/TransferControlView.java
new file mode 100644
index 000000000..c2406e1b0
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/components/TransferControlView.java
@@ -0,0 +1,87 @@
+package org.thoughtcrime.securesms.components;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.widget.ImageButton;
+
+import com.pnikosis.materialishprogress.ProgressWheel;
+
+import org.thoughtcrime.securesms.R;
+import org.thoughtcrime.securesms.database.PartDatabase;
+import org.thoughtcrime.securesms.jobs.PartProgressEvent;
+import org.thoughtcrime.securesms.mms.Slide;
+import org.thoughtcrime.securesms.util.Util;
+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 TransferControlView(Context context) {
+ this(context, null);
+ }
+
+ public TransferControlView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ 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);
+ }
+
+ @Override protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().registerSticky(this);
+ }
+
+ @Override protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ EventBus.getDefault().unregister(this);
+ }
+
+ public void setSlide(final @NonNull Slide slide) {
+ this.slide = slide;
+
+ if (slide.getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_STARTED) {
+ showProgressSpinner();
+ } else if (slide.isPendingDownload()) {
+ display(downloadButton);
+ } else {
+ display(null, false);
+ }
+ }
+
+ public void showProgressSpinner() {
+ progressWheel.spin();
+ display(progressWheel);
+ }
+
+ public void setDownloadClickListener(final @Nullable OnClickListener listener) {
+ downloadButton.setOnClickListener(listener);
+ }
+
+ public void clear() {
+ display(null, false);
+ slide = null;
+ }
+
+ @SuppressWarnings("unused")
+ public void onEventAsync(final PartProgressEvent event) {
+ if (this.slide != null && event.partId.equals(this.slide.getPart().getPartId())) {
+ Util.runOnMain(new Runnable() {
+ @Override public void run() {
+ progressWheel.setInstantProgress(((float)event.progress) / event.total);
+ if (event.progress >= event.total) display(null);
+ }
+ });
+ }
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/mms/Slide.java b/src/org/thoughtcrime/securesms/mms/Slide.java
index 60e925576..f23ff2e65 100644
--- a/src/org/thoughtcrime/securesms/mms/Slide.java
+++ b/src/org/thoughtcrime/securesms/mms/Slide.java
@@ -25,6 +25,7 @@ import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.MediaUtil;
+import org.thoughtcrime.securesms.database.PartDatabase;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
@@ -74,6 +75,11 @@ public abstract class Slide {
return part.isInProgress();
}
+ public boolean isPendingDownload() {
+ return getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_FAILED ||
+ getTransferProgress() == PartDatabase.TRANSFER_PROGRESS_AUTO_PENDING;
+ }
+
public long getTransferProgress() {
return part.getTransferProgress();
}
diff --git a/src/org/thoughtcrime/securesms/util/ViewUtil.java b/src/org/thoughtcrime/securesms/util/ViewUtil.java
index 8e41190b8..9f82db662 100644
--- a/src/org/thoughtcrime/securesms/util/ViewUtil.java
+++ b/src/org/thoughtcrime/securesms/util/ViewUtil.java
@@ -68,4 +68,9 @@ public class ViewUtil {
public static T inflateStub(@NonNull View parent, @IdRes int stubId) {
return (T)((ViewStub)parent.findViewById(stubId)).inflate();
}
+
+ @SuppressWarnings("unchecked")
+ public static T findById(@NonNull View parent, @IdRes int resId) {
+ return (T) parent.findViewById(resId);
+ }
}