mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-23 02:10:44 +01:00
Add support for blocked chat events.
This commit is contained in:
committed by
Greyson Parrelli
parent
8101fcbd8d
commit
f61109391a
@@ -78,13 +78,11 @@ public class FromTextView extends SimpleEmojiTextView {
|
||||
|
||||
setText(builder);
|
||||
|
||||
if (recipient.isBlocked()) setCompoundDrawablesRelativeWithIntrinsicBounds(getBlocked(), null, null, null);
|
||||
else if (RemoteConfig.getInlinePinnedChats() && isPinned) setCompoundDrawablesRelativeWithIntrinsicBounds(getPinned(), null, null, null);
|
||||
else setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
private Drawable getBlocked() {
|
||||
return getDrawable(R.drawable.symbol_block_16, R.color.signal_icon_tint_secondary);
|
||||
if (RemoteConfig.getInlinePinnedChats() && isPinned) {
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(getPinned(), null, null, null);
|
||||
} else {
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private Drawable getMuted() {
|
||||
|
||||
@@ -503,7 +503,8 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
|
||||
thread.isOutgoingAudioCall() ||
|
||||
thread.isOutgoingVideoCall() ||
|
||||
thread.isVerificationStatusChange() ||
|
||||
thread.isScheduledMessage())
|
||||
thread.isScheduledMessage() ||
|
||||
thread.getRecipient().isBlocked())
|
||||
{
|
||||
deliveryStatusIndicator.setNone();
|
||||
alertView.setNone();
|
||||
@@ -586,6 +587,8 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
|
||||
} else {
|
||||
return emphasisAdded(context, context.getString(R.string.ThreadRecord_message_request), defaultTint);
|
||||
}
|
||||
} else if (thread.getRecipient().isBlocked()) {
|
||||
return emphasisAdded(context, context.getString(R.string.ThreadRecord_blocked), R.drawable.symbol_block_16, defaultTint);
|
||||
} else if (MessageTypes.isGroupUpdate(thread.getType())) {
|
||||
if (thread.getRecipient().isPushV2Group()) {
|
||||
if (thread.getMessageExtras() != null) {
|
||||
|
||||
@@ -420,6 +420,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$TYPE & ${MessageTypes.KEY_EXCHANGE_IDENTITY_VERIFIED_BIT} = 0 AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_REPORTED_SPAM} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_MESSAGE_REQUEST_ACCEPTED} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_BLOCKED} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_UNBLOCKED} AND
|
||||
$TYPE NOT IN (
|
||||
${MessageTypes.PROFILE_CHANGE_TYPE},
|
||||
${MessageTypes.GV1_MIGRATION_TYPE},
|
||||
@@ -1911,7 +1913,9 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$TYPE != ${MessageTypes.RELEASE_CHANNEL_DONATION_REQUEST_TYPE} AND
|
||||
$TYPE & ${MessageTypes.GROUP_V2_LEAVE_BITS} != ${MessageTypes.GROUP_V2_LEAVE_BITS} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_REPORTED_SPAM} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_MESSAGE_REQUEST_ACCEPTED}
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_MESSAGE_REQUEST_ACCEPTED} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_BLOCKED} AND
|
||||
$TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} != ${MessageTypes.SPECIAL_TYPE_UNBLOCKED}
|
||||
)
|
||||
"""
|
||||
|
||||
@@ -2556,6 +2560,18 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
sentTimeMillis = timestamp,
|
||||
expiresIn = expiresIn
|
||||
)
|
||||
} else if (MessageTypes.isBlocked(outboxType)) {
|
||||
OutgoingMessage.blockedMessage(
|
||||
threadRecipient = threadRecipient,
|
||||
sentTimeMillis = timestamp,
|
||||
expiresIn = expiresIn
|
||||
)
|
||||
} else if (MessageTypes.isUnblocked(outboxType)) {
|
||||
OutgoingMessage.unblockedMessage(
|
||||
threadRecipient = threadRecipient,
|
||||
sentTimeMillis = timestamp,
|
||||
expiresIn = expiresIn
|
||||
)
|
||||
} else {
|
||||
val giftBadge: GiftBadge? = if (body != null && MessageTypes.isGiftBadge(outboxType)) {
|
||||
GiftBadge.ADAPTER.decode(Base64.decode(body))
|
||||
@@ -2727,6 +2743,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
!MessageTypes.isReportedSpam(type) &&
|
||||
!MessageTypes.isMessageRequestAccepted(type) &&
|
||||
!MessageTypes.isExpirationTimerUpdate(type) &&
|
||||
!MessageTypes.isBlocked(type) &&
|
||||
!MessageTypes.isUnblocked(type) &&
|
||||
!retrieved.storyType.isStory &&
|
||||
isNotStoryGroupReply &&
|
||||
!silent
|
||||
@@ -2860,8 +2878,8 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
fun insertMessageOutbox(
|
||||
message: OutgoingMessage,
|
||||
threadId: Long,
|
||||
forceSms: Boolean,
|
||||
insertListener: InsertListener?
|
||||
forceSms: Boolean = false,
|
||||
insertListener: InsertListener? = null
|
||||
): Long {
|
||||
return insertMessageOutbox(
|
||||
message = message,
|
||||
@@ -2904,7 +2922,16 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
if (message.isGroup) {
|
||||
if (message.isV2Group) {
|
||||
if (message.isBlocked) {
|
||||
type = type or MessageTypes.GROUP_V2_BIT or MessageTypes.SPECIAL_TYPE_BLOCKED
|
||||
hasSpecialType = true
|
||||
} else if (message.isUnblocked) {
|
||||
if (hasSpecialType) {
|
||||
throw MmsException("Cannot insert message with multiple special types.")
|
||||
}
|
||||
type = type or MessageTypes.GROUP_V2_BIT or MessageTypes.SPECIAL_TYPE_UNBLOCKED
|
||||
hasSpecialType = true
|
||||
} else if (message.isV2Group) {
|
||||
type = type or (MessageTypes.GROUP_V2_BIT or MessageTypes.GROUP_UPDATE_BIT)
|
||||
|
||||
if (message.isJustAGroupLeave) {
|
||||
@@ -2926,6 +2953,9 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
if (message.isStoryReaction) {
|
||||
if (hasSpecialType) {
|
||||
throw MmsException("Cannot insert message with multiple special types.")
|
||||
}
|
||||
type = type or MessageTypes.SPECIAL_TYPE_STORY_REACTION
|
||||
hasSpecialType = true
|
||||
}
|
||||
@@ -2978,6 +3008,22 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
hasSpecialType = true
|
||||
}
|
||||
|
||||
if (message.isBlocked && !message.isGroup) {
|
||||
if (hasSpecialType) {
|
||||
throw MmsException("Cannot insert message with multiple special types.")
|
||||
}
|
||||
type = type or MessageTypes.SPECIAL_TYPE_BLOCKED
|
||||
hasSpecialType = true
|
||||
}
|
||||
|
||||
if (message.isUnblocked && !message.isGroup) {
|
||||
if (hasSpecialType) {
|
||||
throw MmsException("Cannot insert message with multiple special types.")
|
||||
}
|
||||
type = type or MessageTypes.SPECIAL_TYPE_UNBLOCKED
|
||||
hasSpecialType = true
|
||||
}
|
||||
|
||||
val earlyDeliveryReceipts: Map<RecipientId, Receipt> = earlyDeliveryReceiptCache.remove(message.sentTimeMillis)
|
||||
|
||||
if (earlyDeliveryReceipts.isNotEmpty()) {
|
||||
|
||||
@@ -248,4 +248,12 @@ public abstract class DisplayRecord {
|
||||
public boolean isMessageRequestAccepted() {
|
||||
return MessageTypes.isMessageRequestAccepted(type);
|
||||
}
|
||||
|
||||
public boolean isBlocked() {
|
||||
return MessageTypes.isBlocked(type);
|
||||
}
|
||||
|
||||
public boolean isUnblocked() {
|
||||
return MessageTypes.isUnblocked(type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +283,10 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_reported_as_spam), R.drawable.symbol_spam_16);
|
||||
} else if (isMessageRequestAccepted()) {
|
||||
return staticUpdateDescription(context.getString(R.string.MessageRecord_you_accepted_the_message_request), R.drawable.symbol_thread_16);
|
||||
} else if (isBlocked()) {
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_blocked_this_group : R.string.MessageRecord_you_blocked_this_person), R.drawable.symbol_block_16);
|
||||
} else if (isUnblocked()) {
|
||||
return staticUpdateDescription(context.getString(isGroupV2() ? R.string.MessageRecord_you_unblocked_this_group : R.string.MessageRecord_you_unblocked_this_person) , R.drawable.symbol_thread_16);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -688,7 +692,8 @@ public abstract class MessageRecord extends DisplayRecord {
|
||||
isEndSession() || isIdentityUpdate() || isIdentityVerified() || isIdentityDefault() ||
|
||||
isProfileChange() || isGroupV1MigrationEvent() || isChatSessionRefresh() || isBadDecryptType() ||
|
||||
isChangeNumber() || isReleaseChannelDonationRequest() || isThreadMergeEventType() || isSmsExportType() || isSessionSwitchoverEventType() ||
|
||||
isPaymentsRequestToActivate() || isPaymentsActivated() || isReportedSpam() || isMessageRequestAccepted();
|
||||
isPaymentsRequestToActivate() || isPaymentsActivated() || isReportedSpam() || isMessageRequestAccepted() ||
|
||||
isBlocked() || isUnblocked();
|
||||
}
|
||||
|
||||
public boolean isMediaPending() {
|
||||
|
||||
@@ -317,6 +317,8 @@ public class MmsMessageRecord extends MessageRecord {
|
||||
(type & MessageTypes.KEY_EXCHANGE_MASK) == 0 &&
|
||||
!isReportedSpam() &&
|
||||
!isMessageRequestAccepted() &&
|
||||
!isBlocked() &&
|
||||
!isUnblocked() &&
|
||||
storyType == StoryType.NONE &&
|
||||
getDateSent() > 0 &&
|
||||
(parentStoryId == null || parentStoryId.isDirectReply());
|
||||
|
||||
@@ -1141,14 +1141,20 @@ object SyncMessageProcessor {
|
||||
|
||||
when (response.type) {
|
||||
MessageRequestResponse.Type.ACCEPT -> {
|
||||
val wasBlocked = recipient.isBlocked
|
||||
SignalDatabase.recipients.setProfileSharing(recipient.id, true)
|
||||
SignalDatabase.recipients.setBlocked(recipient.id, false)
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
OutgoingMessage.messageRequestAcceptMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId,
|
||||
false,
|
||||
null
|
||||
)
|
||||
if (wasBlocked) {
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
message = OutgoingMessage.unblockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
} else {
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
message = OutgoingMessage.messageRequestAcceptMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
}
|
||||
}
|
||||
MessageRequestResponse.Type.DELETE -> {
|
||||
SignalDatabase.recipients.setProfileSharing(recipient.id, false)
|
||||
@@ -1159,6 +1165,10 @@ object SyncMessageProcessor {
|
||||
MessageRequestResponse.Type.BLOCK -> {
|
||||
SignalDatabase.recipients.setBlocked(recipient.id, true)
|
||||
SignalDatabase.recipients.setProfileSharing(recipient.id, false)
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
message = OutgoingMessage.blockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
}
|
||||
MessageRequestResponse.Type.BLOCK_AND_DELETE -> {
|
||||
SignalDatabase.recipients.setBlocked(recipient.id, true)
|
||||
@@ -1169,20 +1179,20 @@ object SyncMessageProcessor {
|
||||
}
|
||||
MessageRequestResponse.Type.SPAM -> {
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
OutgoingMessage.reportSpamMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId,
|
||||
false,
|
||||
null
|
||||
message = OutgoingMessage.reportSpamMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
}
|
||||
MessageRequestResponse.Type.BLOCK_AND_SPAM -> {
|
||||
SignalDatabase.recipients.setBlocked(recipient.id, true)
|
||||
SignalDatabase.recipients.setProfileSharing(recipient.id, false)
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
OutgoingMessage.reportSpamMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId,
|
||||
false,
|
||||
null
|
||||
message = OutgoingMessage.reportSpamMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
SignalDatabase.messages.insertMessageOutbox(
|
||||
message = OutgoingMessage.blockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.expiresInSeconds.toLong())),
|
||||
threadId = threadId
|
||||
)
|
||||
}
|
||||
else -> warn("Got an unknown response type! Skipping")
|
||||
|
||||
@@ -55,6 +55,8 @@ data class OutgoingMessage(
|
||||
val messageToEdit: Long = 0,
|
||||
val isReportSpam: Boolean = false,
|
||||
val isMessageRequestAccept: Boolean = false,
|
||||
val isBlocked: Boolean = false,
|
||||
val isUnblocked: Boolean = false,
|
||||
val messageExtras: MessageExtras? = null
|
||||
) {
|
||||
|
||||
@@ -435,6 +437,38 @@ data class OutgoingMessage(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Message for when you block someone
|
||||
*/
|
||||
@JvmStatic
|
||||
fun blockedMessage(threadRecipient: Recipient, sentTimeMillis: Long, expiresIn: Long): OutgoingMessage {
|
||||
return OutgoingMessage(
|
||||
threadRecipient = threadRecipient,
|
||||
sentTimeMillis = sentTimeMillis,
|
||||
expiresIn = expiresIn,
|
||||
isGroup = threadRecipient.isPushV2Group,
|
||||
isBlocked = true,
|
||||
isUrgent = false,
|
||||
isSecure = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Message for when you unblock someone
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unblockedMessage(threadRecipient: Recipient, sentTimeMillis: Long, expiresIn: Long): OutgoingMessage {
|
||||
return OutgoingMessage(
|
||||
threadRecipient = threadRecipient,
|
||||
sentTimeMillis = sentTimeMillis,
|
||||
expiresIn = expiresIn,
|
||||
isGroup = threadRecipient.isPushV2Group,
|
||||
isUnblocked = true,
|
||||
isUrgent = false,
|
||||
isSecure = true
|
||||
)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun buildMessage(slideDeck: SlideDeck, message: String): String {
|
||||
return if (message.isNotEmpty() && slideDeck.body.isNotEmpty()) {
|
||||
|
||||
@@ -24,10 +24,10 @@ import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob;
|
||||
import org.thoughtcrime.securesms.jobs.RefreshOwnProfileJob;
|
||||
import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.mms.MmsException;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMessage;
|
||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
|
||||
import org.thoughtcrime.securesms.util.ExpirationTimerUtil;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
|
||||
@@ -36,6 +36,7 @@ import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RecipientUtil {
|
||||
|
||||
@@ -172,6 +173,7 @@ public class RecipientUtil {
|
||||
}
|
||||
|
||||
SignalDatabase.recipients().setBlocked(recipient.getId(), true);
|
||||
insertBlockedUpdate(recipient, SignalDatabase.threads().getOrCreateThreadIdFor(recipient));
|
||||
|
||||
if (recipient.isSystemContact() || recipient.isProfileSharing() || isProfileSharedViaGroup(recipient)) {
|
||||
SignalDatabase.recipients().setProfileSharing(recipient.getId(), false);
|
||||
@@ -194,10 +196,37 @@ public class RecipientUtil {
|
||||
|
||||
SignalDatabase.recipients().setBlocked(recipient.getId(), false);
|
||||
SignalDatabase.recipients().setProfileSharing(recipient.getId(), true);
|
||||
insertUnblockedUpdate(recipient, SignalDatabase.threads().getOrCreateThreadIdFor(recipient));
|
||||
AppDependencies.getJobManager().add(new MultiDeviceBlockedUpdateJob());
|
||||
StorageSyncHelper.scheduleSyncForDataChange();
|
||||
}
|
||||
|
||||
private static void insertBlockedUpdate(@NonNull Recipient recipient, long threadId) {
|
||||
try {
|
||||
SignalDatabase.messages().insertMessageOutbox(
|
||||
OutgoingMessage.blockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.getExpiresInSeconds())),
|
||||
threadId,
|
||||
false,
|
||||
null
|
||||
);
|
||||
} catch (MmsException e) {
|
||||
Log.w(TAG, "Unable to insert blocked message", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void insertUnblockedUpdate(@NonNull Recipient recipient, long threadId) {
|
||||
try {
|
||||
SignalDatabase.messages().insertMessageOutbox(
|
||||
OutgoingMessage.unblockedMessage(recipient, System.currentTimeMillis(), TimeUnit.SECONDS.toMillis(recipient.getExpiresInSeconds())),
|
||||
threadId,
|
||||
false,
|
||||
null
|
||||
);
|
||||
} catch (MmsException e) {
|
||||
Log.w(TAG, "Unable to insert unblocked message", e);
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public static Recipient.HiddenState getRecipientHiddenState(long threadId) {
|
||||
if (threadId < 0) {
|
||||
|
||||
Reference in New Issue
Block a user