mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 08:39:22 +01:00
Add support for admin delete.
This commit is contained in:
committed by
Cody Henthorne
parent
1968438ebb
commit
071fbfd916
@@ -116,6 +116,7 @@ import org.thoughtcrime.securesms.database.model.Quote;
|
||||
import org.thoughtcrime.securesms.database.model.databaseprotos.MessageExtras;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
import org.thoughtcrime.securesms.events.PartProgressEvent;
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols;
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicy;
|
||||
import org.thoughtcrime.securesms.giph.mp4.GiphyMp4PlaybackPolicyEnforcer;
|
||||
import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob;
|
||||
@@ -1093,16 +1094,8 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
bodyText.setOverflowText(null);
|
||||
bodyText.setMaxLength(-1);
|
||||
|
||||
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)),
|
||||
0,
|
||||
deletedMessage.length(),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
bodyText.setText(italics);
|
||||
if (conversationMessage.getDeletedByRecipient() != null) {
|
||||
bodyText.setText(getDeletedMessageText(conversationMessage));
|
||||
bodyText.setVisibility(View.VISIBLE);
|
||||
bodyText.setOverflowText(null);
|
||||
} else if (isCaptionlessMms(messageRecord) || isStoryReaction(messageRecord) || isGiftMessage(messageRecord) || messageRecord.isPaymentNotification() || messageRecord.isPaymentTombstone()) {
|
||||
@@ -1156,6 +1149,44 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
}
|
||||
|
||||
private SpannableStringBuilder getDeletedMessageText(@NonNull ConversationMessage message) {
|
||||
boolean isAdminDelete = !message.getDeletedByRecipient().equals(message.getMessageRecord().getFromRecipient());
|
||||
CharSequence body;
|
||||
|
||||
if (!isAdminDelete && messageRecord.isOutgoing()) {
|
||||
body = formatDeletedText(context.getString(R.string.ConversationItem_you_deleted_this_message));
|
||||
} else if (!isAdminDelete) {
|
||||
body = formatDeletedText(context.getString(R.string.ConversationItem_this_message_was_deleted));
|
||||
} else {
|
||||
SpannableString prefix = formatDeletedText(context.getString(R.string.ConversationItem_admin));
|
||||
SpannableString suffix = formatDeletedText(context.getString(R.string.ConversationItem_deleted_this_message));
|
||||
|
||||
int nameColor = colorizer.getIncomingGroupSenderColor(getContext(), message.getDeletedByRecipient());
|
||||
SpannableString name = new SpannableString(message.getDeletedByRecipient().getDisplayName(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);
|
||||
|
||||
body = new SpannableStringBuilder()
|
||||
.append(prefix)
|
||||
.append(" ")
|
||||
.append(name)
|
||||
.append(" ")
|
||||
.append(suffix);
|
||||
}
|
||||
|
||||
return new SpannableStringBuilder()
|
||||
.append(SignalSymbols.getSpannedString(getContext(), SignalSymbols.Weight.REGULAR, SignalSymbols.Glyph.X_CIRCLE, org.signal.core.ui.R.color.signal_colorOnSurfaceVariant))
|
||||
.append(" ")
|
||||
.append(body);
|
||||
}
|
||||
|
||||
private SpannableString formatDeletedText(String text) {
|
||||
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);
|
||||
return spannableString;
|
||||
}
|
||||
|
||||
private void setMediaAttributes(@NonNull MessageRecord messageRecord,
|
||||
@NonNull Optional<MessageRecord> previousRecord,
|
||||
@NonNull Optional<MessageRecord> nextRecord,
|
||||
@@ -1668,7 +1699,7 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
|
||||
List<Annotation> mentionAnnotations = MentionAnnotation.getMentionAnnotations(messageBody);
|
||||
for (Annotation annotation : mentionAnnotations) {
|
||||
messageBody.setSpan(new MentionClickableSpan(RecipientId.from(annotation.getValue())), messageBody.getSpanStart(annotation), messageBody.getSpanEnd(annotation), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
messageBody.setSpan(new RecipientClickableSpan(RecipientId.from(annotation.getValue())), messageBody.getSpanStart(annotation), messageBody.getSpanEnd(annotation), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2895,18 +2926,18 @@ public final class ConversationItem extends RelativeLayout implements BindableCo
|
||||
}
|
||||
}
|
||||
|
||||
private class MentionClickableSpan extends ClickableSpan {
|
||||
private final RecipientId mentionedRecipientId;
|
||||
private class RecipientClickableSpan extends ClickableSpan {
|
||||
private final RecipientId recipientId;
|
||||
|
||||
MentionClickableSpan(RecipientId mentionedRecipientId) {
|
||||
this.mentionedRecipientId = mentionedRecipientId;
|
||||
RecipientClickableSpan(RecipientId recipientId) {
|
||||
this.recipientId = recipientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull View widget) {
|
||||
if (eventListener != null && batchSelected.isEmpty()) {
|
||||
VibrateUtil.vibrateTick(context);
|
||||
eventListener.onGroupMemberClicked(mentionedRecipientId, conversationRecipient.get().requireGroupId());
|
||||
eventListener.onGroupMemberClicked(recipientId, conversationRecipient.get().requireGroupId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ public class ConversationMessage {
|
||||
@NonNull private final ComputedProperties computedProperties;
|
||||
@Nullable private final MemberLabel memberLabel;
|
||||
@Nullable private final MemberLabel quoteMemberLabel;
|
||||
@Nullable private final Recipient deletedByRecipient;
|
||||
|
||||
private ConversationMessage(@NonNull MessageRecord messageRecord,
|
||||
@Nullable CharSequence body,
|
||||
@@ -61,7 +62,8 @@ public class ConversationMessage {
|
||||
@Nullable MessageRecord originalMessage,
|
||||
@NonNull ComputedProperties computedProperties,
|
||||
@Nullable MemberLabel memberLabel,
|
||||
@Nullable MemberLabel quoteMemberLabel)
|
||||
@Nullable MemberLabel quoteMemberLabel,
|
||||
@Nullable Recipient deletedByRecipient)
|
||||
{
|
||||
this.messageRecord = messageRecord;
|
||||
this.hasBeenQuoted = hasBeenQuoted;
|
||||
@@ -72,6 +74,7 @@ public class ConversationMessage {
|
||||
this.computedProperties = computedProperties;
|
||||
this.memberLabel = memberLabel;
|
||||
this.quoteMemberLabel = quoteMemberLabel;
|
||||
this.deletedByRecipient = deletedByRecipient;
|
||||
|
||||
if (body != null) {
|
||||
this.body = SpannableString.valueOf(body);
|
||||
@@ -116,6 +119,10 @@ public class ConversationMessage {
|
||||
return quoteMemberLabel;
|
||||
}
|
||||
|
||||
public @Nullable Recipient getDeletedByRecipient() {
|
||||
return deletedByRecipient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
@@ -252,6 +259,7 @@ public class ConversationMessage {
|
||||
FormattedDate formattedDate = getFormattedDate(context, messageRecord);
|
||||
MemberLabel memberLabel = getMemberLabel(messageRecord, threadRecipient);
|
||||
MemberLabel quoteMemberLabel = getQuoteMemberLabel(messageRecord, threadRecipient);
|
||||
Recipient deletedBy = messageRecord.getDeletedBy() != null ? Recipient.resolved(messageRecord.getDeletedBy()) : null;
|
||||
|
||||
return new ConversationMessage(messageRecord,
|
||||
styledAndMentionBody != null ? styledAndMentionBody : mentionsUpdate != null ? mentionsUpdate.getBody() : body,
|
||||
@@ -262,7 +270,8 @@ public class ConversationMessage {
|
||||
originalMessage,
|
||||
new ComputedProperties(formattedDate),
|
||||
memberLabel,
|
||||
quoteMemberLabel);
|
||||
quoteMemberLabel,
|
||||
deletedBy);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2828,7 +2828,10 @@ class ConversationFragment :
|
||||
|
||||
disposables += DeleteDialog.show(
|
||||
context = requireContext(),
|
||||
messageRecords = records
|
||||
messageRecords = records,
|
||||
title = requireContext().resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_title, records.size, records.size),
|
||||
message = requireContext().resources.getQuantityString(R.plurals.ConversationFragment_delete_selected_body, records.size, records.size),
|
||||
isAdmin = conversationGroupViewModel.isAdmin()
|
||||
).observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { (deleted: Boolean, _: Boolean) ->
|
||||
if (!deleted) return@subscribe
|
||||
|
||||
@@ -62,6 +62,10 @@ class ConversationGroupViewModel(
|
||||
disposables.clear()
|
||||
}
|
||||
|
||||
fun isAdmin(): Boolean {
|
||||
return _memberLevel.value?.groupTableMemberLevel == GroupTable.MemberLevel.ADMINISTRATOR
|
||||
}
|
||||
|
||||
fun isNonAdminInAnnouncementGroup(): Boolean {
|
||||
val memberLevel = _memberLevel.value ?: return false
|
||||
return memberLevel.groupTableMemberLevel != GroupTable.MemberLevel.ADMINISTRATOR && memberLevel.isAnnouncementGroup
|
||||
|
||||
Reference in New Issue
Block a user