mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-21 17:29:32 +01:00
Fix stub of TransferControlsView.
This commit is contained in:
committed by
Greyson Parrelli
parent
1b49b9bffb
commit
5cf937215a
@@ -4,6 +4,8 @@ import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcelable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -22,6 +24,7 @@ import org.thoughtcrime.securesms.mms.ImageSlide;
|
||||
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.thoughtcrime.securesms.util.views.Stub;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -34,23 +37,27 @@ import okhttp3.HttpUrl;
|
||||
*/
|
||||
public class LinkPreviewView extends FrameLayout {
|
||||
|
||||
private static final String STATE_ROOT = "linkPreviewView.state.root";
|
||||
private static final String STATE_STATE = "linkPreviewView.state.state";
|
||||
|
||||
private static final int TYPE_CONVERSATION = 0;
|
||||
private static final int TYPE_COMPOSE = 1;
|
||||
|
||||
private ViewGroup container;
|
||||
private OutlinedThumbnailView thumbnail;
|
||||
private TextView title;
|
||||
private TextView description;
|
||||
private TextView site;
|
||||
private View divider;
|
||||
private View closeButton;
|
||||
private View spinner;
|
||||
private TextView noPreview;
|
||||
private ViewGroup container;
|
||||
private Stub<OutlinedThumbnailView> thumbnail;
|
||||
private TextView title;
|
||||
private TextView description;
|
||||
private TextView site;
|
||||
private View divider;
|
||||
private View closeButton;
|
||||
private View spinner;
|
||||
private TextView noPreview;
|
||||
|
||||
private int type;
|
||||
private int defaultRadius;
|
||||
private CornerMask cornerMask;
|
||||
private CloseClickedListener closeClickedListener;
|
||||
private int type;
|
||||
private int defaultRadius;
|
||||
private CornerMask cornerMask;
|
||||
private CloseClickedListener closeClickedListener;
|
||||
private LinkPreviewViewThumbnailState thumbnailState = new LinkPreviewViewThumbnailState();
|
||||
|
||||
public LinkPreviewView(Context context) {
|
||||
super(context);
|
||||
@@ -66,7 +73,7 @@ public class LinkPreviewView extends FrameLayout {
|
||||
inflate(getContext(), R.layout.link_preview, this);
|
||||
|
||||
container = findViewById(R.id.linkpreview_container);
|
||||
thumbnail = findViewById(R.id.linkpreview_thumbnail);
|
||||
thumbnail = new Stub<>(findViewById(R.id.linkpreview_thumbnail));
|
||||
title = findViewById(R.id.linkpreview_title);
|
||||
description = findViewById(R.id.linkpreview_description);
|
||||
site = findViewById(R.id.linkpreview_site);
|
||||
@@ -101,6 +108,30 @@ public class LinkPreviewView extends FrameLayout {
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull Parcelable onSaveInstanceState() {
|
||||
Parcelable root = super.onSaveInstanceState();
|
||||
Bundle bundle = new Bundle();
|
||||
|
||||
bundle.putParcelable(STATE_ROOT, root);
|
||||
bundle.putParcelable(STATE_STATE, thumbnailState);
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Parcelable state) {
|
||||
if (state instanceof Bundle) {
|
||||
Parcelable root = ((Bundle) state).getParcelable(STATE_ROOT);
|
||||
thumbnailState = ((Bundle) state).getParcelable(STATE_STATE);
|
||||
|
||||
thumbnailState.applyState(thumbnail);
|
||||
super.onRestoreInstanceState(root);
|
||||
} else {
|
||||
super.onRestoreInstanceState(state);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
@@ -173,8 +204,9 @@ public class LinkPreviewView extends FrameLayout {
|
||||
|
||||
if (showThumbnail && linkPreview.getThumbnail().isPresent()) {
|
||||
thumbnail.setVisibility(VISIBLE);
|
||||
thumbnail.setImageResource(glideRequests, new ImageSlide(getContext(), linkPreview.getThumbnail().get()), type == TYPE_CONVERSATION, false);
|
||||
thumbnail.showDownloadText(false);
|
||||
thumbnailState.applyState(thumbnail);
|
||||
thumbnail.get().setImageResource(glideRequests, new ImageSlide(getContext(), linkPreview.getThumbnail().get()), type == TYPE_CONVERSATION, false);
|
||||
thumbnail.get().showDownloadText(false);
|
||||
} else {
|
||||
thumbnail.setVisibility(GONE);
|
||||
}
|
||||
@@ -183,10 +215,24 @@ public class LinkPreviewView extends FrameLayout {
|
||||
public void setCorners(int topStart, int topEnd) {
|
||||
if (ViewUtil.isRtl(this)) {
|
||||
cornerMask.setRadii(topEnd, topStart, 0, 0);
|
||||
thumbnail.setCorners(defaultRadius, topEnd, defaultRadius, defaultRadius);
|
||||
thumbnailState = thumbnailState.copy(
|
||||
defaultRadius,
|
||||
topEnd,
|
||||
defaultRadius,
|
||||
defaultRadius,
|
||||
thumbnailState.getDownloadListener()
|
||||
);
|
||||
thumbnailState.applyState(thumbnail);
|
||||
} else {
|
||||
cornerMask.setRadii(topStart, topEnd, 0, 0);
|
||||
thumbnail.setCorners(topStart, defaultRadius, defaultRadius, defaultRadius);
|
||||
thumbnailState.copy(
|
||||
topStart,
|
||||
defaultRadius,
|
||||
defaultRadius,
|
||||
defaultRadius,
|
||||
thumbnailState.getDownloadListener()
|
||||
);
|
||||
thumbnailState.applyState(thumbnail);
|
||||
}
|
||||
postInvalidate();
|
||||
}
|
||||
@@ -196,7 +242,8 @@ public class LinkPreviewView extends FrameLayout {
|
||||
}
|
||||
|
||||
public void setDownloadClickedListener(SlidesClickedListener listener) {
|
||||
thumbnail.setDownloadClickListener(listener);
|
||||
thumbnailState = thumbnailState.withDownloadListener(listener);
|
||||
thumbnailState.applyState(thumbnail);
|
||||
}
|
||||
|
||||
private @StringRes static int getLinkPreviewErrorString(@Nullable LinkPreviewRepository.Error customError) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.IgnoredOnParcel
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.thoughtcrime.securesms.mms.SlidesClickedListener
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
|
||||
@Parcelize
|
||||
data class LinkPreviewViewThumbnailState(
|
||||
val cornerTopLeft: Int = 0,
|
||||
val cornerTopRight: Int = 0,
|
||||
val cornerBottomRight: Int = 0,
|
||||
val cornerBottomLeft: Int = 0,
|
||||
@IgnoredOnParcel
|
||||
val downloadListener: SlidesClickedListener? = null
|
||||
) : Parcelable {
|
||||
fun withDownloadListener(downloadListener: SlidesClickedListener?): LinkPreviewViewThumbnailState {
|
||||
return copy(downloadListener = downloadListener)
|
||||
}
|
||||
|
||||
fun applyState(thumbnail: Stub<OutlinedThumbnailView>) {
|
||||
if (thumbnail.resolved()) {
|
||||
thumbnail.get().setCorners(cornerTopLeft, cornerTopRight, cornerBottomRight, cornerBottomLeft)
|
||||
thumbnail.get().setDownloadClickListener(downloadListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ 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.thoughtcrime.securesms.util.views.Stub;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
@@ -79,11 +80,11 @@ public class ThumbnailView extends FrameLayout {
|
||||
|
||||
private final CornerMask cornerMask;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
private Optional<TransferControlView> transferControls = Optional.empty();
|
||||
private SlideClickListener thumbnailClickListener = null;
|
||||
private SlidesClickedListener downloadClickListener = null;
|
||||
private Slide slide = null;
|
||||
private ThumbnailViewTransferControlsState transferControlsState = new ThumbnailViewTransferControlsState();
|
||||
private Stub<TransferControlView> transferControlViewStub;
|
||||
private SlideClickListener thumbnailClickListener = null;
|
||||
private SlidesClickedListener downloadClickListener = null;
|
||||
private Slide slide = null;
|
||||
|
||||
|
||||
public ThumbnailView(Context context) {
|
||||
@@ -99,12 +100,13 @@ public class ThumbnailView extends FrameLayout {
|
||||
|
||||
inflate(context, R.layout.thumbnail_view, this);
|
||||
|
||||
this.image = findViewById(R.id.thumbnail_image);
|
||||
this.blurHash = findViewById(R.id.thumbnail_blurhash);
|
||||
this.playOverlay = findViewById(R.id.play_overlay);
|
||||
this.captionIcon = findViewById(R.id.thumbnail_caption_icon);
|
||||
this.errorImage = findViewById(R.id.thumbnail_error);
|
||||
this.cornerMask = new CornerMask(this);
|
||||
this.image = findViewById(R.id.thumbnail_image);
|
||||
this.blurHash = findViewById(R.id.thumbnail_blurhash);
|
||||
this.playOverlay = findViewById(R.id.play_overlay);
|
||||
this.captionIcon = findViewById(R.id.thumbnail_caption_icon);
|
||||
this.errorImage = findViewById(R.id.thumbnail_error);
|
||||
this.cornerMask = new CornerMask(this);
|
||||
this.transferControlViewStub = new Stub<>(findViewById(R.id.transfer_controls_stub));
|
||||
|
||||
super.setOnClickListener(new ThumbnailClickDispatcher());
|
||||
|
||||
@@ -275,26 +277,21 @@ public class ThumbnailView extends FrameLayout {
|
||||
@Override
|
||||
public void setFocusable(boolean focusable) {
|
||||
super.setFocusable(focusable);
|
||||
transferControls.ifPresent(transferControlView -> transferControlView.setFocusable(focusable));
|
||||
transferControlsState = transferControlsState.withFocusable(focusable);
|
||||
transferControlsState.applyState(transferControlViewStub);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClickable(boolean clickable) {
|
||||
super.setClickable(clickable);
|
||||
transferControls.ifPresent(transferControlView -> transferControlView.setClickable(clickable));
|
||||
transferControlsState = transferControlsState.withClickable(clickable);
|
||||
transferControlsState.applyState(transferControlViewStub);
|
||||
}
|
||||
|
||||
public @Nullable Drawable getImageDrawable() {
|
||||
return image.getDrawable();
|
||||
}
|
||||
|
||||
private TransferControlView getTransferControls() {
|
||||
if (!transferControls.isPresent()) {
|
||||
transferControls = Optional.of(ViewUtil.inflateStub(this, R.id.transfer_controls_stub));
|
||||
}
|
||||
return transferControls.get();
|
||||
}
|
||||
|
||||
public void setBounds(int minWidth, int maxWidth, int minHeight, int maxHeight) {
|
||||
bounds[MIN_WIDTH] = minWidth;
|
||||
bounds[MAX_WIDTH] = maxWidth;
|
||||
@@ -327,7 +324,7 @@ public class ThumbnailView extends FrameLayout {
|
||||
if (slide.asAttachment().isPermanentlyFailed()) {
|
||||
this.slide = slide;
|
||||
|
||||
transferControls.ifPresent(c -> c.setVisibility(View.GONE));
|
||||
transferControlViewStub.setVisibility(View.GONE);
|
||||
playOverlay.setVisibility(View.GONE);
|
||||
|
||||
glideRequests.clear(blurHash);
|
||||
@@ -353,10 +350,18 @@ public class ThumbnailView extends FrameLayout {
|
||||
}
|
||||
|
||||
if (showControls) {
|
||||
getTransferControls().setSlide(slide);
|
||||
getTransferControls().setDownloadClickListener(new DownloadClickDispatcher());
|
||||
} else if (transferControls.isPresent()) {
|
||||
getTransferControls().setVisibility(View.GONE);
|
||||
int transferState = TransferControlView.getTransferState(Collections.singletonList(slide));
|
||||
if (transferState == AttachmentTable.TRANSFER_PROGRESS_DONE || transferState == AttachmentTable.TRANSFER_PROGRESS_PERMANENT_FAILURE) {
|
||||
transferControlViewStub.setVisibility(View.GONE);
|
||||
} else {
|
||||
transferControlViewStub.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
transferControlsState = transferControlsState.withSlide(slide)
|
||||
.withDownloadClickListener(new DownloadClickDispatcher());
|
||||
transferControlsState.applyState(transferControlViewStub);
|
||||
} else {
|
||||
transferControlViewStub.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (slide.getUri() != null && slide.hasPlayOverlay() &&
|
||||
@@ -440,7 +445,7 @@ public class ThumbnailView extends FrameLayout {
|
||||
public ListenableFuture<Boolean> setImageResource(@NonNull GlideRequests glideRequests, @NonNull Uri uri, int width, int height, boolean animate, @Nullable ThumbnailRequestListener listener) {
|
||||
SettableFuture<Boolean> future = new SettableFuture<>();
|
||||
|
||||
if (transferControls.isPresent()) getTransferControls().setVisibility(View.GONE);
|
||||
transferControlViewStub.setVisibility(View.GONE);
|
||||
|
||||
GlideRequest<Drawable> request = glideRequests.load(new DecryptableUri(uri))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
@@ -473,7 +478,7 @@ public class ThumbnailView extends FrameLayout {
|
||||
public ListenableFuture<Boolean> setImageResource(@NonNull GlideRequests glideRequests, @NonNull StoryTextPostModel model, int width, int height) {
|
||||
SettableFuture<Boolean> future = new SettableFuture<>();
|
||||
|
||||
if (transferControls.isPresent()) getTransferControls().setVisibility(View.GONE);
|
||||
transferControlViewStub.setVisibility(View.GONE);
|
||||
|
||||
GlideRequest<Drawable> request = glideRequests.load(model)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
@@ -502,8 +507,8 @@ public class ThumbnailView extends FrameLayout {
|
||||
glideRequests.clear(image);
|
||||
image.setImageDrawable(null);
|
||||
|
||||
if (transferControls.isPresent()) {
|
||||
getTransferControls().clear();
|
||||
if (transferControlViewStub.resolved()) {
|
||||
transferControlViewStub.get().clear();
|
||||
}
|
||||
|
||||
glideRequests.clear(blurHash);
|
||||
@@ -513,11 +518,12 @@ public class ThumbnailView extends FrameLayout {
|
||||
}
|
||||
|
||||
public void showDownloadText(boolean showDownloadText) {
|
||||
getTransferControls().setShowDownloadText(showDownloadText);
|
||||
transferControlsState = transferControlsState.withDownloadText(showDownloadText);
|
||||
transferControlsState.applyState(transferControlViewStub);
|
||||
}
|
||||
|
||||
public void showProgressSpinner() {
|
||||
getTransferControls().showProgressSpinner();
|
||||
transferControlViewStub.get().showProgressSpinner();
|
||||
}
|
||||
|
||||
public void setScaleType(@NonNull ImageView.ScaleType scaleType) {
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.view.View.OnClickListener
|
||||
import org.thoughtcrime.securesms.mms.Slide
|
||||
import org.thoughtcrime.securesms.util.views.Stub
|
||||
|
||||
/**
|
||||
* State object for transfer controls.
|
||||
*/
|
||||
data class ThumbnailViewTransferControlsState(
|
||||
val isFocusable: Boolean = true,
|
||||
val isClickable: Boolean = true,
|
||||
val slide: Slide? = null,
|
||||
val downloadClickedListener: OnClickListener? = null,
|
||||
val showDownloadText: Boolean = true
|
||||
) {
|
||||
|
||||
fun withFocusable(isFocusable: Boolean): ThumbnailViewTransferControlsState = copy(isFocusable = isFocusable)
|
||||
fun withClickable(isClickable: Boolean): ThumbnailViewTransferControlsState = copy(isClickable = isClickable)
|
||||
fun withSlide(slide: Slide?): ThumbnailViewTransferControlsState = copy(slide = slide)
|
||||
fun withDownloadClickListener(downloadClickedListener: OnClickListener): ThumbnailViewTransferControlsState = copy(downloadClickedListener = downloadClickedListener)
|
||||
fun withDownloadText(showDownloadText: Boolean): ThumbnailViewTransferControlsState = copy(showDownloadText = showDownloadText)
|
||||
|
||||
fun applyState(transferControlView: Stub<TransferControlView>) {
|
||||
if (transferControlView.resolved()) {
|
||||
transferControlView.get().isFocusable = isFocusable
|
||||
transferControlView.get().isClickable = isClickable
|
||||
if (slide != null) {
|
||||
transferControlView.get().setSlide(slide)
|
||||
}
|
||||
transferControlView.get().setDownloadClickListener(downloadClickedListener)
|
||||
transferControlView.get().setShowDownloadText(showDownloadText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,7 @@ public final class TransferControlView extends FrameLayout {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getTransferState(@NonNull List<Slide> slides) {
|
||||
static int getTransferState(@NonNull List<Slide> slides) {
|
||||
int transferState = AttachmentTable.TRANSFER_PROGRESS_DONE;
|
||||
boolean allFailed = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user