Update deleted messages UI.

This commit is contained in:
Michelle Tang 2026-06-17 11:35:57 -04:00 committed by Greyson Parrelli
parent a5e11abdc9
commit 33ca1132dc
2 changed files with 51 additions and 17 deletions

View File

@ -429,7 +429,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
setGutterSizes(messageRecord, groupThread);
setMessageShape(messageRecord, previousMessageRecord, nextMessageRecord, groupThread);
setMediaAttributes(messageRecord, previousMessageRecord, nextMessageRecord, groupThread, hasWallpaper, isMessageRequestAccepted, allowedToPlayInline);
setBodyText(messageRecord, searchQuery, isMessageRequestAccepted);
setBodyText(messageRecord, searchQuery, isMessageRequestAccepted, hasWallpaper);
setBubbleState(messageRecord, messageRecord.getFromRecipient(), hasWallpaper, colorizer);
setInteractionState(conversationMessage, pulse);
setStatusIcons(messageRecord, hasWallpaper);
@ -941,14 +941,22 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
footer.setRevealDotColor(colorizer.getOutgoingFooterIconColor(context));
footer.setOnlyShowSendingStatus(false, messageRecord);
} else if (messageRecord.isRemoteDelete()) {
if (hasWallpaper) {
bodyBubble.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.wallpaper_bubble_color), PorterDuff.Mode.SRC_IN);
if (messageRecord.isOutgoing() && hasWallpaper) {
bodyBubble.getBackground().setColorFilter(recipient.getChatColors().getChatBubbleColorFilter());
footer.setTextColor(colorizer.getOutgoingFooterTextColor(context));
footer.setIconColor(colorizer.getOutgoingFooterIconColor(context));
footer.setRevealDotColor(colorizer.getOutgoingFooterIconColor(context));
} else if (hasWallpaper) {
bodyBubble.getBackground().setColorFilter(getDefaultBubbleColor(true), PorterDuff.Mode.SRC_IN);
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
footer.setIconColor(ContextCompat.getColor(context, org.signal.core.ui.R.color.signal_colorNeutralVariantInverse));
footer.setRevealDotColor(ContextCompat.getColor(context, org.signal.core.ui.R.color.signal_colorNeutralVariantInverse));
} else {
bodyBubble.getBackground().setColorFilter(ContextCompat.getColor(context, R.color.signal_background_primary), PorterDuff.Mode.MULTIPLY);
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
footer.setIconColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
footer.setRevealDotColor(ContextCompat.getColor(context, R.color.signal_icon_tint_secondary));
}
footer.setTextColor(ContextCompat.getColor(context, R.color.signal_text_secondary));
footer.setOnlyShowSendingStatus(messageRecord.isRemoteDelete(), messageRecord);
} else {
bodyBubble.getBackground().setColorFilter(getDefaultBubbleColor(hasWallpaper), PorterDuff.Mode.SRC_IN);
@ -1143,7 +1151,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
private void setBodyText(@NonNull MessageRecord messageRecord,
@Nullable String searchQuery,
boolean messageRequestAccepted)
boolean messageRequestAccepted,
boolean hasWallpaper)
{
bodyText.setClickable(false);
bodyText.setFocusable(false);
@ -1154,14 +1163,16 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
bodyText.setMaxLength(-1);
if (RemoteConfig.receiveAdminDelete() && conversationMessage.getDeletedByRecipient() != null) {
bodyText.setText(getDeletedMessageText(conversationMessage));
bodyText.setText(getDeletedMessageText(conversationMessage, hasWallpaper));
bodyText.setVisibility(View.VISIBLE);
bodyText.setOverflowText(null);
} else if (messageRecord.isRemoteDelete()) {
String deletedMessage = context.getString(messageRecord.isOutgoing() ? R.string.ConversationItem_you_deleted_this_message : R.string.ConversationItem_this_message_was_deleted);
SpannableString italics = new SpannableString(deletedMessage);
italics.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, deletedMessage.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
italics.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, R.color.signal_text_primary)),
int textColor = messageRecord.isOutgoing() && hasWallpaper ? colorizer.getOutgoingDeleteTextColor(context)
: ContextCompat.getColor(context, R.color.signal_text_primary);
italics.setSpan(new ForegroundColorSpan(textColor),
0,
deletedMessage.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -1220,40 +1231,44 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
}
}
private SpannableStringBuilder getDeletedMessageText(@NonNull ConversationMessage message) {
private SpannableStringBuilder getDeletedMessageText(@NonNull ConversationMessage message, boolean hasWallpaper) {
boolean isAdminDelete = !message.getDeletedByRecipient().equals(message.getMessageRecord().getFromRecipient());
boolean useOutgoing = message.getMessageRecord().isOutgoing() && hasWallpaper;
int textColor = useOutgoing ? colorizer.getOutgoingDeleteTextColor(context)
: ContextCompat.getColor(context, org.signal.core.ui.R.color.signal_colorOnSurfaceVariant);
int nameColor = useOutgoing ? colorizer.getOutgoingDeleteNameColor(context)
: colorizer.getIncomingGroupSenderColor(getContext(), message.getDeletedByRecipient());
CharSequence body;
if (message.getDeletedByRecipient().equals(Recipient.self())) {
body = formatDeletedText(context.getString(R.string.ConversationItem_you_deleted_this_message));
body = formatDeletedText(context.getString(R.string.ConversationItem_you_deleted_this_message), textColor);
} else if (!isAdminDelete) {
body = formatDeletedText(context.getString(R.string.ConversationItem_s_deleted_this_message, message.getDeletedByRecipient().getShortDisplayName(context)));
body = formatDeletedText(context.getString(R.string.ConversationItem_s_deleted_this_message, message.getDeletedByRecipient().getShortDisplayName(context)), textColor);
} else {
String template = context.getString(R.string.ConversationItem_admin_s_deleted_this_message, SpanUtil.SPAN_PLACE_HOLDER);
int start = template.indexOf(SpanUtil.SPAN_PLACE_HOLDER);
int nameColor = colorizer.getIncomingGroupSenderColor(getContext(), message.getDeletedByRecipient());
SpannableString name = new SpannableString(message.getDeletedByRecipient().getShortDisplayName(context));
SpannableString name = new SpannableString(message.getDeletedByRecipient().getShortDisplayName(context));
name.setSpan(new ForegroundColorSpan(nameColor), 0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
name.setSpan(new RecipientClickableSpan(conversationMessage.getDeletedByRecipient().getId()), 0, name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
name.setSpan(new StyleSpan(Typeface.BOLD), 0, name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
SpannableStringBuilder builder = new SpannableStringBuilder(template);
builder.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, org.signal.core.ui.R.color.signal_colorOnSurfaceVariant)), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.setSpan(new ForegroundColorSpan(textColor), 0, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
builder.replace(start, start + SpanUtil.SPAN_PLACE_HOLDER.length(), name);
body = builder;
}
return new SpannableStringBuilder()
.append(SignalSymbols.getSpannedString(getContext(), SignalSymbols.Weight.REGULAR, SignalSymbols.Glyph.X_CIRCLE, org.signal.core.ui.R.color.signal_colorOnSurfaceVariant))
.append(SpanUtil.color(textColor, SignalSymbols.getSpannedString(getContext(), SignalSymbols.Weight.REGULAR, SignalSymbols.Glyph.X_CIRCLE, -1)))
.append(" ")
.append(body);
}
private SpannableString formatDeletedText(String text) {
private SpannableString formatDeletedText(String text, int textColor) {
SpannableString spannableString = new SpannableString(text);
spannableString.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, org.signal.core.ui.R.color.signal_colorOnSurfaceVariant)), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new ForegroundColorSpan(textColor), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannableString;
}
@ -2487,7 +2502,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
if ((messageRecord.isOutgoing() || !outgoingOnly) &&
!hasNoBubble(messageRecord) &&
!messageRecord.isRemoteDelete() &&
(!messageRecord.isRemoteDelete() || (hasWallpaper && messageRecord.isOutgoing())) &&
bodyBubbleCorners != null &&
bodyBubble.getVisibility() == VISIBLE)
{

View File

@ -4,6 +4,7 @@ import android.content.Context
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import org.signal.core.models.ServiceId
import org.signal.core.ui.util.ThemeUtil
import org.signal.core.util.orNull
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.recipients.Recipient
@ -58,6 +59,24 @@ interface Colorizer {
}
}
@ColorInt
fun getOutgoingDeleteTextColor(context: Context): Int {
return if (ThemeUtil.isDarkTheme(context)) {
ContextCompat.getColor(context, CoreUiR.color.signal_colorNeutralVariantInverse)
} else {
ContextCompat.getColor(context, CoreUiR.color.signal_colorNeutralVariant)
}
}
@ColorInt
fun getOutgoingDeleteNameColor(context: Context): Int {
return if (ThemeUtil.isDarkTheme(context)) {
ContextCompat.getColor(context, CoreUiR.color.signal_colorNeutralInverse)
} else {
ContextCompat.getColor(context, CoreUiR.color.signal_colorNeutral)
}
}
@ColorInt
fun getIncomingGroupSenderColor(context: Context, recipient: Recipient): Int {
return getNameColor(context, recipient).getColor(context)