From 814b2b2582f90808eeaa7ae4e23ea9a7518966d2 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 16 Dec 2020 12:22:03 -0300 Subject: [PATCH] Make view state of text send UI easier to reason about and fix bugs with bomb badge and hint display --- .../android/view/CompositeSendButton.java | 8 +-- .../view/TextAttachmentController.java | 39 ++++++++---- .../android/view/TextSendController.java | 61 ++++++++++++------- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/CompositeSendButton.java b/briar-android/src/main/java/org/briarproject/briar/android/view/CompositeSendButton.java index 11ed0adfc..095130fb7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/CompositeSendButton.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/CompositeSendButton.java @@ -23,7 +23,7 @@ public class CompositeSendButton extends FrameLayout { private final ImageView bombBadge; private final ProgressBar progressBar; - private boolean hasImageSupport = false, bombVisible = false; + private boolean hasImageSupport = false; public CompositeSendButton(@NonNull Context context, @Nullable AttributeSet attrs) { @@ -75,7 +75,6 @@ public class CompositeSendButton extends FrameLayout { } public void setBombVisible(boolean visible) { - bombVisible = visible; bombBadge.setVisibility(visible ? VISIBLE : INVISIBLE); } @@ -86,7 +85,6 @@ public class CompositeSendButton extends FrameLayout { sendButton.clearAnimation(); sendButton.animate().alpha(0f).withEndAction(() -> { sendButton.setVisibility(INVISIBLE); - bombBadge.setVisibility(INVISIBLE); imageButton.setEnabled(true); }).start(); imageButton.clearAnimation(); @@ -97,9 +95,7 @@ public class CompositeSendButton extends FrameLayout { sendButton.setEnabled(sendEnabled); imageButton.setEnabled(false); sendButton.clearAnimation(); - sendButton.animate().alpha(1f).withEndAction(() -> { - if (bombVisible) bombBadge.setVisibility(VISIBLE); - }).start(); + sendButton.animate().alpha(1f).start(); imageButton.clearAnimation(); imageButton.animate().alpha(0f).withEndAction(() -> imageButton.setVisibility(INVISIBLE) 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 a048d43e2..5c016ba39 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 @@ -52,7 +52,6 @@ public class TextAttachmentController extends TextSendController private final AttachmentManager attachmentManager; private final List imageUris = new ArrayList<>(); - private final CharSequence textHint; private boolean loadingUris = false; public TextAttachmentController(TextInputView v, ImagePreview imagePreview, @@ -66,23 +65,44 @@ public class TextAttachmentController extends TextSendController sendButton = (CompositeSendButton) compositeSendButton; sendButton.setOnImageClickListener(view -> onImageButtonClicked()); - - textHint = textInput.getHint(); } @Override protected void updateViewState() { - textInput.setEnabled(ready && !loadingUris); - boolean sendEnabled = ready && !loadingUris && - (!textIsEmpty || canSendEmptyText()); + super.updateViewState(); if (loadingUris) { sendButton.showProgress(true); } else if (imageUris.isEmpty()) { sendButton.showProgress(false); - sendButton.showImageButton(textIsEmpty, sendEnabled); + sendButton.showImageButton(textIsEmpty, isSendButtonEnabled()); } else { sendButton.showProgress(false); - sendButton.showImageButton(false, sendEnabled); + sendButton.showImageButton(false, isSendButtonEnabled()); + } + } + + @Override + protected boolean isTextInputEnabled() { + return super.isTextInputEnabled() && !loadingUris; + } + + @Override + protected boolean isSendButtonEnabled() { + return super.isSendButtonEnabled() && !loadingUris; + } + + @Override + protected boolean isBombVisible() { + return super.isBombVisible() && (!textIsEmpty || !imageUris.isEmpty()); + } + + @Override + protected CharSequence getCurrentTextHint() { + if (imageUris.isEmpty()) { + return super.getCurrentTextHint(); + } else { + Context ctx = textInput.getContext(); + return ctx.getString(R.string.image_caption_hint); } } @@ -161,7 +181,6 @@ public class TextAttachmentController extends TextSendController } imageUris.addAll(newUris); updateViewState(); - textInput.setHint(R.string.image_caption_hint); List items = ImagePreviewItem.fromUris(imageUris); imagePreview.showPreview(items); // store attachments and show preview when successful @@ -207,8 +226,6 @@ public class TextAttachmentController extends TextSendController } private void reset() { - // restore hint - textInput.setHint(textHint); // hide image layout imagePreview.setVisibility(GONE); // reset image URIs diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/TextSendController.java b/briar-android/src/main/java/org/briarproject/briar/android/view/TextSendController.java index 886a0a44b..3d471f688 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/TextSendController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/TextSendController.java @@ -1,5 +1,6 @@ package org.briarproject.briar.android.view; +import android.content.Context; import android.os.Parcelable; import android.view.View; @@ -7,12 +8,12 @@ import com.google.android.material.snackbar.Snackbar; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.R; -import org.briarproject.briar.android.conversation.ConversationActivity; import org.briarproject.briar.android.view.EmojiTextInputView.TextInputListener; import org.briarproject.briar.api.attachment.AttachmentHeader; import java.util.List; +import androidx.annotation.CallSuper; import androidx.annotation.Nullable; import androidx.annotation.UiThread; @@ -28,10 +29,12 @@ public class TextSendController implements TextInputListener { protected final View compositeSendButton; protected final SendListener listener; - protected boolean ready = true, textIsEmpty = true; + protected boolean textIsEmpty = true; + private boolean ready = true; + private long currentTimer = NO_AUTO_DELETE_TIMER; + private final CharSequence defaultHint; private final boolean allowEmptyText; - private CharSequence defaultHint; public TextSendController(TextInputView v, SendListener listener, boolean allowEmptyText) { @@ -63,31 +66,43 @@ public class TextSendController implements TextInputListener { /** * Sets the current auto delete timer and updates the UI accordingly. - *

- * Attention: Works only in {@link ConversationActivity}. */ public void setAutoDeleteTimer(long timer) { - // this will need to be adapted when other screens - // besides the private conversation use auto delete timers - CompositeSendButton sendButton = - (CompositeSendButton) compositeSendButton; - // update hint - if (timer == NO_AUTO_DELETE_TIMER) { - textInput.setHint(defaultHint); - sendButton.setBombVisible(false); - } else { - // this might need to be adapted when other screens - // besides the private conversation use auto delete timers - defaultHint = textInput.getHint(); - textInput.setHint(R.string.message_hint_auto_delete); - sendButton.setBombVisible(true); + currentTimer = timer; + updateViewState(); + } + + @CallSuper + protected void updateViewState() { + textInput.setEnabled(isTextInputEnabled()); + textInput.setHint(getCurrentTextHint()); + compositeSendButton.setEnabled(isSendButtonEnabled()); + if (compositeSendButton instanceof CompositeSendButton) { + CompositeSendButton sendButton = + (CompositeSendButton) compositeSendButton; + sendButton.setBombVisible(isBombVisible()); } } - protected void updateViewState() { - textInput.setEnabled(ready); - compositeSendButton - .setEnabled(ready && (!textIsEmpty || canSendEmptyText())); + protected boolean isTextInputEnabled() { + return ready; + } + + protected boolean isSendButtonEnabled() { + return ready && (!textIsEmpty || canSendEmptyText()); + } + + protected boolean isBombVisible() { + return currentTimer != NO_AUTO_DELETE_TIMER; + } + + protected CharSequence getCurrentTextHint() { + if (currentTimer == NO_AUTO_DELETE_TIMER) { + return defaultHint; + } else { + Context ctx = textInput.getContext(); + return ctx.getString(R.string.message_hint_auto_delete); + } } protected final boolean canSend() {