mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 21:29:54 +01:00
[android] Allow sending message with attachments before previews are loaded
This commit is contained in:
@@ -68,7 +68,7 @@ public class ImagePreview extends ConstraintLayout {
|
|||||||
imageList.setLayoutParams(params);
|
imageList.setLayoutParams(params);
|
||||||
}
|
}
|
||||||
setVisibility(VISIBLE);
|
setVisibility(VISIBLE);
|
||||||
ImagePreviewAdapter adapter = new ImagePreviewAdapter(items, listener);
|
ImagePreviewAdapter adapter = new ImagePreviewAdapter(items);
|
||||||
imageList.setAdapter(adapter);
|
imageList.setAdapter(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,16 +79,6 @@ public class ImagePreview extends ConstraintLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ImagePreviewListener {
|
interface ImagePreviewListener {
|
||||||
|
|
||||||
void onPreviewLoaded();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when Glide can't load a preview image.
|
|
||||||
*
|
|
||||||
* Warning: Glide may call this multiple times.
|
|
||||||
*/
|
|
||||||
void onError();
|
|
||||||
|
|
||||||
void onCancel();
|
void onCancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import android.view.ViewGroup;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.conversation.AttachmentResult;
|
import org.briarproject.briar.android.conversation.AttachmentResult;
|
||||||
import org.briarproject.briar.android.view.ImagePreview.ImagePreviewListener;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -22,14 +21,11 @@ import static java.util.Objects.requireNonNull;
|
|||||||
class ImagePreviewAdapter extends Adapter<ImagePreviewViewHolder> {
|
class ImagePreviewAdapter extends Adapter<ImagePreviewViewHolder> {
|
||||||
|
|
||||||
private final List<ImagePreviewItem> items;
|
private final List<ImagePreviewItem> items;
|
||||||
private final ImagePreviewListener listener;
|
|
||||||
@LayoutRes
|
@LayoutRes
|
||||||
private final int layout;
|
private final int layout;
|
||||||
|
|
||||||
ImagePreviewAdapter(Collection<ImagePreviewItem> items,
|
ImagePreviewAdapter(Collection<ImagePreviewItem> items) {
|
||||||
ImagePreviewListener listener) {
|
|
||||||
this.items = new ArrayList<>(items);
|
this.items = new ArrayList<>(items);
|
||||||
this.listener = listener;
|
|
||||||
this.layout = items.size() == 1 ?
|
this.layout = items.size() == 1 ?
|
||||||
R.layout.list_item_image_preview_single :
|
R.layout.list_item_image_preview_single :
|
||||||
R.layout.list_item_image_preview;
|
R.layout.list_item_image_preview;
|
||||||
@@ -40,7 +36,7 @@ class ImagePreviewAdapter extends Adapter<ImagePreviewViewHolder> {
|
|||||||
int type) {
|
int type) {
|
||||||
View v = LayoutInflater.from(viewGroup.getContext())
|
View v = LayoutInflater.from(viewGroup.getContext())
|
||||||
.inflate(layout, viewGroup, false);
|
.inflate(layout, viewGroup, false);
|
||||||
return new ImagePreviewViewHolder(v, requireNonNull(listener));
|
return new ImagePreviewViewHolder(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import com.bumptech.glide.request.target.Target;
|
|||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
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.view.View.INVISIBLE;
|
||||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||||
@@ -29,14 +28,11 @@ class ImagePreviewViewHolder extends ViewHolder {
|
|||||||
@DrawableRes
|
@DrawableRes
|
||||||
private static final int ERROR_RES = R.drawable.ic_image_broken;
|
private static final int ERROR_RES = R.drawable.ic_image_broken;
|
||||||
|
|
||||||
private final ImagePreviewListener listener;
|
|
||||||
|
|
||||||
private final ImageView imageView;
|
private final ImageView imageView;
|
||||||
private final ProgressBar progressBar;
|
private final ProgressBar progressBar;
|
||||||
|
|
||||||
ImagePreviewViewHolder(View v, ImagePreviewListener listener) {
|
ImagePreviewViewHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
this.listener = listener;
|
|
||||||
this.imageView = v.findViewById(R.id.imageView);
|
this.imageView = v.findViewById(R.id.imageView);
|
||||||
this.progressBar = v.findViewById(R.id.progressBar);
|
this.progressBar = v.findViewById(R.id.progressBar);
|
||||||
}
|
}
|
||||||
@@ -55,7 +51,6 @@ class ImagePreviewViewHolder extends ViewHolder {
|
|||||||
Object model, Target<Drawable> target,
|
Object model, Target<Drawable> target,
|
||||||
boolean isFirstResource) {
|
boolean isFirstResource) {
|
||||||
progressBar.setVisibility(INVISIBLE);
|
progressBar.setVisibility(INVISIBLE);
|
||||||
listener.onError();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +59,6 @@ class ImagePreviewViewHolder extends ViewHolder {
|
|||||||
Object model, Target<Drawable> target,
|
Object model, Target<Drawable> target,
|
||||||
DataSource dataSource, boolean isFirstResource) {
|
DataSource dataSource, boolean isFirstResource) {
|
||||||
progressBar.setVisibility(INVISIBLE);
|
progressBar.setVisibility(INVISIBLE);
|
||||||
listener.onPreviewLoaded();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt;
|
||||||
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.PromptStateChangeListener;
|
import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.PromptStateChangeListener;
|
||||||
|
|
||||||
|
import static android.arch.lifecycle.Lifecycle.State.DESTROYED;
|
||||||
import static android.content.Intent.ACTION_GET_CONTENT;
|
import static android.content.Intent.ACTION_GET_CONTENT;
|
||||||
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
||||||
import static android.content.Intent.CATEGORY_OPENABLE;
|
import static android.content.Intent.CATEGORY_OPENABLE;
|
||||||
@@ -56,8 +57,8 @@ public class TextAttachmentController extends TextSendController
|
|||||||
|
|
||||||
private CharSequence textHint;
|
private CharSequence textHint;
|
||||||
private List<Uri> imageUris = emptyList();
|
private List<Uri> imageUris = emptyList();
|
||||||
private int previewsLoaded = 0;
|
private int urisLoaded = 0;
|
||||||
private boolean loadingPreviews = false;
|
private boolean loadingUris = false;
|
||||||
|
|
||||||
public TextAttachmentController(TextInputView v, ImagePreview imagePreview,
|
public TextAttachmentController(TextInputView v, ImagePreview imagePreview,
|
||||||
SendListener listener, AttachImageListener imageListener,
|
SendListener listener, AttachImageListener imageListener,
|
||||||
@@ -76,10 +77,10 @@ public class TextAttachmentController extends TextSendController
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateViewState() {
|
protected void updateViewState() {
|
||||||
textInput.setEnabled(ready && !loadingPreviews);
|
textInput.setEnabled(ready && !loadingUris);
|
||||||
boolean sendEnabled = ready && !loadingPreviews &&
|
boolean sendEnabled = ready && !loadingUris &&
|
||||||
(!textIsEmpty || canSendEmptyText());
|
(!textIsEmpty || canSendEmptyText());
|
||||||
if (loadingPreviews) {
|
if (loadingUris) {
|
||||||
sendButton.showProgress(true);
|
sendButton.showProgress(true);
|
||||||
} else if (imageUris.isEmpty()) {
|
} else if (imageUris.isEmpty()) {
|
||||||
sendButton.showProgress(false);
|
sendButton.showProgress(false);
|
||||||
@@ -121,7 +122,9 @@ public class TextAttachmentController extends TextSendController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Intent intent = getAttachFileIntent();
|
Intent intent = getAttachFileIntent();
|
||||||
requireNonNull(imageListener).onAttachImage(intent);
|
if (imageListener.getLifecycle().getCurrentState() != DESTROYED) {
|
||||||
|
requireNonNull(imageListener).onAttachImage(intent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Intent getAttachFileIntent() {
|
private Intent getAttachFileIntent() {
|
||||||
@@ -152,7 +155,7 @@ public class TextAttachmentController extends TextSendController
|
|||||||
|
|
||||||
private void onNewUris() {
|
private void onNewUris() {
|
||||||
if (imageUris.isEmpty()) return;
|
if (imageUris.isEmpty()) return;
|
||||||
loadingPreviews = true;
|
loadingUris = true;
|
||||||
updateViewState();
|
updateViewState();
|
||||||
textInput.setHint(R.string.image_caption_hint);
|
textInput.setHint(R.string.image_caption_hint);
|
||||||
List<ImagePreviewItem> items = ImagePreviewItem.fromUris(imageUris);
|
List<ImagePreviewItem> items = ImagePreviewItem.fromUris(imageUris);
|
||||||
@@ -170,6 +173,8 @@ public class TextAttachmentController extends TextSendController
|
|||||||
onError(result.getErrorMsg());
|
onError(result.getErrorMsg());
|
||||||
} else {
|
} else {
|
||||||
imagePreview.loadPreviewImage(result);
|
imagePreview.loadPreviewImage(result);
|
||||||
|
urisLoaded++;
|
||||||
|
checkAllUrisLoaded();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,9 +185,9 @@ public class TextAttachmentController extends TextSendController
|
|||||||
imagePreview.setVisibility(GONE);
|
imagePreview.setVisibility(GONE);
|
||||||
// reset image URIs
|
// reset image URIs
|
||||||
imageUris = emptyList();
|
imageUris = emptyList();
|
||||||
// no preview has been loaded
|
// no URIs has been loaded
|
||||||
previewsLoaded = 0;
|
urisLoaded = 0;
|
||||||
loadingPreviews = false;
|
loadingUris = false;
|
||||||
// show the image button again, so images can get attached
|
// show the image button again, so images can get attached
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
@@ -204,17 +209,6 @@ public class TextAttachmentController extends TextSendController
|
|||||||
return state.getSuperState();
|
return state.getSuperState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPreviewLoaded() {
|
|
||||||
previewsLoaded++;
|
|
||||||
checkAllPreviewsLoaded();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError() {
|
|
||||||
onError(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private void onError(@Nullable String errorMsg) {
|
private void onError(@Nullable String errorMsg) {
|
||||||
if (errorMsg == null) {
|
if (errorMsg == null) {
|
||||||
@@ -232,10 +226,10 @@ public class TextAttachmentController extends TextSendController
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkAllPreviewsLoaded() {
|
private void checkAllUrisLoaded() {
|
||||||
if (previewsLoaded == imageUris.size()) {
|
if (urisLoaded == imageUris.size()) {
|
||||||
loadingPreviews = false;
|
loadingUris = false;
|
||||||
// all previews were loaded
|
// all images were turned into attachments
|
||||||
updateViewState();
|
updateViewState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user