From 26e04ce6d292e2e54ac7f7e381698c031e7fcd0d Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 15 Oct 2021 15:46:27 -0400 Subject: [PATCH] Update conversation list multi-select to use checkboxes. --- .../ConversationListItem.java | 74 ++++++++++--------- .../ConversationListSearchAdapter.java | 6 +- .../conversation_list_item_background.xml | 44 +++++++++-- ...nversation_list_item_background_ripple.xml | 5 ++ .../res/drawable/multiselect_empty_ring.xml | 10 +++ .../layout/conversation_list_item_view.xml | 35 ++++++++- app/src/main/res/values-night/dark_colors.xml | 1 + app/src/main/res/values/light_colors.xml | 1 + 8 files changed, 130 insertions(+), 46 deletions(-) create mode 100644 app/src/main/res/drawable-v21/conversation_list_item_background_ripple.xml create mode 100644 app/src/main/res/drawable/multiselect_empty_ring.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java index cae2083499..c22299e634 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java @@ -17,12 +17,8 @@ package org.thoughtcrime.securesms.conversationlist; import android.content.Context; -import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.RippleDrawable; -import android.os.Build; import android.text.Spannable; import android.text.SpannableString; import android.text.SpannableStringBuilder; @@ -46,7 +42,6 @@ import androidx.lifecycle.Transformations; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy; -import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.makeramen.roundedimageview.RoundedDrawable; import org.signal.core.util.DimensionUnit; @@ -122,6 +117,9 @@ public final class ConversationListItem extends ConstraintLayout private Locale locale; private String highlightSubstring; private BadgeImageView badge; + private View checkContainer; + private View uncheckedView; + private View checkedView; private int unreadCount; private AvatarImageView contactPhotoImage; @@ -151,6 +149,11 @@ public final class ConversationListItem extends ConstraintLayout this.archivedView = findViewById(R.id.conversation_list_item_archived); this.unreadIndicator = findViewById(R.id.conversation_list_item_unread_indicator); this.badge = findViewById(R.id.conversation_list_item_badge); + this.checkContainer = findViewById(R.id.conversation_list_item_check_container); + this.uncheckedView = findViewById(R.id.conversation_list_item_unchecked); + this.checkedView = findViewById(R.id.conversation_list_item_checked); + + getLayoutTransition().setDuration(150); } @Override @@ -161,16 +164,16 @@ public final class ConversationListItem extends ConstraintLayout @NonNull Set selectedThreads, boolean batchMode) { - bind(thread, glideRequests, locale, typingThreads, selectedThreads, batchMode, null); + bindThread(thread, glideRequests, locale, typingThreads, selectedThreads, batchMode, null); } - public void bind(@NonNull ThreadRecord thread, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @NonNull Set typingThreads, - @NonNull Set selectedThreads, - boolean batchMode, - @Nullable String highlightSubstring) + public void bindThread(@NonNull ThreadRecord thread, + @NonNull GlideRequests glideRequests, + @NonNull Locale locale, + @NonNull Set typingThreads, + @NonNull Set selectedThreads, + boolean batchMode, + @Nullable String highlightSubstring) { observeRecipient(thread.getRecipient().live()); observeDisplayBody(null); @@ -214,16 +217,15 @@ public final class ConversationListItem extends ConstraintLayout setStatusIcons(thread); setBatchMode(batchMode); - setRippleColor(recipient.get()); badge.setBadgeFromRecipient(recipient.get()); setUnreadIndicator(thread); this.contactPhotoImage.setAvatar(glideRequests, recipient.get(), !batchMode); } - public void bind(@NonNull Recipient contact, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @Nullable String highlightSubstring) + public void bindContact(@NonNull Recipient contact, + @NonNull GlideRequests glideRequests, + @NonNull Locale locale, + @Nullable String highlightSubstring) { observeRecipient(contact.live()); observeDisplayBody(null); @@ -243,15 +245,14 @@ public final class ConversationListItem extends ConstraintLayout alertView.setNone(); setBatchMode(false); - setRippleColor(contact); badge.setBadgeFromRecipient(recipient.get()); contactPhotoImage.setAvatar(glideRequests, recipient.get(), !batchMode); } - public void bind(@NonNull MessageResult messageResult, - @NonNull GlideRequests glideRequests, - @NonNull Locale locale, - @Nullable String highlightSubstring) + public void bindMessage(@NonNull MessageResult messageResult, + @NonNull GlideRequests glideRequests, + @NonNull Locale locale, + @Nullable String highlightSubstring) { observeRecipient(messageResult.getConversationRecipient().live()); observeDisplayBody(null); @@ -271,7 +272,6 @@ public final class ConversationListItem extends ConstraintLayout alertView.setNone(); setBatchMode(false); - setRippleColor(recipient.get()); badge.setBadgeFromRecipient(recipient.get()); contactPhotoImage.setAvatar(glideRequests, recipient.get(), !batchMode); } @@ -290,7 +290,23 @@ public final class ConversationListItem extends ConstraintLayout @Override public void setBatchMode(boolean batchMode) { this.batchMode = batchMode; - setSelected(batchMode && selectedThreads.contains(thread.getThreadId())); + + boolean selected = batchMode && selectedThreads.contains(thread.getThreadId()); + setSelected(selected); + + if (batchMode && selected) { + checkContainer.setVisibility(VISIBLE); + uncheckedView.setVisibility(GONE); + checkedView.setVisibility(VISIBLE); + } else if (batchMode) { + checkContainer.setVisibility(VISIBLE); + uncheckedView.setVisibility(VISIBLE); + checkedView.setVisibility(GONE); + } else { + checkContainer.setVisibility(GONE); + uncheckedView.setVisibility(GONE); + checkedView.setVisibility(GONE); + } } @Override @@ -402,13 +418,6 @@ public final class ConversationListItem extends ConstraintLayout } } - private void setRippleColor(Recipient recipient) { - if (Build.VERSION.SDK_INT >= 21) { - ((RippleDrawable)(getBackground()).mutate()) - .setColor(ColorStateList.valueOf(recipient.getChatColors().asSingleColor())); - } - } - private void setUnreadIndicator(ThreadRecord thread) { if ((thread.isOutgoing() && !thread.isForcedUnread()) || thread.isRead()) { unreadIndicator.setVisibility(View.GONE); @@ -433,7 +442,6 @@ public final class ConversationListItem extends ConstraintLayout fromView.setText(recipient, false); } contactPhotoImage.setAvatar(glideRequests, recipient, !batchMode); - setRippleColor(recipient); badge.setBadgeFromRecipient(recipient); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.java index ef7c767730..4bfdf666d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.java @@ -162,7 +162,7 @@ class ConversationListSearchAdapter extends RecyclerView.Adapter eventListener.onConversationClicked(conversationResult)); } @@ -172,7 +172,7 @@ class ConversationListSearchAdapter extends RecyclerView.Adapter eventListener.onContactClicked(contactResult)); } @@ -182,7 +182,7 @@ class ConversationListSearchAdapter extends RecyclerView.Adapter eventListener.onMessageClicked(messageResult)); } diff --git a/app/src/main/res/drawable-v21/conversation_list_item_background.xml b/app/src/main/res/drawable-v21/conversation_list_item_background.xml index 6ef38ac5e1..8e214c4cfb 100644 --- a/app/src/main/res/drawable-v21/conversation_list_item_background.xml +++ b/app/src/main/res/drawable-v21/conversation_list_item_background.xml @@ -1,10 +1,38 @@ - - - - - - + + + + + + + + + + - + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable-v21/conversation_list_item_background_ripple.xml b/app/src/main/res/drawable-v21/conversation_list_item_background_ripple.xml new file mode 100644 index 0000000000..e7ec79622f --- /dev/null +++ b/app/src/main/res/drawable-v21/conversation_list_item_background_ripple.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/multiselect_empty_ring.xml b/app/src/main/res/drawable/multiselect_empty_ring.xml new file mode 100644 index 0000000000..ea9c94a7d3 --- /dev/null +++ b/app/src/main/res/drawable/multiselect_empty_ring.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/conversation_list_item_view.xml b/app/src/main/res/layout/conversation_list_item_view.xml index 4049f37f03..b65ed3075a 100644 --- a/app/src/main/res/layout/conversation_list_item_view.xml +++ b/app/src/main/res/layout/conversation_list_item_view.xml @@ -10,17 +10,48 @@ android:nextFocusLeft="@+id/container" android:nextFocusRight="@+id/fab" android:paddingStart="@dimen/dsl_settings_gutter" - android:paddingEnd="@dimen/dsl_settings_gutter"> + android:paddingEnd="@dimen/dsl_settings_gutter" + android:animateLayoutChanges="true"> + + + + + + + + @color/core_white @color/core_grey_85 + #4c6191f3 @color/core_grey_75 diff --git a/app/src/main/res/values/light_colors.xml b/app/src/main/res/values/light_colors.xml index c2f0ec05d3..025f3b6526 100644 --- a/app/src/main/res/values/light_colors.xml +++ b/app/src/main/res/values/light_colors.xml @@ -98,6 +98,7 @@ @color/grey_600 @color/core_white + #222c6bed @color/core_grey_02