mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-08 09:18:39 +01:00
Update UI and strings for the duplicate name review screen.
This commit is contained in:
committed by
Cody Henthorne
parent
e7c018283a
commit
bdb34e16c6
+4
-17
@@ -6,7 +6,6 @@
|
|||||||
package org.thoughtcrime.securesms.conversation.v2
|
package org.thoughtcrime.securesms.conversation.v2
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.text.SpannableStringBuilder
|
|
||||||
import android.transition.ChangeBounds
|
import android.transition.ChangeBounds
|
||||||
import android.transition.Slide
|
import android.transition.Slide
|
||||||
import android.transition.TransitionManager
|
import android.transition.TransitionManager
|
||||||
@@ -15,8 +14,6 @@ import android.util.AttributeSet
|
|||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.widget.LinearLayoutCompat
|
import androidx.appcompat.widget.LinearLayoutCompat
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
|
||||||
import androidx.core.transition.addListener
|
import androidx.core.transition.addListener
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView
|
import org.thoughtcrime.securesms.components.identity.UnverifiedBannerView
|
||||||
@@ -28,9 +25,7 @@ import org.thoughtcrime.securesms.database.model.IdentityRecord
|
|||||||
import org.thoughtcrime.securesms.groups.GroupId
|
import org.thoughtcrime.securesms.groups.GroupId
|
||||||
import org.thoughtcrime.securesms.profiles.spoofing.ReviewBannerView
|
import org.thoughtcrime.securesms.profiles.spoofing.ReviewBannerView
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||||
import org.thoughtcrime.securesms.util.ContextUtil
|
|
||||||
import org.thoughtcrime.securesms.util.IdentityUtil
|
import org.thoughtcrime.securesms.util.IdentityUtil
|
||||||
import org.thoughtcrime.securesms.util.SpanUtil
|
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil
|
import org.thoughtcrime.securesms.util.ViewUtil
|
||||||
import org.thoughtcrime.securesms.util.views.Stub
|
import org.thoughtcrime.securesms.util.views.Stub
|
||||||
import org.thoughtcrime.securesms.util.visible
|
import org.thoughtcrime.securesms.util.visible
|
||||||
@@ -114,20 +109,12 @@ class ConversationBannerView @JvmOverloads constructor(
|
|||||||
stub = reviewBannerStub
|
stub = reviewBannerStub
|
||||||
) {
|
) {
|
||||||
if (requestReviewState.individualReviewState != null) {
|
if (requestReviewState.individualReviewState != null) {
|
||||||
val message: CharSequence = SpannableStringBuilder()
|
setBannerMessage(context.getString(R.string.ConversationFragment__review_banner_body))
|
||||||
.append(SpanUtil.bold(context.getString(R.string.ConversationFragment__review_requests_carefully)))
|
setBannerRecipients(requestReviewState.individualReviewState.target, requestReviewState.individualReviewState.firstDuplicate)
|
||||||
.append(" ")
|
setOnClickListener { listener?.onRequestReviewIndividual(requestReviewState.individualReviewState.target.id) }
|
||||||
.append(context.getString(R.string.ConversationFragment__signal_found_another_contact_with_the_same_name))
|
|
||||||
|
|
||||||
setBannerMessage(message)
|
|
||||||
|
|
||||||
val drawable = ContextUtil.requireDrawable(context, R.drawable.symbol_info_24).mutate()
|
|
||||||
DrawableCompat.setTint(drawable, ContextCompat.getColor(context, R.color.signal_icon_tint_primary))
|
|
||||||
setBannerIcon(drawable)
|
|
||||||
setOnClickListener { listener?.onRequestReviewIndividual(requestReviewState.individualReviewState.recipient.id) }
|
|
||||||
} else if (requestReviewState.groupReviewState != null) {
|
} else if (requestReviewState.groupReviewState != null) {
|
||||||
setBannerMessage(context.getString(R.string.ConversationFragment__d_group_members_have_the_same_name, requestReviewState.groupReviewState.count))
|
setBannerMessage(context.getString(R.string.ConversationFragment__d_group_members_have_the_same_name, requestReviewState.groupReviewState.count))
|
||||||
setBannerRecipient(requestReviewState.groupReviewState.recipient)
|
setBannerRecipients(requestReviewState.groupReviewState.target, requestReviewState.groupReviewState.firstDuplicate)
|
||||||
setOnClickListener { listener?.onReviewGroupMembers(requestReviewState.groupReviewState.groupId) }
|
setOnClickListener { listener?.onReviewGroupMembers(requestReviewState.groupReviewState.groupId) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -370,8 +370,16 @@ class ConversationRepository(
|
|||||||
return@fromCallable RequestReviewState()
|
return@fromCallable RequestReviewState()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group == null && ReviewUtil.isRecipientReviewSuggested(recipient.id)) {
|
if (group == null) {
|
||||||
return@fromCallable RequestReviewState(individualReviewState = IndividualReviewState(recipient))
|
val recipientsToReview = ReviewUtil.getRecipientsToPromptForReview(recipient.id)
|
||||||
|
if (recipientsToReview.size > 0) {
|
||||||
|
return@fromCallable RequestReviewState(
|
||||||
|
individualReviewState = IndividualReviewState(
|
||||||
|
target = recipient,
|
||||||
|
firstDuplicate = Recipient.resolvedList(recipientsToReview)[0]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (group != null && group.isV2Group) {
|
if (group != null && group.isV2Group) {
|
||||||
@@ -383,6 +391,7 @@ class ConversationRepository(
|
|||||||
groupReviewState = GroupReviewState(
|
groupReviewState = GroupReviewState(
|
||||||
groupId,
|
groupId,
|
||||||
duplicateRecipients[0],
|
duplicateRecipients[0],
|
||||||
|
duplicateRecipients[1],
|
||||||
duplicateRecipients.size
|
duplicateRecipients.size
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ data class RequestReviewState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Recipient is in message request state and has similar name as someone else */
|
/** Recipient is in message request state and has similar name as someone else */
|
||||||
data class IndividualReviewState(val recipient: Recipient)
|
data class IndividualReviewState(val target: Recipient, val firstDuplicate: Recipient)
|
||||||
|
|
||||||
/** Group has multiple members with similar names */
|
/** Group has multiple members with similar names */
|
||||||
data class GroupReviewState(val groupId: GroupId.V2, val recipient: Recipient, val count: Int)
|
data class GroupReviewState(val groupId: GroupId.V2, val target: Recipient, val firstDuplicate: Recipient, val count: Int)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -69,9 +69,9 @@ public class ReviewBannerView extends FrameLayout {
|
|||||||
binding.bannerAvatarStroke.setVisibility(GONE);
|
binding.bannerAvatarStroke.setVisibility(GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBannerRecipient(@NonNull Recipient recipient) {
|
public void setBannerRecipients(@NonNull Recipient target, @NonNull Recipient dupe) {
|
||||||
binding.bannerTopLeftAvatar.setAvatar(recipient);
|
binding.bannerTopLeftAvatar.setAvatar(target);
|
||||||
binding.bannerBottomRightAvatar.setAvatar(recipient);
|
binding.bannerBottomRightAvatar.setAvatar(dupe);
|
||||||
|
|
||||||
binding.bannerIcon.setVisibility(GONE);
|
binding.bannerIcon.setVisibility(GONE);
|
||||||
binding.bannerTopLeftAvatar.setVisibility(VISIBLE);
|
binding.bannerTopLeftAvatar.setVisibility(VISIBLE);
|
||||||
|
|||||||
-15
@@ -83,13 +83,6 @@ class ReviewCardViewHolder extends RecyclerView.ViewHolder {
|
|||||||
|
|
||||||
binding.cardName.setText(name);
|
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()) {
|
List<ReviewTextRow> rows = switch (reviewCard.getCardType()) {
|
||||||
case MEMBER, REQUEST -> getNonContactSublines(reviewCard);
|
case MEMBER, REQUEST -> getNonContactSublines(reviewCard);
|
||||||
case YOUR_CONTACT -> getContactSublines(reviewCard);
|
case YOUR_CONTACT -> getContactSublines(reviewCard);
|
||||||
@@ -253,14 +246,6 @@ class ReviewCardViewHolder extends RecyclerView.ViewHolder {
|
|||||||
void onSignalConnectionClicked();
|
void onSignalConnectionClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @StringRes int getTitleResId(@NonNull ReviewCard.CardType 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) {
|
private static @StringRes int getActionLabelResId(@NonNull ReviewCard.Action action) {
|
||||||
return switch (action) {
|
return switch (action) {
|
||||||
case UPDATE_CONTACT -> R.string.ReviewCard__update_contact;
|
case UPDATE_CONTACT -> R.string.ReviewCard__update_contact;
|
||||||
|
|||||||
@@ -39,15 +39,17 @@ public final class ReviewUtil {
|
|||||||
* @return Whether or not multiple recipients share this profile name.
|
* @return Whether or not multiple recipients share this profile name.
|
||||||
*/
|
*/
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public static boolean isRecipientReviewSuggested(@NonNull RecipientId recipientId)
|
public static List<RecipientId> getRecipientsToPromptForReview(@NonNull RecipientId recipientId)
|
||||||
{
|
{
|
||||||
Recipient recipient = Recipient.resolved(recipientId);
|
Recipient recipient = Recipient.resolved(recipientId);
|
||||||
|
|
||||||
if (recipient.isGroup() || recipient.isSystemContact()) {
|
if (recipient.isGroup() || recipient.isSystemContact()) {
|
||||||
return false;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
return SignalDatabase.recipients().getSimilarRecipientIds(recipient).size() > 1;
|
return Stream.of(SignalDatabase.recipients().getSimilarRecipientIds(recipient))
|
||||||
|
.filter(id -> !id.equals(recipientId))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
android:layout_marginBottom="18dp"
|
android:layout_marginBottom="18dp"
|
||||||
android:layout_marginHorizontal="@dimen/core_ui__gutter"
|
android:layout_marginHorizontal="@dimen/core_ui__gutter"
|
||||||
android:textAppearance="@style/Signal.Text.BodyMedium"
|
android:textAppearance="@style/Signal.Text.BodyMedium"
|
||||||
android:textColor="@color/signal_colorOutline"
|
android:textColor="@color/signal_colorOnSurfaceVariant"
|
||||||
tools:text="@string/ReviewCardDialogFragment__d_group_members_have_the_same_name" />
|
tools:text="@string/ReviewCardDialogFragment__d_group_members_have_the_same_name" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
|||||||
@@ -19,19 +19,6 @@
|
|||||||
app:layout_constraintStart_toStartOf="@id/card_avatar"
|
app:layout_constraintStart_toStartOf="@id/card_avatar"
|
||||||
app:layout_constraintTop_toTopOf="@id/card_avatar" />
|
app:layout_constraintTop_toTopOf="@id/card_avatar" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/card_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="40dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:textAppearance="@style/TextAppearance.Signal.Body2.Bold"
|
|
||||||
android:textColor="@color/signal_text_secondary"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:text="Member" />
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.AvatarImageView
|
<org.thoughtcrime.securesms.components.AvatarImageView
|
||||||
android:id="@+id/card_avatar"
|
android:id="@+id/card_avatar"
|
||||||
@@ -40,7 +27,7 @@
|
|||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/card_title"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_goneMarginTop="16dp"
|
app:layout_goneMarginTop="16dp"
|
||||||
tools:src="@drawable/ic_person_large" />
|
tools:src="@drawable/ic_person_large" />
|
||||||
|
|
||||||
|
|||||||
@@ -494,8 +494,8 @@
|
|||||||
<string name="ConversationFragment__you_can_add_notes_for_yourself_in_this_conversation">You can add notes for yourself in this chat. If your account has any linked devices, new notes will be synced.</string>
|
<string name="ConversationFragment__you_can_add_notes_for_yourself_in_this_conversation">You can add notes for yourself in this chat. If your account has any linked devices, new notes will be synced.</string>
|
||||||
<string name="ConversationFragment__d_group_members_have_the_same_name">%1$d group members have the same name.</string>
|
<string name="ConversationFragment__d_group_members_have_the_same_name">%1$d group members have the same name.</string>
|
||||||
<string name="ConversationFragment__tap_to_review">Tap to review</string>
|
<string name="ConversationFragment__tap_to_review">Tap to review</string>
|
||||||
<string name="ConversationFragment__review_requests_carefully">Review requests carefully</string>
|
<!-- The body of a banner that can show up at the top of a chat, letting the user know that you have two contacts with the same name -->
|
||||||
<string name="ConversationFragment__signal_found_another_contact_with_the_same_name">Signal found another contact with the same name.</string>
|
<string name="ConversationFragment__review_banner_body">This person has the same name as another contact</string>
|
||||||
<string name="ConversationFragment_contact_us">Contact us</string>
|
<string name="ConversationFragment_contact_us">Contact us</string>
|
||||||
<string name="ConversationFragment_verify">Verify</string>
|
<string name="ConversationFragment_verify">Verify</string>
|
||||||
<string name="ConversationFragment_not_now">Not now</string>
|
<string name="ConversationFragment_not_now">Not now</string>
|
||||||
@@ -4127,8 +4127,10 @@
|
|||||||
<string name="BlockedUsersActivity__s_has_been_unblocked">\"%1$s\" has been unblocked.</string>
|
<string name="BlockedUsersActivity__s_has_been_unblocked">\"%1$s\" has been unblocked.</string>
|
||||||
|
|
||||||
<!-- ReviewCardDialogFragment -->
|
<!-- ReviewCardDialogFragment -->
|
||||||
<string name="ReviewCardDialogFragment__review_members">Review Members</string>
|
<!-- Title of a screen where the user will be prompted to review group members with the same name -->
|
||||||
<string name="ReviewCardDialogFragment__review_request">Review Request</string>
|
<string name="ReviewCardDialogFragment__review_members">Review members</string>
|
||||||
|
<!-- Title of a screen where the user will be prompted to review a message request matching the name of someone they already know -->
|
||||||
|
<string name="ReviewCardDialogFragment__review_request">Review request</string>
|
||||||
<string name="ReviewCardDialogFragment__d_group_members_have_the_same_name">%1$d group members have the same name, review the members below and choose to take action.</string>
|
<string name="ReviewCardDialogFragment__d_group_members_have_the_same_name">%1$d group members have the same name, review the members below and choose to take action.</string>
|
||||||
<string name="ReviewCardDialogFragment__if_youre_not_sure">If you\'re not sure who the request is from, review the contacts below and take action.</string>
|
<string name="ReviewCardDialogFragment__if_youre_not_sure">If you\'re not sure who the request is from, review the contacts below and take action.</string>
|
||||||
<string name="ReviewCardDialogFragment__no_other_groups_in_common">No other groups in common.</string>
|
<string name="ReviewCardDialogFragment__no_other_groups_in_common">No other groups in common.</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user