Restyling review banner and cards.

This commit is contained in:
Alex Hart 2023-12-20 13:55:40 -04:00 committed by Clark Chen
parent bb30535afb
commit ca9a629804
15 changed files with 548 additions and 227 deletions

View file

@ -29,7 +29,7 @@ fun AvatarImage(
} else {
AndroidView(
factory = ::AvatarImageView,
modifier = modifier
modifier = modifier.background(color = Color.Transparent, shape = CircleShape)
) {
it.setAvatarUsingProfile(recipient)
}

View file

@ -3,34 +3,26 @@ package org.thoughtcrime.securesms.profiles.spoofing;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.contacts.avatars.FallbackContactPhoto;
import org.thoughtcrime.securesms.contacts.avatars.FallbackPhoto20dp;
import org.thoughtcrime.securesms.contacts.avatars.GeneratedContactPhoto;
import org.thoughtcrime.securesms.conversation.colors.AvatarColor;
import org.thoughtcrime.securesms.databinding.ReviewBannerViewBinding;
import org.thoughtcrime.securesms.recipients.Recipient;
/**
* Banner displayed within a conversation when a review is suggested.
*/
public class ReviewBannerView extends LinearLayout {
public class ReviewBannerView extends FrameLayout {
private ImageView bannerIcon;
private TextView bannerMessage;
private View bannerClose;
private AvatarImageView topLeftAvatar;
private AvatarImageView bottomRightAvatar;
private View stroke;
private OnHideListener onHideListener;
private ReviewBannerViewBinding binding;
private OnHideListener onHideListener;
public ReviewBannerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@ -44,19 +36,14 @@ public class ReviewBannerView extends LinearLayout {
protected void onFinishInflate() {
super.onFinishInflate();
bannerIcon = findViewById(R.id.banner_icon);
bannerMessage = findViewById(R.id.banner_message);
bannerClose = findViewById(R.id.banner_close);
topLeftAvatar = findViewById(R.id.banner_avatar_1);
bottomRightAvatar = findViewById(R.id.banner_avatar_2);
stroke = findViewById(R.id.banner_avatar_stroke);
binding = ReviewBannerViewBinding.bind(this);
FallbackPhotoProvider provider = new FallbackPhotoProvider();
topLeftAvatar.setFallbackPhotoProvider(provider);
bottomRightAvatar.setFallbackPhotoProvider(provider);
binding.bannerBottomRightAvatar.setFallbackPhotoProvider(provider);
binding.bannerTopLeftAvatar.setFallbackPhotoProvider(provider);
bannerClose.setOnClickListener(v -> {
binding.bannerClose.setOnClickListener(v -> {
if (onHideListener != null && onHideListener.onHide()) {
return;
}
@ -70,26 +57,32 @@ public class ReviewBannerView extends LinearLayout {
}
public void setBannerMessage(@Nullable CharSequence charSequence) {
bannerMessage.setText(charSequence);
binding.bannerMessage.setText(charSequence);
}
public void setBannerIcon(@Nullable Drawable icon) {
bannerIcon.setImageDrawable(icon);
binding.bannerIcon.setImageDrawable(icon);
bannerIcon.setVisibility(VISIBLE);
topLeftAvatar.setVisibility(GONE);
bottomRightAvatar.setVisibility(GONE);
stroke.setVisibility(GONE);
binding.bannerIcon.setVisibility(VISIBLE);
binding.bannerTopLeftAvatar.setVisibility(GONE);
binding.bannerBottomRightAvatar.setVisibility(GONE);
binding.bannerAvatarStroke.setVisibility(GONE);
}
public void setBannerRecipient(@NonNull Recipient recipient) {
topLeftAvatar.setAvatar(recipient);
bottomRightAvatar.setAvatar(recipient);
binding.bannerTopLeftAvatar.setAvatar(recipient);
binding.bannerBottomRightAvatar.setAvatar(recipient);
bannerIcon.setVisibility(GONE);
topLeftAvatar.setVisibility(VISIBLE);
bottomRightAvatar.setVisibility(VISIBLE);
stroke.setVisibility(VISIBLE);
binding.bannerIcon.setVisibility(GONE);
binding.bannerTopLeftAvatar.setVisibility(VISIBLE);
binding.bannerBottomRightAvatar.setVisibility(VISIBLE);
binding.bannerAvatarStroke.setVisibility(VISIBLE);
}
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
super.setOnClickListener(l);
binding.bannerTapToReview.setOnClickListener(l);
}
private static final class FallbackPhotoProvider extends Recipient.FallbackPhotoProvider {

View file

@ -44,6 +44,7 @@ class ReviewCardAdapter extends ListAdapter<ReviewCard, ReviewCardViewHolder> {
interface Callbacks {
void onCardClicked(@NonNull ReviewCard card);
void onActionClicked(@NonNull ReviewCard card, @NonNull ReviewCard.Action action);
void onSignalConnectionClicked();
}
private final class CallbacksAdapter implements ReviewCardViewHolder.Callbacks {
@ -70,5 +71,10 @@ class ReviewCardAdapter extends ListAdapter<ReviewCard, ReviewCardViewHolder> {
ReviewCard card = getItem(position);
callback.onActionClicked(card, Objects.requireNonNull(card.getSecondaryAction()));
}
@Override
public void onSignalConnectionClicked() {
callback.onSignalConnectionClicked();
}
}
}

View file

@ -22,6 +22,8 @@ import org.thoughtcrime.securesms.groups.BadGroupIdException;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.ui.bottomsheet.RecipientBottomSheetDialogFragment;
import org.thoughtcrime.securesms.stories.settings.my.SignalConnectionsBottomSheetDialogFragment;
import org.thoughtcrime.securesms.util.BottomSheetUtil;
public class ReviewCardDialogFragment extends FullScreenDialogFragment {
@ -202,5 +204,10 @@ public class ReviewCardDialogFragment extends FullScreenDialogFragment {
viewModel.act(card, action);
}
}
@Override
public void onSignalConnectionClicked() {
new SignalConnectionsBottomSheetDialogFragment().show(getParentFragmentManager(), BottomSheetUtil.STANDARD_BOTTOM_SHEET_FRAGMENT_TAG);
}
}
}

View file

@ -1,31 +1,37 @@
package org.thoughtcrime.securesms.profiles.spoofing;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.util.Pair;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.databinding.ReviewCardBinding;
import org.thoughtcrime.securesms.util.SpanUtil;
import org.whispersystems.signalservice.api.util.Preconditions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class ReviewCardViewHolder extends RecyclerView.ViewHolder {
private final int noGroupsInCommonResId;
private final int groupsInCommonResId;
private final TextView title;
private final AvatarImageView avatar;
private final TextView name;
private final TextView subtextLine1;
private final TextView subtextLine2;
private final Button primaryAction;
private final Button secondaryAction;
private final int noGroupsInCommonResId;
private final int groupsInCommonResId;
private final ReviewCardBinding binding;
private final List<Pair<TextView, ImageView>> subtextGroups;
private final Runnable onSignalConnectionClicked;
public ReviewCardViewHolder(@NonNull View itemView,
@StringRes int noGroupsInCommonResId,
@ -36,69 +42,188 @@ class ReviewCardViewHolder extends RecyclerView.ViewHolder {
this.noGroupsInCommonResId = noGroupsInCommonResId;
this.groupsInCommonResId = groupsInCommonResId;
this.title = itemView.findViewById(R.id.card_title);
this.avatar = itemView.findViewById(R.id.card_avatar);
this.name = itemView.findViewById(R.id.card_name);
this.subtextLine1 = itemView.findViewById(R.id.card_subtext_line1);
this.subtextLine2 = itemView.findViewById(R.id.card_subtext_line2);
this.primaryAction = itemView.findViewById(R.id.card_primary_action_button);
this.secondaryAction = itemView.findViewById(R.id.card_secondary_action_button);
this.binding = ReviewCardBinding.bind(itemView);
this.subtextGroups = Arrays.asList(
Pair.create(binding.cardSubtextLine1, binding.cardSubtextIcon1),
Pair.create(binding.cardSubtextLine2, binding.cardSubtextIcon2),
Pair.create(binding.cardSubtextLine3, binding.cardSubtextIcon3),
Pair.create(binding.cardSubtextLine4, binding.cardSubtextIcon4)
);
itemView.findViewById(R.id.card_tap_target).setOnClickListener(unused -> {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onCardClicked(getAdapterPosition());
if (getBindingAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onCardClicked(getBindingAdapterPosition());
}
});
primaryAction.setOnClickListener(unused -> {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onPrimaryActionItemClicked(getAdapterPosition());
binding.cardPrimaryActionButton.setOnClickListener(unused -> {
if (getBindingAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onPrimaryActionItemClicked(getBindingAdapterPosition());
}
});
secondaryAction.setOnClickListener(unused -> {
if (getAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onSecondaryActionItemClicked(getAdapterPosition());
binding.cardSecondaryActionButton.setOnClickListener(unused -> {
if (getBindingAdapterPosition() != RecyclerView.NO_POSITION) {
callbacks.onSecondaryActionItemClicked(getBindingAdapterPosition());
}
});
onSignalConnectionClicked = callbacks::onSignalConnectionClicked;
}
void bind(@NonNull ReviewCard reviewCard) {
Context context = itemView.getContext();
avatar.setAvatar(reviewCard.getReviewRecipient());
name.setText(reviewCard.getReviewRecipient().getDisplayName(context));
title.setText(getTitleResId(reviewCard.getCardType()));
binding.cardAvatar.setAvatarUsingProfile(reviewCard.getReviewRecipient());
switch (reviewCard.getCardType()) {
case MEMBER:
case REQUEST:
setNonContactSublines(context, reviewCard);
break;
case YOUR_CONTACT:
subtextLine1.setText(reviewCard.getReviewRecipient().getE164().orElse(null));
subtextLine2.setText(getGroupsInCommon(reviewCard.getInCommonGroupsCount()));
break;
default:
throw new AssertionError();
String name = reviewCard.getReviewRecipient().isSelf()
? context.getString(R.string.AboutSheet__you)
: reviewCard.getReviewRecipient().getDisplayName(context);
binding.cardName.setText(name);
int titleTextResId = getTitleResId(reviewCard.getCardType());
if (titleTextResId > 0) {
binding.cardTitle.setText(getTitleResId(reviewCard.getCardType()));
} else {
binding.cardTitle.setVisibility(View.GONE);
}
List<ReviewTextRow> rows = switch (reviewCard.getCardType()) {
case MEMBER, REQUEST -> getNonContactSublines(reviewCard);
case YOUR_CONTACT -> getContactSublines(reviewCard);
};
presentReviewTextRows(rows, context, reviewCard);
setActions(reviewCard);
}
private void setNonContactSublines(@NonNull Context context, @NonNull ReviewCard reviewCard) {
subtextLine1.setText(getGroupsInCommon(reviewCard.getInCommonGroupsCount()));
private List<ReviewTextRow> getNonContactSublines(@NonNull ReviewCard reviewCard) {
List<ReviewTextRow> reviewTextRows = new ArrayList<>(subtextGroups.size());
if (reviewCard.getReviewRecipient().isProfileSharing() && !reviewCard.getReviewRecipient().isSelf()) {
reviewTextRows.add(ReviewTextRow.SIGNAL_CONNECTION);
}
if (reviewCard.getReviewRecipient().isSystemContact()) {
reviewTextRows.add(ReviewTextRow.SYSTEM_CONTACTS);
}
if (reviewCard.getNameChange() != null) {
subtextLine2.setText(SpanUtil.italic(context.getString(R.string.ReviewCard__recently_changed,
reviewCard.getNameChange().previous,
reviewCard.getNameChange().newValue)));
reviewTextRows.add(ReviewTextRow.RECENTLY_CHANGED);
}
reviewTextRows.add(ReviewTextRow.GROUPS_IN_COMMON);
return reviewTextRows;
}
private List<ReviewTextRow> getContactSublines(@NonNull ReviewCard reviewCard) {
List<ReviewTextRow> reviewTextRows = new ArrayList<>(subtextGroups.size());
if (reviewCard.getReviewRecipient().isProfileSharing() && !reviewCard.getReviewRecipient().isSelf()) {
reviewTextRows.add(ReviewTextRow.SIGNAL_CONNECTION);
}
if (reviewCard.getReviewRecipient().isSystemContact()) {
reviewTextRows.add(ReviewTextRow.SYSTEM_CONTACTS);
}
if (reviewCard.getReviewRecipient().hasE164() && reviewCard.getReviewRecipient().shouldShowE164()) {
reviewTextRows.add(ReviewTextRow.PHONE_NUMBER);
}
reviewTextRows.add(ReviewTextRow.GROUPS_IN_COMMON);
return reviewTextRows;
}
private void presentReviewTextRows(@NonNull List<ReviewTextRow> reviewTextRows, @NonNull Context context, @NonNull ReviewCard reviewCard) {
for (Pair<TextView, ImageView> group : subtextGroups) {
setVisibility(View.GONE, group.first, group.second);
}
for (int i = 0; i < Math.min(reviewTextRows.size(), subtextGroups.size()); i++) {
ReviewTextRow row = reviewTextRows.get(i);
Pair<TextView, ImageView> group = subtextGroups.get(i);
setVisibility(View.VISIBLE, group.first, group.second);
switch (row) {
case SIGNAL_CONNECTION -> presentSignalConnection(group.first, group.second, context, reviewCard);
case PHONE_NUMBER -> presentPhoneNumber(group.first, group.second, reviewCard);
case RECENTLY_CHANGED -> presentRecentlyChanged(group.first, group.second, context, reviewCard);
case GROUPS_IN_COMMON -> presentGroupsInCommon(group.first, group.second, reviewCard);
case SYSTEM_CONTACTS -> presentSystemContacts(group.first, group.second, context, reviewCard);
}
}
}
private void presentSignalConnection(@NonNull TextView line, @NonNull ImageView icon, @NonNull Context context, @NonNull ReviewCard reviewCard) {
Preconditions.checkArgument(reviewCard.getReviewRecipient().isProfileSharing());
Drawable chevron = ContextCompat.getDrawable(context, R.drawable.symbol_chevron_right_24);
Preconditions.checkNotNull(chevron);
chevron.setTint(ContextCompat.getColor(context, R.color.core_grey_45));
SpannableStringBuilder builder = new SpannableStringBuilder(context.getString(R.string.AboutSheet__signal_connection));
SpanUtil.appendCenteredImageSpan(builder, chevron, 20, 20);
icon.setImageResource(R.drawable.symbol_connections_compact_16);
line.setText(builder);
line.setOnClickListener(v -> onSignalConnectionClicked.run());
}
private void presentPhoneNumber(@NonNull TextView line, @NonNull ImageView icon, @NonNull ReviewCard reviewCard) {
icon.setImageResource(R.drawable.symbol_phone_compact_16);
line.setText(reviewCard.getReviewRecipient().requireE164());
line.setOnClickListener(null);
line.setClickable(false);
}
private void presentRecentlyChanged(@NonNull TextView line, @NonNull ImageView icon, @NonNull Context context, @NonNull ReviewCard reviewCard) {
Preconditions.checkNotNull(reviewCard.getNameChange());
icon.setImageResource(R.drawable.symbol_person_compact_16);
line.setText(context.getString(R.string.ReviewCard__s_recently_changed,
reviewCard.getReviewRecipient().getShortDisplayName(context),
reviewCard.getNameChange().previous,
reviewCard.getNameChange().newValue));
line.setOnClickListener(null);
line.setClickable(false);
}
private void presentGroupsInCommon(@NonNull TextView line, @NonNull ImageView icon, @NonNull ReviewCard reviewCard) {
icon.setImageResource(R.drawable.symbol_group_compact_16);
line.setText(getGroupsInCommon(reviewCard.getInCommonGroupsCount()));
line.setOnClickListener(null);
line.setClickable(false);
}
private void presentSystemContacts(@NonNull TextView line, @NonNull ImageView icon, @NonNull Context context, @NonNull ReviewCard reviewCard) {
icon.setImageResource(R.drawable.symbol_person_circle_compat_16);
line.setText(context.getString(R.string.ReviewCard__s_is_in_your_system_contacts, reviewCard.getReviewRecipient().getShortDisplayName(context)));
line.setOnClickListener(null);
line.setClickable(false);
}
private void setVisibility(int visibility, View... views) {
for (View view : views) {
view.setVisibility(visibility);
}
}
private void setActions(@NonNull ReviewCard reviewCard) {
setAction(reviewCard.getPrimaryAction(), primaryAction);
setAction(reviewCard.getSecondaryAction(), secondaryAction);
if (reviewCard.getReviewRecipient().isSelf()) {
setAction(null, binding.cardPrimaryActionButton);
setAction(null, binding.cardSecondaryActionButton);
} else {
setAction(reviewCard.getPrimaryAction(), binding.cardPrimaryActionButton);
setAction(reviewCard.getSecondaryAction(), binding.cardSecondaryActionButton);
}
}
private String getGroupsInCommon(int groupsInCommon) {
@ -120,35 +245,36 @@ class ReviewCardViewHolder extends RecyclerView.ViewHolder {
interface Callbacks {
void onCardClicked(int position);
void onPrimaryActionItemClicked(int position);
void onSecondaryActionItemClicked(int position);
void onSignalConnectionClicked();
}
private static @StringRes int getTitleResId(@NonNull ReviewCard.CardType cardType) {
switch (cardType) {
case MEMBER:
return R.string.ReviewCard__member;
case REQUEST:
return R.string.ReviewCard__request;
case YOUR_CONTACT:
return R.string.ReviewCard__your_contact;
default:
throw new IllegalArgumentException("Unsupported card type " + cardType);
}
return switch (cardType) {
case MEMBER -> -1;
case REQUEST -> R.string.ReviewCard__request;
case YOUR_CONTACT -> R.string.ReviewCard__your_contact;
};
}
private static @StringRes int getActionLabelResId(@NonNull ReviewCard.Action action) {
switch (action) {
case UPDATE_CONTACT:
return R.string.ReviewCard__update_contact;
case DELETE:
return R.string.ReviewCard__delete;
case BLOCK:
return R.string.ReviewCard__block;
case REMOVE_FROM_GROUP:
return R.string.ReviewCard__remove_from_group;
default:
throw new IllegalArgumentException("Unsupported action: " + action);
}
return switch (action) {
case UPDATE_CONTACT -> R.string.ReviewCard__update_contact;
case DELETE -> R.string.ReviewCard__delete;
case BLOCK -> R.string.ReviewCard__block;
case REMOVE_FROM_GROUP -> R.string.ReviewCard__remove_from_group;
};
}
private enum ReviewTextRow {
SIGNAL_CONNECTION,
PHONE_NUMBER,
RECENTLY_CHANGED,
GROUPS_IN_COMMON,
SYSTEM_CONTACTS
}
}

View file

@ -127,17 +127,25 @@ private fun AboutSheetContent(
BottomSheets.Handle(modifier = Modifier.padding(top = 6.dp))
}
val avatarOnClick = remember(recipient.profileAvatarFileDetails.hasFile()) {
if (recipient.profileAvatarFileDetails.hasFile()) {
onAvatarClicked
} else {
{ }
}
}
Column(horizontalAlignment = Alignment.CenterHorizontally) {
AvatarImage(
recipient = recipient,
modifier = Modifier
.padding(top = 56.dp)
.size(240.dp)
.clickable(onClick = onAvatarClicked)
.clickable(onClick = avatarOnClick)
)
Text(
text = "About",
text = stringResource(id = if (recipient.isSelf) R.string.AboutSheet__you else R.string.AboutSheet__about),
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier
.fillMaxWidth()

View file

@ -0,0 +1,26 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<group>
<path
android:fillColor="#FF000000"
android:pathData="M5.25 0.72c-1.4 0-2.52 1.14-2.52 2.53 0 1.4 1.13 2.52 2.52 2.52 1.4 0 2.53-1.13 2.53-2.52 0-1.4-1.14-2.53-2.53-2.53ZM4.03 3.25c0-0.68 0.54-1.23 1.22-1.23 0.68 0 1.23 0.55 1.23 1.23 0 0.68-0.55 1.22-1.23 1.22-0.68 0-1.22-0.54-1.22-1.22Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M5.25 10.22c-1.4 0-2.52 1.14-2.52 2.53 0 1.4 1.13 2.53 2.52 2.53 1.4 0 2.53-1.14 2.53-2.53 0-1.4-1.14-2.53-2.53-2.53Zm-1.22 2.53c0-0.68 0.54-1.22 1.22-1.22 0.68 0 1.23 0.54 1.23 1.22 0 0.68-0.55 1.22-1.23 1.22-0.68 0-1.22-0.54-1.22-1.22Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M8.23 3.25c0-1.4 1.13-2.53 2.52-2.53 1.4 0 2.53 1.14 2.53 2.53 0 1.4-1.14 2.52-2.53 2.52-1.4 0-2.52-1.13-2.52-2.52Zm2.52-1.23c-0.68 0-1.22 0.55-1.22 1.23 0 0.68 0.54 1.22 1.22 1.22 0.68 0 1.23-0.54 1.23-1.22 0-0.68-0.55-1.23-1.23-1.23Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M10.75 10.22c-1.4 0-2.52 1.14-2.52 2.53 0 1.4 1.13 2.53 2.52 2.53 1.4 0 2.53-1.14 2.53-2.53 0-1.4-1.14-2.53-2.53-2.53Zm-1.22 2.53c0-0.68 0.54-1.22 1.22-1.22 0.68 0 1.23 0.54 1.23 1.22 0 0.68-0.55 1.22-1.23 1.22-0.68 0-1.22-0.54-1.22-1.22Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M10.85 8c0-1.4 1.13-2.53 2.53-2.53 1.39 0 2.52 1.14 2.52 2.53 0 1.4-1.13 2.53-2.52 2.53-1.4 0-2.53-1.14-2.53-2.53Zm2.53-1.23c-0.68 0-1.23 0.55-1.23 1.23 0 0.68 0.55 1.22 1.23 1.22 0.67 0 1.22-0.54 1.22-1.22 0-0.68-0.55-1.23-1.22-1.23Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M2.63 5.47C1.23 5.47 0.1 6.61 0.1 8c0 1.4 1.13 2.53 2.53 2.53 1.39 0 2.52-1.14 2.52-2.53 0-1.4-1.13-2.53-2.52-2.53ZM1.4 8c0-0.68 0.55-1.23 1.23-1.23 0.67 0 1.22 0.55 1.22 1.23 0 0.68-0.55 1.22-1.22 1.22C1.95 9.22 1.4 8.68 1.4 8Z"/>
</group>
</vector>

View file

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<group>
<path
android:fillColor="#FF000000"
android:pathData="M5.48 6.55c0-1.51 1.04-2.82 2.52-2.82s2.53 1.31 2.53 2.82c0 1.46-1 2.98-2.53 2.98-1.52 0-2.52-1.52-2.52-2.98ZM8 5.03c-0.6 0-1.22 0.55-1.22 1.52 0 1.03 0.67 1.68 1.22 1.68 0.55 0 1.23-0.65 1.23-1.68C9.23 5.58 8.6 5.03 8 5.03Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M0.85 8c0-3.95 3.2-7.15 7.15-7.15s7.15 3.2 7.15 7.15-3.2 7.15-7.15 7.15S0.85 11.95 0.85 8ZM8 2.15C4.77 2.15 2.15 4.77 2.15 8c0 1.56 0.61 2.98 1.6 4.03 0.21-0.22 0.44-0.43 0.69-0.6 0.93-0.68 2.2-1.08 3.56-1.08 1.36 0 2.63 0.4 3.56 1.08 0.25 0.17 0.48 0.38 0.68 0.6 1-1.05 1.61-2.47 1.61-4.03 0-3.23-2.62-5.85-5.85-5.85Zm3.25 10.72c-0.13-0.14-0.28-0.27-0.45-0.4-0.69-0.5-1.68-0.82-2.8-0.82-1.12 0-2.1 0.33-2.8 0.83-0.17 0.12-0.32 0.25-0.45 0.39 0.93 0.62 2.05 0.98 3.25 0.98 1.2 0 2.32-0.36 3.25-0.98Z"/>
</group>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#FF000000"
android:pathData="M8 0.85c-1.7 0-2.9 1.54-2.9 3.31 0 0.9 0.3 1.75 0.8 2.4C6.4 7.18 7.14 7.64 8 7.64c0.86 0 1.6-0.46 2.1-1.1 0.5-0.64 0.8-1.49 0.8-2.39 0-1.77-1.2-3.31-2.9-3.31ZM6.4 4.16c0-1.25 0.8-2.01 1.6-2.01s1.6 0.76 1.6 2.01c0 0.62-0.2 1.2-0.52 1.59-0.31 0.4-0.7 0.6-1.08 0.6-0.38 0-0.77-0.2-1.08-0.6C6.61 5.35 6.4 4.78 6.4 4.16Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M8 8.35c-2.84 0-5.35 1.63-6 3.99-0.13 0.5 0.02 0.98 0.33 1.3 0.29 0.32 0.72 0.51 1.17 0.51h9c0.45 0 0.88-0.19 1.17-0.5 0.3-0.33 0.46-0.8 0.32-1.31C13.35 9.98 10.84 8.35 8 8.35Zm-4.74 4.33C3.71 11.02 5.6 9.65 8 9.65c2.4 0 4.29 1.37 4.74 3.03v0.04c0 0.01 0 0.03-0.02 0.05-0.04 0.04-0.12 0.08-0.22 0.08h-9c-0.1 0-0.18-0.04-0.22-0.08l-0.02-0.05v-0.04Z"/>
</vector>

View file

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12 1.25c-2.53 0-4.37 2.34-4.37 5.1 0 1.41 0.45 2.73 1.21 3.72 0.77 0.99 1.87 1.68 3.16 1.68s2.4-0.7 3.16-1.68c0.76-0.99 1.22-2.31 1.22-3.71 0-2.77-1.85-5.11-4.38-5.11Zm-2.87 5.1c0-2.19 1.4-3.6 2.87-3.6 1.47 0 2.88 1.41 2.88 3.6 0 1.1-0.36 2.1-0.91 2.8-0.55 0.72-1.25 1.1-1.97 1.1s-1.42-0.38-1.97-1.1c-0.55-0.7-0.9-1.7-0.9-2.8Z"/>
<path
android:fillColor="#FF000000"
android:pathData="M12 13.25c-4.55 0-8.49 2.78-9.15 6.63-0.2 1.09 0.73 1.87 1.65 1.87h15c0.92 0 1.84-0.78 1.65-1.87-0.66-3.85-4.6-6.63-9.15-6.63Zm-7.68 6.88c0.51-2.94 3.66-5.38 7.68-5.38s7.17 2.44 7.68 5.38v0.03l-0.02 0.03c-0.03 0.03-0.09 0.06-0.16 0.06h-15c-0.07 0-0.13-0.03-0.16-0.06l-0.02-0.03v-0.03Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:fillColor="#FF000000"
android:pathData="M2.92 1.93c0.84-0.85 2.23-0.75 2.95 0.2l1.41 1.85C7.88 4.76 7.8 5.86 7.1 6.56L6.46 7.2l0.1 0.2c0.17 0.3 0.48 0.72 0.9 1.14 0.42 0.42 0.83 0.73 1.15 0.9 0.07 0.05 0.14 0.08 0.19 0.1L9.44 8.9c0.7-0.7 1.8-0.77 2.58-0.18l1.85 1.4c0.95 0.73 1.05 2.12 0.2 2.96l-0.28 0.28c-1.03 1.04-2.58 1.61-4.08 1.1-1.84-0.63-3.56-1.68-5.03-3.14-1.46-1.47-2.51-3.2-3.14-5.03-0.51-1.5 0.06-3.05 1.1-4.08l0.28-0.28ZM4.84 2.9c-0.25-0.32-0.72-0.35-1-0.06L3.55 3.13C2.78 3.9 2.45 4.95 2.77 5.87c0.57 1.65 1.51 3.2 2.83 4.53 1.32 1.32 2.88 2.26 4.53 2.83 0.92 0.32 1.97-0.01 2.74-0.78l0.28-0.29c0.29-0.28 0.26-0.75-0.06-1l-1.85-1.4c-0.27-0.2-0.64-0.18-0.88 0.05l-0.8 0.81c-0.3 0.3-0.69 0.27-0.9 0.23-0.23-0.04-0.47-0.15-0.68-0.27-0.45-0.25-0.96-0.64-1.44-1.12-0.48-0.48-0.87-0.99-1.12-1.44C5.3 7.81 5.19 7.57 5.15 7.34c-0.04-0.21-0.07-0.6 0.23-0.9l0.8-0.8C6.43 5.4 6.46 5.03 6.25 4.76l-1.4-1.85Z"/>
</vector>

View file

@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
tools:viewBindingIgnore="true">
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
android:textAppearance="@style/Signal.Text.Caption"
android:layout_marginTop="12dp"
android:layout_marginBottom="18dp"
android:layout_marginHorizontal="@dimen/core_ui__gutter"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_colorOutline"
tools:text="@string/ReviewCardDialogFragment__d_group_members_have_the_same_name" />
<androidx.recyclerview.widget.RecyclerView

View file

@ -1,111 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<org.thoughtcrime.securesms.profiles.spoofing.ReviewBannerView
xmlns:android="http://schemas.android.com/apk/res/android"
tools:viewBindingIgnore="true"
<org.thoughtcrime.securesms.profiles.spoofing.ReviewBannerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/review_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="108dp"
android:background="@color/signal_background_primary">
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginHorizontal="12dp"
android:layout_marginVertical="11dp"
android:background="@color/signal_background_primary"
android:minHeight="66dp"
app:cardCornerRadius="12dp"
app:cardElevation="0dp"
app:strokeColor="@color/signal_colorOutline_38"
app:strokeWidth="1dp">
<FrameLayout
android:id="@+id/banner_icon_frame"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/banner_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:scaleType="centerInside" />
<FrameLayout
android:id="@+id/banner_icon_frame"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginHorizontal="15dp"
android:layout_marginStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/banner_avatar_1"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|start"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:visibility="gone"
tools:visibility="visible" />
<ImageView
android:id="@+id/banner_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:importantForAccessibility="no"
android:scaleType="centerInside" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/banner_avatar_stroke"
android:layout_width="29dp"
android:layout_height="29dp"
android:layout_marginStart="11.5dp"
android:layout_marginTop="11.5dp"
android:background="@drawable/circle_tintable"
android:visibility="gone"
app:backgroundTint="?android:windowBackground"
tools:backgroundTint="@color/red_500"
tools:visibility="visible" />
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/banner_top_left_avatar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="top|start"
android:layout_marginStart="2dp"
android:layout_marginTop="2dp"
android:visibility="gone"
tools:visibility="visible" />
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/banner_avatar_2"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end|bottom"
android:layout_marginEnd="2dp"
android:layout_marginBottom="2dp"
android:visibility="gone"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/banner_avatar_stroke"
android:layout_width="29dp"
android:layout_height="29dp"
android:layout_marginStart="11.5dp"
android:layout_marginTop="11.5dp"
android:background="@drawable/circle_tintable"
android:visibility="gone"
app:backgroundTint="?android:windowBackground"
tools:backgroundTint="@color/red_500"
tools:visibility="visible" />
</FrameLayout>
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/banner_bottom_right_avatar"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end|bottom"
android:layout_marginEnd="2dp"
android:layout_marginBottom="2dp"
android:visibility="gone"
tools:visibility="visible" />
<TextView
android:id="@+id/banner_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="72dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="72dp"
android:textAppearance="@style/Signal.Text.Body"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Review requests carefully Signal found another contact with the same name." />
</FrameLayout>
<ImageView
android:id="@+id/banner_close"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerInside"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_x_20" />
<TextView
android:id="@+id/banner_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginVertical="16dp"
android:text="@string/ReviewBannerView__name_conflict_found"
android:textAppearance="@style/Signal.Text.BodyMedium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/banner_tap_to_review"
app:layout_constraintStart_toEndOf="@id/banner_icon_frame"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/banner_tap_to_review"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="16dp"
android:text="@string/ConversationFragment__tap_to_review"
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
android:textColor="?colorAccent"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@id/banner_message"
app:layout_constraintTop_toBottomOf="@id/banner_message" />
<ImageView
android:id="@+id/banner_close"
android:layout_width="48dp"
android:layout_height="48dp"
android:contentDescription="@string/Material3SearchToolbar__close"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_x_20" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.button.MaterialButton
android:id="@+id/banner_tap_to_review"
style="@style/Signal.Widget.Button.Small.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:minWidth="0dp"
android:paddingHorizontal="16dp"
android:paddingVertical="6dp"
android:text="@string/ReviewBannerView__view"
android:textColor="@color/signal_colorOnSecondaryContainer"
app:backgroundTint="@color/signal_colorSurface2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/banner_close"
app:layout_constraintStart_toEndOf="@id/banner_message"
app:layout_constraintTop_toTopOf="parent"
app:strokeWidth="0dp" />
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@drawable/toolbar_shadow"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
</org.thoughtcrime.securesms.profiles.spoofing.ReviewBannerView>

View file

@ -1,15 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:viewBindingIgnore="true"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginHorizontal="@dimen/core_ui__gutter"
android:layout_marginBottom="16dp"
android:background="@drawable/review_card_outline"
android:minHeight="190dp">
android:background="@drawable/review_card_outline">
<View
android:id="@+id/card_tap_target"
@ -17,10 +14,10 @@
android:layout_height="0dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:minHeight="52dp"
app:layout_constraintBottom_toBottomOf="@id/card_subtext_line2"
app:layout_constraintBottom_toBottomOf="@id/card_action_button_barrier"
app:layout_constraintEnd_toEndOf="@id/card_name"
app:layout_constraintStart_toStartOf="@id/card_avatar"
app:layout_constraintTop_toTopOf="@id/card_name" />
app:layout_constraintTop_toTopOf="@id/card_avatar" />
<TextView
android:id="@+id/card_title"
@ -38,12 +35,13 @@
<org.thoughtcrime.securesms.components.AvatarImageView
android:id="@+id/card_avatar"
android:layout_width="52dp"
android:layout_height="52dp"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_title"
app:layout_goneMarginTop="16dp"
tools:src="@drawable/ic_person_large" />
<TextView
@ -51,44 +49,124 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/TextAppearance.Signal.Body1.Bold"
android:textAppearance="@style/Signal.Text.TitleMedium"
app:layout_constraintBottom_toTopOf="@id/card_subtext_line1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintTop_toBottomOf="@id/card_title"
app:layout_constraintTop_toTopOf="@id/card_avatar"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Michelle Tyler" />
tools:text="Maya Johnson" />
<TextView
android:id="@+id/card_subtext_line1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_text_secondary"
app:layout_constraintBottom_toTopOf="@id/card_subtext_line2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintStart_toEndOf="@id/card_subtext_icon1"
app:layout_constraintTop_toBottomOf="@id/card_name"
tools:text="@tools:sample/lorem/random" />
tools:text="Maya recently changed their profile name from Alice Chen to Maya Johnson" />
<ImageView
android:id="@+id/card_subtext_icon1"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintTop_toTopOf="@id/card_subtext_line1"
app:tint="@color/signal_colorOnSurface"
tools:srcCompat="@drawable/symbol_person_compact_16" />
<TextView
android:id="@+id/card_subtext_line2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_text_secondary"
app:layout_constraintBottom_toTopOf="@+id/card_subtext_line3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card_subtext_icon2"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line1"
tools:text="No other groups in common" />
<ImageView
android:id="@+id/card_subtext_icon2"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintTop_toTopOf="@id/card_subtext_line2"
app:tint="@color/signal_colorOnSurface"
tools:srcCompat="@drawable/symbol_group_compact_16" />
<TextView
android:id="@+id/card_subtext_line3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_text_secondary"
app:layout_constraintBottom_toTopOf="@+id/card_subtext_line4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card_subtext_icon3"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line2"
tools:text="No other groups in common" />
<ImageView
android:id="@+id/card_subtext_icon3"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintTop_toTopOf="@id/card_subtext_line3"
app:tint="@color/signal_colorOnSurface"
tools:srcCompat="@drawable/symbol_group_24" />
<TextView
android:id="@+id/card_subtext_line4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="16dp"
android:textAppearance="@style/Signal.Text.BodyMedium"
android:textColor="@color/signal_text_secondary"
app:layout_constraintBottom_toTopOf="@+id/card_action_button_barrier"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/card_subtext_icon4"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line3"
tools:text="No other groups in common" />
<ImageView
android:id="@+id/card_subtext_icon4"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="2dp"
android:importantForAccessibility="no"
app:layout_constraintStart_toEndOf="@id/card_avatar"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line1"
tools:text="@tools:sample/lorem/random" />
app:layout_constraintTop_toTopOf="@id/card_subtext_line4"
app:tint="@color/signal_colorOnSurface"
tools:srcCompat="@drawable/symbol_group_24" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/card_action_button_barrier"
@ -97,6 +175,12 @@
app:barrierDirection="top"
app:constraint_referenced_ids="card_primary_action_button,card_secondary_action_button" />
<Space
app:layout_constraintTop_toBottomOf="@id/card_subtext_line4"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="16dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/card_primary_action_button"
style="@style/Signal.Widget.Button.Large.Secondary"
@ -109,7 +193,7 @@
android:paddingEnd="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line2"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line4"
app:layout_constraintVertical_bias="1.0"
tools:text="@string/ReviewCard__block" />
@ -124,7 +208,7 @@
android:paddingEnd="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/card_primary_action_button"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line2"
app:layout_constraintTop_toBottomOf="@id/card_subtext_line4"
app:layout_constraintVertical_bias="1.0"
tools:text="@string/ReviewCard__delete" />

View file

@ -1892,6 +1892,10 @@
<string name="AboutSheet__review_requests_carefully">Review requests carefully</string>
<!-- Text used when user has groups in common. Placeholder is the count -->
<string name="AboutSheet__d_groups_in_common">%1$d groups in common</string>
<!-- Text displayed in title for external recipients -->
<string name="AboutSheet__about">About</string>
<!-- Text displayed in title for you -->
<string name="AboutSheet__you">You</string>
<!-- CallParticipantsListDialog -->
<plurals name="CallParticipantsListDialog_in_this_call">
@ -2024,6 +2028,12 @@
<string name="RevealableMessageView_viewed">Viewed</string>
<string name="RevealableMessageView_media">Media</string>
<!-- ReviewBannerView -->
<!-- ReviewBannerView text when a name conflict has been found -->
<string name="ReviewBannerView__name_conflict_found">Name conflict found</string>
<!-- Button label to view name conflicts -->
<string name="ReviewBannerView__view">View</string>
<!-- Search -->
<string name="SearchFragment_no_results">No results found for \'%s\'</string>
@ -3992,14 +4002,16 @@
<string name="ReviewCardDialogFragment__failed_to_remove_group_member">Failed to remove group member.</string>
<!-- ReviewCard -->
<string name="ReviewCard__member">Member</string>
<string name="ReviewCard__request">Request</string>
<string name="ReviewCard__your_contact">Your contact</string>
<string name="ReviewCard__remove_from_group">Remove from group</string>
<string name="ReviewCard__update_contact">Update contact</string>
<string name="ReviewCard__block">Block</string>
<string name="ReviewCard__delete">Delete</string>
<string name="ReviewCard__recently_changed">Recently changed their profile name from %1$s to %2$s</string>
<!-- Displayed when a recent name change has occurred. First placeholder is new short name, second is previous name, third is new name. -->
<string name="ReviewCard__s_recently_changed">%1$s recently changed their profile name from %2$s to %3$s</string>
<!-- Displayed when a review user is in your system contacts. Placeholder is short name. -->
<string name="ReviewCard__s_is_in_your_system_contacts">%1$s is in your system contacts</string>
<!-- CallParticipantsListUpdatePopupWindow -->
<string name="CallParticipantsListUpdatePopupWindow__s_joined">%1$s joined</string>