From b5af691cc4e280e3064c33d301bbbf28eed32efe Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Fri, 24 Sep 2021 13:39:28 -0300 Subject: [PATCH] Add badges to Avatars in a variety of places. --- .../transitions/CircleAvatarTransition.kt | 5 +- .../securesms/badges/BadgeImageView.kt | 75 ++++ .../settings/app/AppSettingsFragment.kt | 3 + .../ConversationSettingsFragment.kt | 3 + .../preferences/AvatarPreference.kt | 19 +- .../contacts/ContactSelectionListItem.java | 25 +- .../conversation/ConversationBannerView.java | 7 + .../conversation/ConversationFragment.java | 4 + .../conversation/ConversationItem.java | 2 +- .../conversation/ConversationTitleView.java | 6 + .../ConversationListItem.java | 5 + .../securesms/recipients/Recipient.java | 8 + .../RecipientBottomSheetDialogFragment.java | 10 + app/src/main/res/drawable/ic_badge_24.xml | 9 + .../main/res/layout/bio_preference_item.xml | 14 + .../layout/contact_selection_list_item.xml | 14 + .../res/layout/conversation_banner_view.xml | 40 +- .../layout/conversation_list_item_view.xml | 349 +++++++++--------- ...sation_settings_avatar_preference_item.xml | 38 +- .../res/layout/conversation_title_view.xml | 58 ++- .../res/layout/manage_profile_fragment.xml | 15 +- .../res/layout/recipient_bottom_sheet.xml | 14 + app/src/main/res/values/attrs.xml | 5 + app/src/main/res/values/dimens.xml | 3 + app/src/main/res/values/strings.xml | 2 + 25 files changed, 499 insertions(+), 234 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/badges/BadgeImageView.kt create mode 100644 app/src/main/res/drawable/ic_badge_24.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/CircleAvatarTransition.kt b/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/CircleAvatarTransition.kt index 1fda6fe7d3..30a034b42f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/CircleAvatarTransition.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/animation/transitions/CircleAvatarTransition.kt @@ -14,7 +14,6 @@ import android.view.animation.AccelerateInterpolator import android.view.animation.DecelerateInterpolator import android.view.animation.Interpolator import androidx.annotation.RequiresApi -import org.thoughtcrime.securesms.components.AvatarImageView private const val POSITION_ON_SCREEN = "signal.circleavatartransition.positiononscreen" private const val WIDTH = "signal.circleavatartransition.width" @@ -36,7 +35,7 @@ class CircleAvatarTransition(context: Context, attrs: AttributeSet?) : Transitio private fun captureValues(transitionValues: TransitionValues) { val view: View = transitionValues.view - if (view is AvatarImageView) { + if (view.transitionName == "avatar") { val topLeft = intArrayOf(0, 0) view.getLocationOnScreen(topLeft) transitionValues.values[POSITION_ON_SCREEN] = topLeft @@ -51,7 +50,7 @@ class CircleAvatarTransition(context: Context, attrs: AttributeSet?) : Transitio } val view: View = endValues.view - if (view !is AvatarImageView || view.transitionName != "avatar") { + if (view.transitionName != "avatar") { return null } diff --git a/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeImageView.kt b/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeImageView.kt new file mode 100644 index 0000000000..137efc711e --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/badges/BadgeImageView.kt @@ -0,0 +1,75 @@ +package org.thoughtcrime.securesms.badges + +import android.content.Context +import android.graphics.Color +import android.graphics.drawable.Drawable +import android.util.AttributeSet +import androidx.annotation.ColorInt +import androidx.annotation.Px +import androidx.appcompat.widget.AppCompatImageView +import androidx.core.content.res.use +import androidx.lifecycle.Lifecycle +import org.signal.core.util.logging.Log +import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.badges.Badges.insetWithOutline +import org.thoughtcrime.securesms.badges.models.Badge +import org.thoughtcrime.securesms.mms.GlideApp +import org.thoughtcrime.securesms.recipients.Recipient +import org.thoughtcrime.securesms.util.ViewUtil +import org.thoughtcrime.securesms.util.visible + +private val TAG = Log.tag(BadgeImageView::class.java) + +class BadgeImageView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null +) : AppCompatImageView(context, attrs) { + + @Px + private var outlineWidth: Float = 0f + + @ColorInt + private var outlineColor: Int = Color.BLACK + + init { + context.obtainStyledAttributes(attrs, R.styleable.BadgeImageView).use { + outlineWidth = it.getDimension(R.styleable.BadgeImageView_badge_outline_width, 0f) + outlineColor = it.getColor(R.styleable.BadgeImageView_badge_outline_color, Color.BLACK) + } + } + + fun setBadgeFromRecipient(recipient: Recipient?) { + if (recipient == null || recipient.badges.isEmpty()) { + setBadge(null) + } else { + setBadge(recipient.badges[0]) + } + } + + fun setBadge(badge: Badge?) { + visible = badge != null + + val lifecycle = ViewUtil.getActivityLifecycle(this) + if (lifecycle?.currentState == Lifecycle.State.DESTROYED) { + Log.w(TAG, "Ignoring setBadge call for destroyed activity.") + return + } + + GlideApp + .with(this) + .load(badge) + .into(this) + } + + override fun setImageDrawable(drawable: Drawable?) { + if (drawable == null || outlineWidth == 0f) { + super.setImageDrawable(drawable) + } else { + super.setImageDrawable( + drawable.insetWithOutline( + outlineWidth, outlineColor + ) + ) + } + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt index 21b1eb6a10..1cb834ee88 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/AppSettingsFragment.kt @@ -5,6 +5,7 @@ import android.widget.TextView import androidx.lifecycle.ViewModelProvider import androidx.navigation.Navigation import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.badges.BadgeImageView import org.thoughtcrime.securesms.components.AvatarImageView import org.thoughtcrime.securesms.components.settings.DSLConfiguration import org.thoughtcrime.securesms.components.settings.DSLSettingsAdapter @@ -162,6 +163,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men private val avatarView: AvatarImageView = itemView.findViewById(R.id.icon) private val aboutView: TextView = itemView.findViewById(R.id.about) + private val badgeView: BadgeImageView = itemView.findViewById(R.id.badge) override fun bind(model: BioPreference) { super.bind(model) @@ -171,6 +173,7 @@ class AppSettingsFragment : DSLSettingsFragment(R.string.text_secure_normal__men titleView.text = model.recipient.profileName.toString() summaryView.text = PhoneNumberFormatter.prettyPrint(model.recipient.requireE164()) avatarView.setRecipient(Recipient.self()) + badgeView.setBadgeFromRecipient(Recipient.self()) titleView.visibility = View.VISIBLE summaryView.visibility = View.VISIBLE diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt index 5be739639e..a44ad57fa1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/ConversationSettingsFragment.kt @@ -259,6 +259,9 @@ class ConversationSettingsFragment : DSLSettingsFragment( ) } } + }, + onBadgeClick = { badge -> + ViewBadgeBottomSheetDialogFragment.show(parentFragmentManager, state.recipient.id, badge) } ) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/AvatarPreference.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/AvatarPreference.kt index 76f5afcb3c..ea137b6387 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/AvatarPreference.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/conversation/preferences/AvatarPreference.kt @@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.components.settings.conversation.preferences import android.view.View import androidx.core.view.ViewCompat import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.badges.BadgeImageView +import org.thoughtcrime.securesms.badges.models.Badge import org.thoughtcrime.securesms.components.AvatarImageView import org.thoughtcrime.securesms.components.settings.PreferenceModel import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto @@ -23,7 +25,8 @@ object AvatarPreference { class Model( val recipient: Recipient, - val onAvatarClick: (View) -> Unit + val onAvatarClick: (View) -> Unit, + val onBadgeClick: (Badge) -> Unit ) : PreferenceModel() { override fun areItemsTheSame(newItem: Model): Boolean { return recipient == newItem.recipient @@ -36,11 +39,23 @@ object AvatarPreference { private class ViewHolder(itemView: View) : MappingViewHolder(itemView) { private val avatar: AvatarImageView = itemView.findViewById(R.id.bio_preference_avatar).apply { - ViewCompat.setTransitionName(this, "avatar") setFallbackPhotoProvider(AvatarPreferenceFallbackPhotoProvider()) } + private val badge: BadgeImageView = itemView.findViewById(R.id.bio_preference_badge) + + init { + ViewCompat.setTransitionName(avatar.parent as View, "avatar") + } + override fun bind(model: Model) { + badge.setBadgeFromRecipient(model.recipient) + badge.setOnClickListener { + val badge = model.recipient.badges.firstOrNull() + if (badge != null) { + model.onBadgeClick(badge) + } + } avatar.setAvatar(model.recipient) avatar.disableQuickContact() avatar.setOnClickListener { model.onAvatarClick(avatar) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java index c532c2eaac..ff5414b4b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/contacts/ContactSelectionListItem.java @@ -5,7 +5,6 @@ import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.widget.CheckBox; -import android.widget.LinearLayout; import android.widget.TextView; import androidx.annotation.NonNull; @@ -14,6 +13,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.badges.BadgeImageView; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.FromTextView; import org.thoughtcrime.securesms.mms.GlideRequests; @@ -37,16 +37,17 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi private TextView labelView; private CheckBox checkBox; private View smsTag; + private BadgeImageView badge; - private String number; - private String chipName; - private int contactType; - private String contactName; - private String contactNumber; - private String contactLabel; - private String contactAbout; - private LiveRecipient recipient; - private GlideRequests glideRequests; + private String number; + private String chipName; + private int contactType; + private String contactName; + private String contactNumber; + private String contactLabel; + private String contactAbout; + private LiveRecipient recipient; + private GlideRequests glideRequests; public ContactSelectionListItem(Context context) { super(context); @@ -65,6 +66,7 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi this.nameView = findViewById(R.id.name); this.checkBox = findViewById(R.id.check_box); this.smsTag = findViewById(R.id.sms_tag); + this.badge = findViewById(R.id.contact_badge); ViewUtil.setTextViewGravityStart(this.nameView, getContext()); } @@ -118,6 +120,8 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi } this.checkBox.setVisibility(checkboxVisible ? View.VISIBLE : View.GONE); + + badge.setBadgeFromRecipient(recipientSnapshot); } public void setChecked(boolean selected, boolean animate) { @@ -229,6 +233,7 @@ public class ContactSelectionListItem extends ConstraintLayout implements Recipi contactPhotoImage.setAvatar(glideRequests, recipient, false); setText(recipient, contactType, contactName, contactNumber, contactLabel, contactAbout); smsTag.setVisibility(recipient.isRegistered() ? GONE : VISIBLE); + badge.setBadgeFromRecipient(recipient); } else { Log.w(TAG, "Bad change! Local recipient doesn't match. Ignoring. Local: " + (this.recipient == null ? "null" : this.recipient.getId()) + ", Changed: " + recipient.getId()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java index 26282b0b4c..9262632a0d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationBannerView.java @@ -12,6 +12,7 @@ import androidx.constraintlayout.widget.ConstraintLayout; import org.signal.core.util.concurrent.SignalExecutors; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.badges.BadgeImageView; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.emoji.EmojiTextView; import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto; @@ -29,6 +30,7 @@ public class ConversationBannerView extends ConstraintLayout { private TextView contactSubtitle; private EmojiTextView contactDescription; private View tapToView; + private BadgeImageView contactBadge; public ConversationBannerView(Context context) { this(context, null); @@ -44,6 +46,7 @@ public class ConversationBannerView extends ConstraintLayout { inflate(getContext(), R.layout.conversation_banner_view, this); contactAvatar = findViewById(R.id.message_request_avatar); + contactBadge = findViewById(R.id.message_request_badge); contactTitle = findViewById(R.id.message_request_title); contactAbout = findViewById(R.id.message_request_about); contactSubtitle = findViewById(R.id.message_request_subtitle); @@ -53,6 +56,10 @@ public class ConversationBannerView extends ConstraintLayout { contactAvatar.setFallbackPhotoProvider(new FallbackPhotoProvider()); } + public void setBadge(@Nullable Recipient recipient) { + contactBadge.setBadgeFromRecipient(recipient); + } + public void setAvatar(@NonNull GlideRequests requests, @Nullable Recipient recipient) { contactAvatar.setAvatar(requests, recipient, false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 36bca67f4b..e504e57573 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -55,6 +55,7 @@ import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityOptionsCompat; import androidx.core.text.HtmlCompat; +import androidx.core.view.ViewCompat; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProviders; @@ -579,6 +580,8 @@ public class ConversationFragment extends LoggingFragment implements Multiselect int pendingMemberCount = recipientInfo.getGroupPendingMemberCount(); List groups = recipientInfo.getSharedGroups(); + conversationBanner.setBadge(recipient); + if (recipient != null) { conversationBanner.setAvatar(GlideApp.with(context), recipient); conversationBanner.showBackgroundBubble(recipient.hasWallpaper()); @@ -1510,6 +1513,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect @Override public void onSharedContactDetailsClicked(@NonNull Contact contact, @NonNull View avatarTransitionView) { if (getContext() != null && getActivity() != null) { + ViewCompat.setTransitionName(avatarTransitionView, "avatar"); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), avatarTransitionView, "avatar").toBundle(); ActivityCompat.startActivity(getActivity(), SharedContactDetailsActivity.getIntent(getContext(), contact), bundle); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 819f51b782..37fd206fb4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -1788,7 +1788,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo @Override public void onClick(View view) { if (eventListener != null && batchSelected.isEmpty() && messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getSharedContacts().isEmpty()) { - eventListener.onSharedContactDetailsClicked(((MmsMessageRecord) messageRecord).getSharedContacts().get(0), sharedContactStub.get().getAvatarView()); + eventListener.onSharedContactDetailsClicked(((MmsMessageRecord) messageRecord).getSharedContacts().get(0), (View) sharedContactStub.get().getAvatarView().getParent()); } else { passthroughClickListener.onClick(view); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationTitleView.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationTitleView.java index 76d1e170cb..2d0b85c415 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationTitleView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationTitleView.java @@ -19,6 +19,8 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.badges.BadgeImageView; +import org.thoughtcrime.securesms.badges.models.Badge; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.recipients.LiveRecipient; @@ -31,6 +33,7 @@ import java.util.Objects; public class ConversationTitleView extends RelativeLayout { private AvatarImageView avatar; + private BadgeImageView badge; private TextView title; private TextView subtitle; private ImageView verified; @@ -52,6 +55,7 @@ public class ConversationTitleView extends RelativeLayout { super.onFinishInflate(); this.title = findViewById(R.id.title); + this.badge = findViewById(R.id.badge); this.subtitle = findViewById(R.id.subtitle); this.verified = findViewById(R.id.verified_indicator); this.subtitleContainer = findViewById(R.id.subtitle_container); @@ -102,6 +106,8 @@ public class ConversationTitleView extends RelativeLayout { this.avatar.setAvatar(glideRequests, recipient, false); } + badge.setBadgeFromRecipient(recipient); + updateVerifiedSubtitleVisibility(); } 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 d3349ae8f2..3f8cd5e830 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListItem.java @@ -42,6 +42,7 @@ import org.signal.core.util.logging.Log; import org.thoughtcrime.securesms.BindableConversationListItem; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.Unbindable; +import org.thoughtcrime.securesms.badges.BadgeImageView; import org.thoughtcrime.securesms.components.AlertView; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.DeliveryStatusView; @@ -105,6 +106,7 @@ public final class ConversationListItem extends ConstraintLayout private boolean batchMode; private Locale locale; private String highlightSubstring; + private BadgeImageView badge; private int unreadCount; private AvatarImageView contactPhotoImage; @@ -135,6 +137,7 @@ public final class ConversationListItem extends ConstraintLayout this.thumbnailView = findViewById(R.id.conversation_list_item_thumbnail); 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); thumbnailView.setClickable(false); } @@ -201,6 +204,7 @@ public final class ConversationListItem extends ConstraintLayout setThumbnailSnippet(thread); setBatchMode(batchMode); setRippleColor(recipient.get()); + badge.setBadgeFromRecipient(recipient.get()); setUnreadIndicator(thread); this.contactPhotoImage.setAvatar(glideRequests, recipient.get(), !batchMode); } @@ -428,6 +432,7 @@ public final class ConversationListItem extends ConstraintLayout } contactPhotoImage.setAvatar(glideRequests, recipient, !batchMode); setRippleColor(recipient); + badge.setBadgeFromRecipient(recipient); } private static @NonNull LiveData getThreadDisplayBody(@NonNull Context context, @NonNull ThreadRecord thread) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index 49c1b3a34a..b8c969f46a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -1031,6 +1031,14 @@ public class Recipient { return badges; } + public @Nullable Badge getFeaturedBadge() { + if (badges.isEmpty()) { + return null; + } else { + return badges.get(0); + } + } + public @Nullable String getCombinedAboutAndEmoji() { if (!Util.isEmpty(aboutEmoji)) { if (!Util.isEmpty(about)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java index f3a54c215f..4b02185266 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/bottomsheet/RecipientBottomSheetDialogFragment.java @@ -24,6 +24,8 @@ import androidx.lifecycle.ViewModelProviders; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.badges.BadgeImageView; +import org.thoughtcrime.securesms.badges.view.ViewBadgeBottomSheetDialogFragment; import org.thoughtcrime.securesms.components.AvatarImageView; import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon; import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference; @@ -75,6 +77,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF private View noteToSelfDescription; private View buttonStrip; private View interactionsContainer; + private BadgeImageView badgeImageView; public static BottomSheetDialogFragment create(@NonNull RecipientId recipientId, @Nullable GroupId groupId) @@ -122,6 +125,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF noteToSelfDescription = view.findViewById(R.id.rbs_note_to_self_description); buttonStrip = view.findViewById(R.id.button_strip); interactionsContainer = view.findViewById(R.id.interactions_container); + badgeImageView = view.findViewById(R.id.rbs_badge); return view; } @@ -148,6 +152,7 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF } }); avatar.setAvatar(recipient); + badgeImageView.setBadgeFromRecipient(recipient); if (recipient.isSelf()) { avatar.setOnClickListener(v -> { dismiss(); @@ -279,6 +284,11 @@ public final class RecipientBottomSheetDialogFragment extends BottomSheetDialogF viewModel.onAvatarClicked(requireActivity()); }); + badgeImageView.setOnClickListener(view -> { + dismiss(); + ViewBadgeBottomSheetDialogFragment.show(getParentFragmentManager(), recipientId, null); + }); + blockButton.setOnClickListener(view -> viewModel.onBlockClicked(requireActivity())); unblockButton.setOnClickListener(view -> viewModel.onUnblockClicked(requireActivity())); diff --git a/app/src/main/res/drawable/ic_badge_24.xml b/app/src/main/res/drawable/ic_badge_24.xml new file mode 100644 index 0000000000..0660b97cf3 --- /dev/null +++ b/app/src/main/res/drawable/ic_badge_24.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/bio_preference_item.xml b/app/src/main/res/layout/bio_preference_item.xml index f9db8a98be..e9905b9fb8 100644 --- a/app/src/main/res/layout/bio_preference_item.xml +++ b/app/src/main/res/layout/bio_preference_item.xml @@ -19,6 +19,20 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + + + app:srcCompat="@drawable/ic_tap_outline_24" + app:tint="@color/core_white" /> + android:text="@string/MessageRequestProfileView_view" + android:textAppearance="@style/TextAppearance.Signal.Subtitle" + android:textColor="@color/core_white" /> @@ -64,13 +78,13 @@ android:id="@+id/message_request_about" android:layout_width="match_parent" android:layout_height="wrap_content" + android:gravity="center" android:paddingStart="16dp" android:paddingEnd="16dp" - android:gravity="center" android:textAppearance="@style/Signal.Text.MessageRequest.Subtitle" - tools:text="Hangin' on the web" + app:emoji_forceCustom="true" app:layout_constraintTop_toBottomOf="@id/message_request_title" - app:emoji_forceCustom="true"/> + tools:text="Hangin' on the web" /> - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + android:layout_marginTop="6dp" + android:gravity="center" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/conversation_list_item_date"> - + - + - + - + - + + + + + + + diff --git a/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml b/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml index 7b53fee6e1..90bcf11bcd 100644 --- a/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml +++ b/app/src/main/res/layout/conversation_settings_avatar_preference_item.xml @@ -1,12 +1,38 @@ - + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/conversation_title_view.xml b/app/src/main/res/layout/conversation_title_view.xml index cfeb3a7f94..261fbc9e59 100644 --- a/app/src/main/res/layout/conversation_title_view.xml +++ b/app/src/main/res/layout/conversation_title_view.xml @@ -9,27 +9,47 @@ android:gravity="center_vertical" tools:layout_height="?actionBarSize"> - + + + + + + @@ -61,8 +81,8 @@ android:layout_height="match_parent" android:layout_marginEnd="3dp" android:tint="@color/signal_inverse_transparent_80" - app:srcCompat="@drawable/ic_check_24" android:visibility="gone" + app:srcCompat="@drawable/ic_check_24" tools:visibility="visible" /> diff --git a/app/src/main/res/layout/manage_profile_fragment.xml b/app/src/main/res/layout/manage_profile_fragment.xml index 4a7dce7312..ad4e53a973 100644 --- a/app/src/main/res/layout/manage_profile_fragment.xml +++ b/app/src/main/res/layout/manage_profile_fragment.xml @@ -243,10 +243,10 @@ android:layout_width="24dp" android:layout_height="24dp" android:scaleType="fitCenter" - app:srcCompat="@drawable/ic_compose_24" + app:srcCompat="@drawable/ic_badge_24" app:tint="@color/signal_text_primary" app:layout_constraintTop_toTopOf="@id/manage_profile_badges" - app:layout_constraintBottom_toBottomOf="@id/manage_profile_badges_subtitle" + app:layout_constraintBottom_toBottomOf="@id/manage_profile_badges" app:layout_constraintStart_toStartOf="parent"/> - - + + + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 589ce4a193..86fc5a0bec 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -205,6 +205,9 @@ 28dp 26dp 48dp + 25dp 16dp + + 18dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e7c1af0b8e..fc92145f6d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3854,6 +3854,8 @@ Become a sustainer + Badge +