Added support for multi-image receive.

This commit is contained in:
Greyson Parrelli
2018-11-08 23:33:37 -08:00
parent e665252b86
commit 47a10a0288
55 changed files with 1277 additions and 186 deletions

View File

@@ -0,0 +1,159 @@
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.support.annotation.ColorInt;
import android.support.annotation.IdRes;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideClickListener;
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
import org.thoughtcrime.securesms.util.views.Stub;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class AlbumThumbnailView extends FrameLayout {
private @Nullable SlideClickListener thumbnailClickListener;
private @Nullable SlidesClickedListener downloadClickListener;
private int currentSizeClass;
private ViewGroup albumCellContainer;
private Stub<TransferControlView> transferControls;
private final SlideClickListener defaultThumbnailClickListener = (v, slide) -> {
if (thumbnailClickListener != null) {
thumbnailClickListener.onClick(v, slide);
}
};
private final OnLongClickListener defaultLongClickListener = v -> this.performLongClick();
public AlbumThumbnailView(@NonNull @android.support.annotation.NonNull Context context) {
super(context);
initialize();
}
public AlbumThumbnailView(@NonNull @android.support.annotation.NonNull Context context, @Nullable @android.support.annotation.Nullable AttributeSet attrs) {
super(context, attrs);
initialize();
}
private void initialize() {
inflate(getContext(), R.layout.album_thumbnail_view, this);
albumCellContainer = findViewById(R.id.album_cell_container);
transferControls = new Stub<>(findViewById(R.id.album_transfer_controls_stub));
}
public void setSlides(@NonNull GlideRequests glideRequests, @NonNull List<Slide> slides, boolean showControls) {
if (slides.size() < 2) {
throw new IllegalStateException("Provided less than two slides.");
}
if (showControls) {
transferControls.get().setShowDownloadText(true);
transferControls.get().setSlides(slides);
transferControls.get().setDownloadClickListener(v -> {
if (downloadClickListener != null) {
downloadClickListener.onClick(v, slides);
}
});
} else {
if (transferControls.resolved()) {
transferControls.get().setVisibility(GONE);
}
}
int sizeClass = sizeClass(slides.size());
if (sizeClass != currentSizeClass) {
inflateLayout(sizeClass);
currentSizeClass = sizeClass;
}
showSlides(glideRequests, slides);
}
public void setCellBackgroundColor(@ColorInt int color) {
ViewGroup cellRoot = findViewById(R.id.album_thumbnail_root);
if (cellRoot != null) {
for (int i = 0; i < cellRoot.getChildCount(); i++) {
cellRoot.getChildAt(i).setBackgroundColor(color);
}
}
}
public void setThumbnailClickListener(@Nullable SlideClickListener listener) {
thumbnailClickListener = listener;
}
public void setDownloadClickListener(@Nullable SlidesClickedListener listener) {
downloadClickListener = listener;
}
private void inflateLayout(int sizeClass) {
albumCellContainer.removeAllViews();
switch (sizeClass) {
case 2:
inflate(getContext(), R.layout.album_thumbnail_2, albumCellContainer);
break;
case 3:
inflate(getContext(), R.layout.album_thumbnail_3, albumCellContainer);
break;
case 4:
inflate(getContext(), R.layout.album_thumbnail_4, albumCellContainer);
break;
case 5:
inflate(getContext(), R.layout.album_thumbnail_5, albumCellContainer);
break;
default:
inflate(getContext(), R.layout.album_thumbnail_many, albumCellContainer);
break;
}
}
private void showSlides(@NonNull GlideRequests glideRequests, @NonNull List<Slide> slides) {
setSlide(glideRequests, slides.get(0), R.id.album_cell_1);
setSlide(glideRequests, slides.get(1), R.id.album_cell_2);
if (slides.size() >= 3) {
setSlide(glideRequests, slides.get(2), R.id.album_cell_3);
}
if (slides.size() >= 4) {
setSlide(glideRequests, slides.get(3), R.id.album_cell_4);
}
if (slides.size() >= 5) {
setSlide(glideRequests, slides.get(4), R.id.album_cell_5);
}
if (slides.size() > 5) {
TextView text = findViewById(R.id.album_cell_overflow_text);
text.setText(getContext().getString(R.string.AlbumThumbnailView_plus, slides.size() - 5));
}
}
private void setSlide(@NonNull GlideRequests glideRequests, @NonNull Slide slide, @IdRes int id) {
ThumbnailView cell = findViewById(id);
cell.setImageResource(glideRequests, slide, false, false);
cell.setThumbnailClickListener(defaultThumbnailClickListener);
cell.setOnLongClickListener(defaultLongClickListener);
}
private int sizeClass(int size) {
return Math.min(size, 6);
}
}

View File

@@ -3,11 +3,10 @@ package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
@@ -16,40 +15,36 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideClickListener;
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
import org.thoughtcrime.securesms.util.ThemeUtil;
import java.util.List;
public class ConversationItemThumbnail extends FrameLayout {
private static final String TAG = ConversationItemThumbnail.class.getSimpleName();
private static final Paint LIGHT_THEME_OUTLINE_PAINT = new Paint();
private static final Paint DARK_THEME_OUTLINE_PAINT = new Paint();
static {
LIGHT_THEME_OUTLINE_PAINT.setColor(Color.argb((int) (255 * 0.2), 0, 0, 0));
LIGHT_THEME_OUTLINE_PAINT.setStyle(Paint.Style.STROKE);
LIGHT_THEME_OUTLINE_PAINT.setStrokeWidth(1f);
LIGHT_THEME_OUTLINE_PAINT.setAntiAlias(true);
DARK_THEME_OUTLINE_PAINT.setColor(Color.argb((int) (255 * 0.2), 255, 255, 255));
DARK_THEME_OUTLINE_PAINT.setStyle(Paint.Style.STROKE);
DARK_THEME_OUTLINE_PAINT.setStrokeWidth(1f);
DARK_THEME_OUTLINE_PAINT.setAntiAlias(true);
}
private final float[] radii = new float[8];
private final RectF bounds = new RectF();
private final Path corners = new Path();
private final float[] radii = new float[8];
private final RectF bounds = new RectF();
private final Path corners = new Path();
private ThumbnailView thumbnail;
private AlbumThumbnailView album;
private ImageView shade;
private ConversationItemFooter footer;
private Paint outlinePaint;
private CornerMask cornerMask;
private final Paint outlinePaint = new Paint();
{
outlinePaint.setStyle(Paint.Style.STROKE);
outlinePaint.setStrokeWidth(1f);
outlinePaint.setAntiAlias(true);
}
public ConversationItemThumbnail(Context context) {
super(context);
init(null);
@@ -68,13 +63,13 @@ public class ConversationItemThumbnail extends FrameLayout {
private void init(@Nullable AttributeSet attrs) {
inflate(getContext(), R.layout.conversation_item_thumbnail, this);
this.thumbnail = findViewById(R.id.conversation_thumbnail_image);
this.shade = findViewById(R.id.conversation_thumbnail_shade);
this.footer = findViewById(R.id.conversation_thumbnail_footer);
this.outlinePaint = ThemeUtil.isDarkTheme(getContext()) ? DARK_THEME_OUTLINE_PAINT : LIGHT_THEME_OUTLINE_PAINT;
this.cornerMask = new CornerMask(this);
outlinePaint.setColor(ThemeUtil.getThemedColor(getContext(), R.attr.conversation_item_image_outline_color));
setTouchDelegate(thumbnail.getTouchDelegate());
this.thumbnail = findViewById(R.id.conversation_thumbnail_image);
this.album = findViewById(R.id.conversation_thumbnail_album);
this.shade = findViewById(R.id.conversation_thumbnail_shade);
this.footer = findViewById(R.id.conversation_thumbnail_footer);
this.cornerMask = new CornerMask(this);
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ConversationItemThumbnail, 0, 0);
@@ -99,32 +94,37 @@ public class ConversationItemThumbnail extends FrameLayout {
cornerMask.mask(canvas);
}
final float halfStrokeWidth = outlinePaint.getStrokeWidth() / 2;
if (album.getVisibility() != VISIBLE) {
final float halfStrokeWidth = outlinePaint.getStrokeWidth() / 2;
bounds.left = halfStrokeWidth;
bounds.top = halfStrokeWidth;
bounds.right = canvas.getWidth() - halfStrokeWidth;
bounds.bottom = canvas.getHeight() - halfStrokeWidth;
bounds.left = halfStrokeWidth;
bounds.top = halfStrokeWidth;
bounds.right = canvas.getWidth() - halfStrokeWidth;
bounds.bottom = canvas.getHeight() - halfStrokeWidth;
corners.reset();
corners.addRoundRect(bounds, radii, Path.Direction.CW);
corners.reset();
corners.addRoundRect(bounds, radii, Path.Direction.CW);
canvas.drawPath(corners, outlinePaint);
canvas.drawPath(corners, outlinePaint);
}
}
@Override
public void setFocusable(boolean focusable) {
thumbnail.setFocusable(focusable);
album.setFocusable(focusable);
}
@Override
public void setClickable(boolean clickable) {
thumbnail.setClickable(clickable);
album.setClickable(clickable);
}
@Override
public void setOnLongClickListener(@Nullable OnLongClickListener l) {
thumbnail.setOnLongClickListener(l);
album.setOnLongClickListener(l);
}
public void showShade(boolean show) {
@@ -146,37 +146,38 @@ public class ConversationItemThumbnail extends FrameLayout {
}
@UiThread
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull Slide slide,
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull List<Slide> slides,
boolean showControls, boolean isPreview)
{
thumbnail.setImageResource(glideRequests, slide, showControls, isPreview);
if (slides.size() == 1) {
thumbnail.setVisibility(VISIBLE);
album.setVisibility(GONE);
Attachment attachment = slides.get(0).asAttachment();
thumbnail.setImageResource(glideRequests, slides.get(0), showControls, isPreview, attachment.getWidth(), attachment.getHeight());
setTouchDelegate(thumbnail.getTouchDelegate());
} else {
thumbnail.setVisibility(GONE);
album.setVisibility(VISIBLE);
album.setSlides(glideRequests, slides, showControls);
setTouchDelegate(album.getTouchDelegate());
}
}
@UiThread
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull Slide slide,
boolean showControls, boolean isPreview, int naturalWidth,
int naturalHeight)
{
thumbnail.setImageResource(glideRequests, slide, showControls, isPreview, naturalWidth, naturalHeight);
}
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull Uri uri) {
thumbnail.setImageResource(glideRequests, uri);
public void setConversationColor(@ColorInt int color) {
if (album.getVisibility() == VISIBLE) {
album.setCellBackgroundColor(color);
}
}
public void setThumbnailClickListener(SlideClickListener listener) {
thumbnail.setThumbnailClickListener(listener);
album.setThumbnailClickListener(listener);
}
public void setDownloadClickListener(SlideClickListener listener) {
public void setDownloadClickListener(SlidesClickedListener listener) {
thumbnail.setDownloadClickListener(listener);
}
public void clear(GlideRequests glideRequests) {
thumbnail.clear(glideRequests);
}
public void showProgressSpinner() {
thumbnail.showProgressSpinner();
album.setDownloadClickListener(listener);
}
}

View File

@@ -0,0 +1,42 @@
package org.thoughtcrime.securesms.components;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ScrollView;
import org.thoughtcrime.securesms.R;
public class MaxHeightScrollView extends ScrollView {
private int maxHeight = -1;
public MaxHeightScrollView(Context context) {
super(context);
initialize(null);
}
public MaxHeightScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(attrs);
}
private void initialize(@Nullable AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.MaxHeightScrollView, 0, 0);
maxHeight = typedArray.getDimensionPixelOffset(R.styleable.MaxHeightScrollView_scrollView_maxHeight, -1);
typedArray.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (maxHeight >= 0) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

View File

@@ -11,6 +11,7 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.mms.GlideRequests;
@@ -81,6 +82,19 @@ public class MediaView extends FrameLayout {
}
}
public void hideControls() {
if (this.videoView.resolved()){
this.videoView.get().hideControls();
}
}
public @Nullable View getPlaybackControls() {
if (this.videoView.resolved()){
return this.videoView.get().getControlView();
}
return null;
}
public void cleanup() {
this.imageView.cleanup();
if (this.videoView.resolved()) {

View File

@@ -27,12 +27,14 @@ import org.thoughtcrime.securesms.mms.GlideRequest;
import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideClickListener;
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
import org.whispersystems.libsignal.util.guava.Optional;
import java.util.Collections;
import java.util.Locale;
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
@@ -49,6 +51,7 @@ public class ThumbnailView extends FrameLayout {
private ImageView image;
private View playOverlay;
private View captionIcon;
private OnClickListener parentClickListener;
private final int[] dimens = new int[2];
@@ -57,7 +60,7 @@ public class ThumbnailView extends FrameLayout {
private Optional<TransferControlView> transferControls = Optional.absent();
private SlideClickListener thumbnailClickListener = null;
private SlideClickListener downloadClickListener = null;
private SlidesClickedListener downloadClickListener = null;
private Slide slide = null;
private int radius;
@@ -77,6 +80,7 @@ public class ThumbnailView extends FrameLayout {
this.image = findViewById(R.id.thumbnail_image);
this.playOverlay = findViewById(R.id.play_overlay);
this.captionIcon = findViewById(R.id.thumbnail_caption_icon);
super.setOnClickListener(new ThumbnailClickDispatcher());
if (attrs != null) {
@@ -230,8 +234,8 @@ public class ThumbnailView extends FrameLayout {
@UiThread
public ListenableFuture<Boolean> setImageResource(@NonNull GlideRequests glideRequests, @NonNull Slide slide,
boolean showControls, boolean isPreview, int naturalWidth,
int naturalHeight)
boolean showControls, boolean isPreview,
int naturalWidth, int naturalHeight)
{
if (showControls) {
getTransferControls().setSlide(slide);
@@ -267,6 +271,8 @@ public class ThumbnailView extends FrameLayout {
this.slide = slide;
this.captionIcon.setVisibility(slide.getCaption().isPresent() ? VISIBLE : GONE);
dimens[WIDTH] = naturalWidth;
dimens[HEIGHT] = naturalHeight;
invalidate();
@@ -302,7 +308,7 @@ public class ThumbnailView extends FrameLayout {
this.thumbnailClickListener = listener;
}
public void setDownloadClickListener(SlideClickListener listener) {
public void setDownloadClickListener(SlidesClickedListener listener) {
this.downloadClickListener = listener;
}
@@ -342,8 +348,14 @@ public class ThumbnailView extends FrameLayout {
size[WIDTH] = getDefaultWidth();
size[HEIGHT] = getDefaultHeight();
}
return request.override(size[WIDTH], size[HEIGHT])
.transforms(fitting, new RoundedCorners(radius));
request = request.override(size[WIDTH], size[HEIGHT]);
if (radius > 0) {
return request.transforms(fitting, new RoundedCorners(radius));
} else {
return request.transforms(fitting);
}
}
private int getDefaultWidth() {
@@ -382,7 +394,7 @@ public class ThumbnailView extends FrameLayout {
public void onClick(View view) {
Log.i(TAG, "onClick() for download button");
if (downloadClickListener != null && slide != null) {
downloadClickListener.onClick(view, slide);
downloadClickListener.onClick(view, Collections.singletonList(slide));
} else {
Log.w(TAG, "Received a download button click, but unable to execute it. slide: " + String.valueOf(slide) + " downloadClickListener: " + String.valueOf(downloadClickListener));
}

View File

@@ -15,32 +15,42 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.annimon.stream.Stream;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;
import com.pnikosis.materialishprogress.ProgressWheel;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.events.PartProgressEvent;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TransferControlView extends FrameLayout {
private static final int TRANSITION_MS = 300;
@Nullable private Slide slide;
@Nullable private View current;
@Nullable private List<Slide> slides;
@Nullable private View current;
private final ProgressWheel progressWheel;
private final TextView downloadDetails;
private final View downloadDetails;
private final TextView downloadDetailsText;
private final int contractedWidth;
private final int expandedWidth;
private final Map<Attachment, Float> downloadProgress;
public TransferControlView(Context context) {
this(context, null);
}
@@ -61,10 +71,12 @@ public class TransferControlView extends FrameLayout {
ViewUtil.setBackground(this, 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.downloadProgress = new HashMap<>();
this.progressWheel = ViewUtil.findById(this, R.id.progress_wheel);
this.downloadDetails = ViewUtil.findById(this, R.id.download_details);
this.downloadDetailsText = ViewUtil.findById(this, R.id.download_details_text);
this.contractedWidth = getResources().getDimensionPixelSize(R.dimen.transfer_controls_contracted_width);
this.expandedWidth = getResources().getDimensionPixelSize(R.dimen.transfer_controls_expanded_width);
}
@Override
@@ -91,20 +103,54 @@ public class TransferControlView extends FrameLayout {
EventBus.getDefault().unregister(this);
}
public void setSlide(final @NonNull Slide slide) {
this.slide = slide;
if (slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_STARTED) {
showProgressSpinner();
} else if (slide.isPendingDownload()) {
downloadDetails.setText(slide.getContentDescription());
display(downloadDetails);
public void setSlide(final @NonNull Slide slides) {
setSlides(Collections.singletonList(slides));
}
public void setSlides(final @NonNull List<Slide> slides) {
if (slides.isEmpty()) {
throw new IllegalArgumentException("Must provide at least one slide.");
}
this.slides = slides;
if (!isUpdateToExistingSet(slides)) {
downloadProgress.clear();
Stream.of(slides).forEach(s -> downloadProgress.put(s.asAttachment(), 0f));
} else {
display(null);
for (Slide slide : slides) {
if (slide.asAttachment().getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
downloadProgress.put(slide.asAttachment(), 1f);
}
}
}
switch (getTransferState(slides)) {
case AttachmentDatabase.TRANSFER_PROGRESS_STARTED:
showProgressSpinner(calculateProgress(downloadProgress));
break;
case AttachmentDatabase.TRANSFER_PROGRESS_PENDING:
case AttachmentDatabase.TRANSFER_PROGRESS_FAILED:
downloadDetailsText.setText(getDownloadText(this.slides));
display(downloadDetails);
break;
default:
display(null);
break;
}
}
public void showProgressSpinner() {
progressWheel.spin();
showProgressSpinner(calculateProgress(downloadProgress));
}
public void showProgressSpinner(float progress) {
if (progress == 0) {
progressWheel.spin();
} else {
progressWheel.setInstantProgress(progress);
}
display(progressWheel);
}
@@ -120,12 +166,51 @@ public class TransferControlView extends FrameLayout {
current.setVisibility(GONE);
}
current = null;
slide = null;
slides = null;
}
public void setShowDownloadText(boolean showDownloadText) {
downloadDetailsText.setVisibility(showDownloadText ? VISIBLE : GONE);
}
private boolean isUpdateToExistingSet(@NonNull List<Slide> slides) {
if (slides.size() != downloadProgress.size()) {
return false;
}
for (Slide slide : slides) {
if (!downloadProgress.containsKey(slide.asAttachment())) {
return false;
}
}
return true;
}
private int getTransferState(@NonNull List<Slide> slides) {
int transferState = AttachmentDatabase.TRANSFER_PROGRESS_DONE;
for (Slide slide : slides) {
if (slide.getTransferState() == AttachmentDatabase.TRANSFER_PROGRESS_PENDING && transferState == AttachmentDatabase.TRANSFER_PROGRESS_DONE) {
transferState = slide.getTransferState();
} else {
transferState = Math.max(transferState, slide.getTransferState());
}
}
return transferState;
}
private String getDownloadText(@NonNull List<Slide> slides) {
if (slides.size() == 1) {
return slides.get(0).getContentDescription();
} else {
int downloadCount = Stream.of(slides).reduce(0, (count, slide) -> slide.getTransferState() != AttachmentDatabase.TRANSFER_PROGRESS_DONE ? count + 1 : count);
return getContext().getResources().getQuantityString(R.plurals.TransferControlView_n_items, downloadCount, downloadCount);
}
}
private void display(@Nullable final View view) {
final int sourceWidth = current == downloadDetails ? expandedWidth : contractedWidth;
final int targetWidth = view == downloadDetails ? expandedWidth : contractedWidth;
final int sourceWidth = (current == downloadDetails && downloadDetailsText.getVisibility() == VISIBLE) ? expandedWidth : contractedWidth;
final int targetWidth = (view == downloadDetails && downloadDetailsText.getVisibility() == VISIBLE) ? expandedWidth : contractedWidth;
if (current == view || current == null) {
ViewGroup.LayoutParams layoutParams = getLayoutParams();
@@ -149,28 +234,31 @@ public class TransferControlView extends FrameLayout {
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.addUpdateListener(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;
}
private float calculateProgress(@NonNull Map<Attachment, Float> downloadProgress) {
float totalProgress = 0;
for (float progress : downloadProgress.values()) {
totalProgress += progress / downloadProgress.size();
}
return totalProgress;
}
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
public void onEventAsync(final PartProgressEvent event) {
if (this.slide != null && event.attachment.equals(this.slide.asAttachment())) {
Util.runOnMain(new Runnable() {
@Override
public void run() {
progressWheel.setInstantProgress(((float)event.progress) / event.total);
}
if (downloadProgress.containsKey(event.attachment)) {
Util.runOnMain(() -> {
downloadProgress.put(event.attachment, ((float)event.progress) / event.total);
progressWheel.setInstantProgress(calculateProgress(downloadProgress));
});
}
}