diff --git a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarImage.kt b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarImage.kt index 8e8daa1c52..6a78a607d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarImage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/avatar/AvatarImage.kt @@ -29,7 +29,7 @@ fun AvatarImage( } else { AndroidView( factory = ::AvatarImageView, - modifier = modifier + modifier = modifier.background(color = Color.Transparent, shape = CircleShape) ) { it.setAvatarUsingProfile(recipient) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewBannerView.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewBannerView.java index 596525842b..7d4c3f2cea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewBannerView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewBannerView.java @@ -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 { diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardAdapter.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardAdapter.java index 5178deb4eb..2432e42d8f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardAdapter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardAdapter.java @@ -44,6 +44,7 @@ class ReviewCardAdapter extends ListAdapter { 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 card = getItem(position); callback.onActionClicked(card, Objects.requireNonNull(card.getSecondaryAction())); } + + @Override + public void onSignalConnectionClicked() { + callback.onSignalConnectionClicked(); + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardDialogFragment.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardDialogFragment.java index d89de6e602..f4e253c897 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardDialogFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardDialogFragment.java @@ -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); + } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardViewHolder.java b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardViewHolder.java index d23d236342..63f6836e12 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardViewHolder.java +++ b/app/src/main/java/org/thoughtcrime/securesms/profiles/spoofing/ReviewCardViewHolder.java @@ -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> 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 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 getNonContactSublines(@NonNull ReviewCard reviewCard) { + List 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 getContactSublines(@NonNull ReviewCard reviewCard) { + List 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 reviewTextRows, @NonNull Context context, @NonNull ReviewCard reviewCard) { + + for (Pair 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 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 } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/about/AboutSheet.kt b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/about/AboutSheet.kt index 5b88c608a2..86210c338b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/about/AboutSheet.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/ui/about/AboutSheet.kt @@ -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() diff --git a/app/src/main/res/drawable/symbol_connections_compact_16.xml b/app/src/main/res/drawable/symbol_connections_compact_16.xml new file mode 100644 index 0000000000..65ae7de9c9 --- /dev/null +++ b/app/src/main/res/drawable/symbol_connections_compact_16.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/symbol_person_circle_compat_16.xml b/app/src/main/res/drawable/symbol_person_circle_compat_16.xml new file mode 100644 index 0000000000..1edd0e9bd3 --- /dev/null +++ b/app/src/main/res/drawable/symbol_person_circle_compat_16.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/drawable/symbol_person_compact_16.xml b/app/src/main/res/drawable/symbol_person_compact_16.xml new file mode 100644 index 0000000000..47dbe0d420 --- /dev/null +++ b/app/src/main/res/drawable/symbol_person_compact_16.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/symbol_person_light_24.xml b/app/src/main/res/drawable/symbol_person_light_24.xml new file mode 100644 index 0000000000..99d0ba0506 --- /dev/null +++ b/app/src/main/res/drawable/symbol_person_light_24.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/symbol_phone_compact_16.xml b/app/src/main/res/drawable/symbol_phone_compact_16.xml new file mode 100644 index 0000000000..80ad4a53a9 --- /dev/null +++ b/app/src/main/res/drawable/symbol_phone_compact_16.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/fragment_review.xml b/app/src/main/res/layout/fragment_review.xml index 80d0dd1046..f9ed20c65d 100644 --- a/app/src/main/res/layout/fragment_review.xml +++ b/app/src/main/res/layout/fragment_review.xml @@ -1,21 +1,21 @@ + android:orientation="vertical" + tools:viewBindingIgnore="true"> - + android:layout_height="wrap_content"> - + 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"> - + - + - + - + - + - + - + - + - + - + - + + \ No newline at end of file diff --git a/app/src/main/res/layout/review_card.xml b/app/src/main/res/layout/review_card.xml index b2995b61ba..cf8ba9c42f 100644 --- a/app/src/main/res/layout/review_card.xml +++ b/app/src/main/res/layout/review_card.xml @@ -1,15 +1,12 @@ + android:background="@drawable/review_card_outline"> + app:layout_constraintTop_toTopOf="@id/card_avatar" /> + tools:text="Maya Johnson" /> + tools:text="Maya recently changed their profile name from Alice Chen to Maya Johnson" /> + + + + + + + + + + + + + app:layout_constraintTop_toTopOf="@id/card_subtext_line4" + app:tint="@color/signal_colorOnSurface" + tools:srcCompat="@drawable/symbol_group_24" /> + + @@ -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" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e35574f2b7..f087dd1de8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1892,6 +1892,10 @@ Review requests carefully %1$d groups in common + + About + + You @@ -2024,6 +2028,12 @@ Viewed Media + + + Name conflict found + + View + No results found for \'%s\' @@ -3992,14 +4002,16 @@ Failed to remove group member. - Member Request Your contact Remove from group Update contact Block Delete - Recently changed their profile name from %1$s to %2$s + + %1$s recently changed their profile name from %2$s to %3$s + + %1$s is in your system contacts %1$s joined