diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreview.java b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreview.java index 7784d2ae3..820fdc0e5 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreview.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreview.java @@ -11,7 +11,7 @@ import android.view.LayoutInflater; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.R; -import java.util.List; +import java.util.Collection; import static android.content.Context.LAYOUT_INFLATER_SERVICE; import static android.support.v4.content.ContextCompat.getColor; @@ -60,7 +60,7 @@ public class ImagePreview extends ConstraintLayout { this.listener = listener; } - void showPreview(List imageUris) { + void showPreview(Collection imageUris) { if (listener == null) throw new IllegalStateException(); if (imageUris.size() == 1) { LayoutParams params = (LayoutParams) imageList.getLayoutParams(); @@ -71,7 +71,14 @@ public class ImagePreview extends ConstraintLayout { imageList.setAdapter(new ImagePreviewAdapter(imageUris, listener)); } + void removeUri(Uri uri) { + ImagePreviewAdapter adapter = + (ImagePreviewAdapter) imageList.getAdapter(); + requireNonNull(adapter).removeUri(uri); + } + interface ImagePreviewListener { + void onUriError(Uri uri); void onCancel(); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewAdapter.java b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewAdapter.java index 057d6e229..8f9238487 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewAdapter.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewAdapter.java @@ -11,6 +11,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.R; import org.briarproject.briar.android.view.ImagePreview.ImagePreviewListener; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import static java.util.Objects.requireNonNull; @@ -23,8 +25,9 @@ class ImagePreviewAdapter extends Adapter { @LayoutRes private final int layout; - public ImagePreviewAdapter(List items, ImagePreviewListener listener) { - this.items = items; + public ImagePreviewAdapter(Collection items, + ImagePreviewListener listener) { + this.items = new ArrayList<>(items); this.listener = listener; this.layout = items.size() == 1 ? R.layout.list_item_image_preview_single : @@ -35,8 +38,7 @@ class ImagePreviewAdapter extends Adapter { public ImagePreviewViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) { View v = LayoutInflater.from(viewGroup.getContext()) .inflate(layout, viewGroup, false); - return new ImagePreviewViewHolder(v, items.size() == 1, - requireNonNull(listener)); + return new ImagePreviewViewHolder(v, requireNonNull(listener)); } @Override @@ -49,4 +51,10 @@ class ImagePreviewAdapter extends Adapter { return items.size(); } + void removeUri(Uri uri) { + int pos = items.indexOf(uri); + items.remove(uri); + notifyItemRemoved(pos); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewViewHolder.java index 9db3ea118..d63569024 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewViewHolder.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/ImagePreviewViewHolder.java @@ -8,7 +8,6 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.View; import android.widget.ImageView; import android.widget.ProgressBar; -import android.widget.Toast; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.engine.GlideException; @@ -21,7 +20,6 @@ import org.briarproject.briar.android.conversation.glide.GlideApp; import org.briarproject.briar.android.view.ImagePreview.ImagePreviewListener; import static android.view.View.INVISIBLE; -import static android.widget.Toast.LENGTH_LONG; import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE; import static com.bumptech.glide.load.resource.bitmap.DownsampleStrategy.FIT_CENTER; import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade; @@ -32,16 +30,13 @@ class ImagePreviewViewHolder extends ViewHolder { @DrawableRes private static final int ERROR_RES = R.drawable.ic_image_broken; - private final boolean single; private final ImagePreviewListener listener; private final ImageView imageView; private final ProgressBar progressBar; - ImagePreviewViewHolder(View v, boolean single, - ImagePreviewListener listener) { + ImagePreviewViewHolder(View v, ImagePreviewListener listener) { super(v); - this.single = single; this.listener = listener; this.imageView = v.findViewById(R.id.imageView); this.progressBar = v.findViewById(R.id.progressBar); @@ -59,11 +54,8 @@ class ImagePreviewViewHolder extends ViewHolder { public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - if (single) listener.onCancel(); + listener.onUriError(uri); progressBar.setVisibility(INVISIBLE); - Toast.makeText(imageView.getContext(), - R.string.image_attach_error, LENGTH_LONG) - .show(); return false; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/TextAttachmentController.java b/briar-android/src/main/java/org/briarproject/briar/android/view/TextAttachmentController.java index 939d0d045..4ebae76db 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/TextAttachmentController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/TextAttachmentController.java @@ -5,12 +5,13 @@ import android.content.Intent; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v4.view.AbsSavedState; import android.support.v7.widget.AppCompatImageButton; +import android.widget.Toast; +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.R; import org.briarproject.briar.android.view.ImagePreview.ImagePreviewListener; @@ -26,11 +27,12 @@ import static android.support.v4.view.AbsSavedState.EMPTY_STATE; import static android.view.View.GONE; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; +import static android.widget.Toast.LENGTH_LONG; import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; @UiThread +@NotNullByDefault public class TextAttachmentController extends TextSendController implements ImagePreviewListener { @@ -88,7 +90,8 @@ public class TextAttachmentController extends TextSendController public void onImageReceived(@Nullable Intent resultData) { if (resultData == null) return; if (resultData.getData() != null) { - imageUris = singletonList(resultData.getData()); + imageUris = new ArrayList<>(1); + imageUris.add(resultData.getData()); onNewUris(); } else if (SDK_INT >= 18 && resultData.getClipData() != null) { ClipData clipData = resultData.getClipData(); @@ -162,13 +165,22 @@ public class TextAttachmentController extends TextSendController @Override @Nullable - public Parcelable onRestoreInstanceState(@NonNull Parcelable inState) { + public Parcelable onRestoreInstanceState(Parcelable inState) { SavedState state = (SavedState) inState; - imageUris = state.imageUris; + imageUris = requireNonNull(state.imageUris); onNewUris(); return state.getSuperState(); } + @Override + public void onUriError(Uri uri) { + imageUris.remove(uri); + imagePreview.removeUri(uri); + if (imageUris.isEmpty()) onCancel(); + Toast.makeText(textInput.getContext(), R.string.image_attach_error, + LENGTH_LONG).show(); + } + @Override public void onCancel() { textInput.clearText(); @@ -176,6 +188,7 @@ public class TextAttachmentController extends TextSendController } private static class SavedState extends AbsSavedState { + @Nullable private List imageUris; private SavedState(Parcelable superState) {