mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-02 08:23:00 +01:00
Fix chevron appearing below the recipient name.
This commit is contained in:
committed by
Michelle Tang
parent
95149764eb
commit
6fbf4d4ae6
@@ -2,23 +2,16 @@ package org.thoughtcrime.securesms.components.settings.conversation.preferences
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.ContextCompat
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.PreferenceModel
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.util.ContextUtil
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
/**
|
||||
* Renders name, description, about, etc. for a given group or recipient.
|
||||
@@ -44,54 +37,7 @@ object BioTextPreference {
|
||||
) : BioTextPreferenceModel<RecipientModel>() {
|
||||
|
||||
override fun getHeadlineText(context: Context): CharSequence {
|
||||
val name = if (recipient.isSelf) {
|
||||
context.getString(R.string.note_to_self)
|
||||
} else {
|
||||
recipient.getDisplayName(context)
|
||||
}
|
||||
|
||||
if (!recipient.showVerified && !recipient.isIndividual) {
|
||||
return name
|
||||
}
|
||||
|
||||
return SpannableStringBuilder(name).apply {
|
||||
if (recipient.showVerified) {
|
||||
SpanUtil.appendSpacer(this, 8)
|
||||
SpanUtil.appendCenteredImageSpanWithoutSpace(this, ContextUtil.requireDrawable(context, R.drawable.ic_official_28), 28, 28)
|
||||
} else if (recipient.isSystemContact) {
|
||||
val systemContactGlyph = SignalSymbols.getSpannedString(
|
||||
context,
|
||||
SignalSymbols.Weight.BOLD,
|
||||
SignalSymbols.Glyph.PERSON_CIRCLE
|
||||
).let {
|
||||
SpanUtil.ofSize(it, 20)
|
||||
}
|
||||
|
||||
append(" ")
|
||||
append(systemContactGlyph)
|
||||
}
|
||||
|
||||
if (recipient.isIndividual && !recipient.isSelf) {
|
||||
val isLtr = ViewUtil.isLtr(context)
|
||||
val chevronGlyph = SignalSymbols.getSpannedString(
|
||||
context,
|
||||
SignalSymbols.Weight.BOLD,
|
||||
if (isLtr) SignalSymbols.Glyph.CHEVRON_RIGHT else SignalSymbols.Glyph.CHEVRON_LEFT
|
||||
).let {
|
||||
SpanUtil.ofSize(it, 24)
|
||||
}.let {
|
||||
SpanUtil.color(ContextCompat.getColor(context, CoreUiR.color.signal_colorOutline), it)
|
||||
}
|
||||
|
||||
if (isLtr) {
|
||||
append(" ")
|
||||
append(chevronGlyph)
|
||||
} else {
|
||||
insert(0, " ")
|
||||
insert(0, chevronGlyph)
|
||||
}
|
||||
}
|
||||
}
|
||||
return recipient.getDisplayNameForHeadline(context)
|
||||
}
|
||||
|
||||
override fun getSubhead1Text(context: Context): String? {
|
||||
|
||||
@@ -16,7 +16,6 @@ import android.view.View;
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.content.res.AppCompatResources;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@@ -33,11 +32,9 @@ import org.thoughtcrime.securesms.conversation.colors.AvatarGradientColors;
|
||||
import org.thoughtcrime.securesms.conversation.v2.data.AvatarDownloadStateCache;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.databinding.ConversationHeaderViewBinding;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.jobs.AvatarGroupsV2DownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.ContextUtil;
|
||||
import org.thoughtcrime.securesms.util.LongClickMovementMethod;
|
||||
import org.thoughtcrime.securesms.util.SpanUtil;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
@@ -130,23 +127,9 @@ public class ConversationHeaderView extends ConstraintLayout {
|
||||
}
|
||||
|
||||
public String setTitle(@NonNull Recipient recipient, @NonNull Runnable onTitleClicked) {
|
||||
SpannableStringBuilder title = new SpannableStringBuilder(recipient.isSelf() ? getContext().getString(R.string.note_to_self) : recipient.getDisplayName(getContext()));
|
||||
if (recipient.getShowVerified()) {
|
||||
SpanUtil.appendCenteredImageSpan(title, ContextUtil.requireDrawable(getContext(), R.drawable.ic_official_28), 28, 28);
|
||||
}
|
||||
CharSequence title = recipient.getDisplayNameForHeadline(getContext());
|
||||
|
||||
if (recipient.isIndividual() && !recipient.isSelf()) {
|
||||
boolean isLtr = ViewUtil.isLtr(this);
|
||||
CharSequence chevron = SignalSymbols.getSpannedString(getContext(), SignalSymbols.Weight.BOLD, isLtr ? SignalSymbols.Glyph.CHEVRON_RIGHT : SignalSymbols.Glyph.CHEVRON_LEFT, org.signal.core.ui.R.color.signal_colorOutline);
|
||||
|
||||
if (isLtr) {
|
||||
title.append(" ");
|
||||
title.append(SpanUtil.ofSize(chevron, 24));
|
||||
} else {
|
||||
title.insert(0, " ");
|
||||
title.insert(0, SpanUtil.ofSize(chevron, 24));
|
||||
}
|
||||
|
||||
binding.messageRequestTitle.setOnClickListener(v -> onTitleClicked.run());
|
||||
} else {
|
||||
binding.messageRequestTitle.setOnClickListener(null);
|
||||
@@ -225,8 +208,8 @@ public class ConversationHeaderView extends ConstraintLayout {
|
||||
binding.messageRequestProfileNameUnverified.setVisibility(View.VISIBLE);
|
||||
binding.messageRequestProfileNameUnverified.setOnClickListener(view -> onClick.run());
|
||||
|
||||
String substring = forGroup ? getContext().getString(R.string.ConversationFragment_group_names)
|
||||
: getContext().getString(R.string.ConversationFragment_profile_names);
|
||||
String substring = forGroup ? getContext().getString(R.string.ConversationFragment_group_names)
|
||||
: getContext().getString(R.string.ConversationFragment_profile_names);
|
||||
|
||||
String fullString = forGroup ? getContext().getString(R.string.ConversationFragment_group_names_not_verified, substring)
|
||||
: getContext().getString(R.string.ConversationFragment_profile_names_not_verified, substring);
|
||||
@@ -273,8 +256,8 @@ public class ConversationHeaderView extends ConstraintLayout {
|
||||
}
|
||||
|
||||
private void animateAvatarLoading(@NonNull Recipient recipient) {
|
||||
Drawable loadingProfile = AppCompatResources.getDrawable(getContext(), R.drawable.circle_profile_photo);
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(binding.messageRequestAvatar, "alpha", 1f, 0f).setDuration(FADE_DURATION);
|
||||
Drawable loadingProfile = AppCompatResources.getDrawable(getContext(), R.drawable.circle_profile_photo);
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(binding.messageRequestAvatar, "alpha", 1f, 0f).setDuration(FADE_DURATION);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.annotation.AnyThread
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.core.text.buildSpannedString
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
@@ -41,6 +42,7 @@ import org.thoughtcrime.securesms.database.model.ProfileAvatarFileDetails
|
||||
import org.thoughtcrime.securesms.database.model.RecipientRecord
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.RecipientExtras
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels
|
||||
@@ -48,18 +50,22 @@ import org.thoughtcrime.securesms.phonenumbers.NumberUtil
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName
|
||||
import org.thoughtcrime.securesms.recipients.Recipient.Companion.external
|
||||
import org.thoughtcrime.securesms.service.webrtc.links.CallLinkRoomId
|
||||
import org.thoughtcrime.securesms.util.ContextUtil
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.SignalE164Util
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil.isValidUsernameForSearch
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress
|
||||
import org.whispersystems.signalservice.api.util.OptionalUtil
|
||||
import java.util.LinkedList
|
||||
import java.util.Objects
|
||||
import java.util.Optional
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
/**
|
||||
* A recipient represents something you can send messages to, or receive messages from. They could be individuals, groups, or even distribution lists.
|
||||
* A recipient represents something you can send messages to or receive messages from. They could be individuals, groups, or even distribution lists.
|
||||
* This class is a snapshot of common state that is used to present recipients through the UI.
|
||||
*
|
||||
* It's important to note that this is only a snapshot, and the actual state of a recipient can change over time.
|
||||
@@ -387,13 +393,14 @@ class Recipient(
|
||||
* The badge to feature on a recipient's avatar, if any.
|
||||
* This value respects the local user's [SignalStore.inAppPayments.getDisplayBadgesOnProfile()] preference.
|
||||
*/
|
||||
val featuredBadge: Badge? get() {
|
||||
return if (isSelf && !SignalStore.inAppPayments.getDisplayBadgesOnProfile()) {
|
||||
null
|
||||
} else {
|
||||
badges.firstOrNull()
|
||||
val featuredBadge: Badge?
|
||||
get() {
|
||||
return if (isSelf && !SignalStore.inAppPayments.getDisplayBadgesOnProfile()) {
|
||||
null
|
||||
} else {
|
||||
badges.firstOrNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A string combining the about emoji + text for displaying various places. */
|
||||
val combinedAboutAndEmoji: String? by lazy { listOf(aboutEmoji, about).filter { it.isNotNullOrBlank() }.joinToString(separator = " ").nullIfBlank() }
|
||||
@@ -659,6 +666,47 @@ class Recipient(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipient's display name with any applicable decorations:
|
||||
* - A badge icon for verified recipients
|
||||
* - A person-circle glyph for system contacts
|
||||
* - A directional chevron for tappable individual profiles
|
||||
*/
|
||||
fun getDisplayNameForHeadline(context: Context): CharSequence {
|
||||
val name = if (isSelf) context.getString(R.string.note_to_self) else getDisplayName(context)
|
||||
|
||||
return buildSpannedString {
|
||||
append(name)
|
||||
|
||||
if (showVerified) {
|
||||
val verifiedBadge = ContextUtil.requireDrawable(context, R.drawable.ic_official_28)
|
||||
SpanUtil.appendSpacer(this, 8)
|
||||
SpanUtil.appendCenteredImageSpanWithoutSpace(this, verifiedBadge, 28, 28)
|
||||
} else if (isSystemContact) {
|
||||
val systemContactGlyph = SignalSymbols
|
||||
.getSpannedString(context, SignalSymbols.Weight.BOLD, SignalSymbols.Glyph.PERSON_CIRCLE)
|
||||
.let { SpanUtil.ofSize(it, 20) }
|
||||
|
||||
append("\u00A0")
|
||||
append(systemContactGlyph)
|
||||
}
|
||||
|
||||
if (isIndividual && !isSelf) {
|
||||
val isLtr = ViewUtil.isLtr(context)
|
||||
val chevronGlyph = SignalSymbols.getSpannedString(context, SignalSymbols.Weight.BOLD, if (isLtr) SignalSymbols.Glyph.CHEVRON_RIGHT else SignalSymbols.Glyph.CHEVRON_LEFT, CoreUiR.color.signal_colorOutline)
|
||||
.let { SpanUtil.ofSize(it, 24) }
|
||||
|
||||
if (isLtr) {
|
||||
append("\u00A0")
|
||||
append(chevronGlyph)
|
||||
} else {
|
||||
insert(0, "\u00A0")
|
||||
insert(0, chevronGlyph)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getFallbackAvatar(): FallbackAvatar {
|
||||
return if (isSelf) {
|
||||
FallbackAvatar.Resource.Local(avatarColor)
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.content.ActivityNotFoundException
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -34,7 +33,6 @@ import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsIcon
|
||||
import org.thoughtcrime.securesms.components.settings.conversation.preferences.ButtonStripPreference
|
||||
import org.thoughtcrime.securesms.conversation.v2.data.AvatarDownloadStateCache
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabelEducationSheet
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabelPillView
|
||||
@@ -45,11 +43,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil
|
||||
import org.thoughtcrime.securesms.recipients.ui.about.AboutSheet
|
||||
import org.thoughtcrime.securesms.util.ContextUtil
|
||||
import org.thoughtcrime.securesms.util.SpanUtil
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.util.WindowUtil
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import org.signal.core.ui.R as CoreUiR
|
||||
|
||||
/**
|
||||
* A bottom sheet that shows some simple recipient details, as well as some actions (like calling,
|
||||
@@ -216,42 +211,13 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
tapToView.setOnClickListener(null)
|
||||
}
|
||||
|
||||
val name = if (recipient.isSelf) requireContext().getString(R.string.note_to_self) else recipient.getDisplayName(requireContext())
|
||||
|
||||
fullName.visible = name.isNotEmpty()
|
||||
val nameBuilder = SpannableStringBuilder(name)
|
||||
if (recipient.showVerified) {
|
||||
SpanUtil.appendSpacer(nameBuilder, 8)
|
||||
SpanUtil.appendCenteredImageSpanWithoutSpace(nameBuilder, ContextUtil.requireDrawable(requireContext(), R.drawable.ic_official_28), 28, 28)
|
||||
} else if (recipient.isSystemContact) {
|
||||
val systemContactGlyph = SignalSymbols.getSpannedString(
|
||||
requireContext(),
|
||||
SignalSymbols.Weight.BOLD,
|
||||
SignalSymbols.Glyph.PERSON_CIRCLE
|
||||
)
|
||||
|
||||
nameBuilder.append(" ")
|
||||
nameBuilder.append(SpanUtil.ofSize(systemContactGlyph, 20))
|
||||
val name = recipient.getDisplayNameForHeadline(requireContext())
|
||||
fullName.apply {
|
||||
text = name
|
||||
visible = name.isNotEmpty()
|
||||
}
|
||||
|
||||
if (!recipient.isSelf && recipient.isIndividual) {
|
||||
val isLtr = ViewUtil.isLtr(view)
|
||||
val chevronGlyph = SignalSymbols.getSpannedString(
|
||||
requireContext(),
|
||||
SignalSymbols.Weight.BOLD,
|
||||
if (isLtr) SignalSymbols.Glyph.CHEVRON_RIGHT else SignalSymbols.Glyph.CHEVRON_LEFT,
|
||||
CoreUiR.color.signal_colorOutline
|
||||
)
|
||||
|
||||
if (isLtr) {
|
||||
nameBuilder.append(" ")
|
||||
nameBuilder.append(SpanUtil.ofSize(chevronGlyph, 24))
|
||||
} else {
|
||||
nameBuilder.insert(0, " ")
|
||||
nameBuilder.insert(0, SpanUtil.ofSize(chevronGlyph, 24))
|
||||
}
|
||||
|
||||
fullName.text = nameBuilder
|
||||
fullName.setOnClickListener {
|
||||
dismiss()
|
||||
AboutSheet.create(recipient).show(getParentFragmentManager(), null)
|
||||
@@ -261,8 +227,8 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
nickname.setOnClickListener {
|
||||
nicknameLauncher.launch(NicknameActivity.Args(recipientId, false))
|
||||
}
|
||||
} else if (recipient.isReleaseNotes) {
|
||||
fullName.text = name
|
||||
} else {
|
||||
fullName.setOnClickListener(null)
|
||||
}
|
||||
|
||||
noteToSelfDescription.visible = recipient.isSelf
|
||||
|
||||
Reference in New Issue
Block a user