diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt index 6ca50ab719..c9495bb64e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/CallParticipantsState.kt @@ -312,26 +312,26 @@ data class CallParticipantsState( @PluralsRes multipleParticipants: Int, members: List ): String { - val membersWithoutYou: List = members.filterNot { it.member.isSelf } + val eligibleMembers: List = members.filterNot { it.member.isSelf || it.member.isBlocked } - return when (membersWithoutYou.size) { + return when (eligibleMembers.size) { 0 -> "" 1 -> context.getString( oneParticipant, - membersWithoutYou[0].member.getShortDisplayName(context) + eligibleMembers[0].member.getShortDisplayName(context) ) 2 -> context.getString( twoParticipants, - membersWithoutYou[0].member.getShortDisplayName(context), - membersWithoutYou[1].member.getShortDisplayName(context) + eligibleMembers[0].member.getShortDisplayName(context), + eligibleMembers[1].member.getShortDisplayName(context) ) else -> { - val others = membersWithoutYou.size - 2 + val others = eligibleMembers.size - 2 context.resources.getQuantityString( multipleParticipants, others, - membersWithoutYou[0].member.getShortDisplayName(context), - membersWithoutYou[1].member.getShortDisplayName(context), + eligibleMembers[0].member.getShortDisplayName(context), + eligibleMembers[1].member.getShortDisplayName(context), others ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java index 991e88d897..3d6259fa76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptDatabase.java @@ -34,6 +34,7 @@ public class GroupReceiptDatabase extends Database { public static final int STATUS_DELIVERED = 1; public static final int STATUS_READ = 2; public static final int STATUS_VIEWED = 3; + public static final int STATUS_SKIPPED = 4; public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + MMS_ID + " INTEGER, " + RECIPIENT_ID + " INTEGER, " + STATUS + " INTEGER, " + TIMESTAMP + " INTEGER, " + UNIDENTIFIED + " INTEGER DEFAULT 0);"; @@ -95,6 +96,26 @@ public class GroupReceiptDatabase extends Database { } } + public void setSkipped(Collection recipients, long mmsId) { + SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); + + db.beginTransaction(); + try { + String query = MMS_ID + " = ? AND " + RECIPIENT_ID + " = ?"; + + for (RecipientId recipient : recipients) { + ContentValues values = new ContentValues(1); + values.put(STATUS, STATUS_SKIPPED); + + db.update(TABLE_NAME, values, query, new String[]{ String.valueOf(mmsId), recipient.serialize()}); + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + } + public @NonNull List getGroupReceiptInfo(long mmsId) { SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); List results = new LinkedList<>(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java index e3ec3db8da..1cd6c0285c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/GroupCallUpdateSendJob.java @@ -58,7 +58,6 @@ public class GroupCallUpdateSendJob extends BaseJob { List recipients = Stream.of(RecipientUtil.getEligibleForSending(conversationRecipient.getParticipants())) .filterNot(Recipient::isSelf) - .filterNot(Recipient::isBlocked) .map(Recipient::getId) .toList(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java index 41090b683c..69121077b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RemoteDeleteSendJob.java @@ -187,6 +187,9 @@ public class RemoteDeleteSendJob extends BaseJob { new MessageId(messageId, isMms), dataMessage); + List blockedIds = Stream.of(conversationRecipient.getParticipants()).filter(Recipient::isBlocked).map(Recipient::getId).toList(); + SignalDatabase.groupReceipts().setSkipped(blockedIds, messageId); + return GroupSendJobHelper.getCompletedSends(destinations, results); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java index 4dcbc5bf15..46e45e53b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java @@ -122,7 +122,6 @@ public class TypingSendJob extends BaseJob { recipients = RecipientUtil.getEligibleForSending(Stream.of(recipients) .map(Recipient::resolve) - .filter(r -> !r.isBlocked()) .toList()); SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis(), groupId); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetails.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetails.java index 9196daf6d2..d859e9e0e6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetails.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetails.java @@ -25,6 +25,7 @@ final class MessageDetails { private final Collection read; private final Collection notSent; private final Collection viewed; + private final Collection skipped; MessageDetails(@NonNull ConversationMessage conversationMessage, @NonNull List recipients) { this.conversationMessage = conversationMessage; @@ -35,6 +36,7 @@ final class MessageDetails { read = new TreeSet<>(RECIPIENT_COMPARATOR); notSent = new TreeSet<>(RECIPIENT_COMPARATOR); viewed = new TreeSet<>(RECIPIENT_COMPARATOR); + skipped = new TreeSet<>(RECIPIENT_COMPARATOR); if (conversationMessage.getMessageRecord().getRecipient().isSelf()) { read.addAll(recipients); @@ -58,6 +60,9 @@ final class MessageDetails { break; case VIEWED: viewed.add(status); + break; + case SKIPPED: + skipped.add(status); } } } else { @@ -77,6 +82,8 @@ final class MessageDetails { return sent; } + @NonNull Collection getSkipped() {return skipped;} + @NonNull Collection getDelivered() { return delivered; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.java index 17d7508e26..59724ae008 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsFragment.java @@ -138,6 +138,7 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment { addRecipients(list, RecipientHeader.DELIVERED, details.getDelivered()); addRecipients(list, RecipientHeader.SENT_TO, details.getSent()); addRecipients(list, RecipientHeader.PENDING, details.getPending()); + addRecipients(list, RecipientHeader.SKIPPED, details.getSkipped()); } else { addRecipients(list, RecipientHeader.SENT_FROM, details.getSent()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java index dac264e506..8d92baf1c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/MessageDetailsRepository.java @@ -132,6 +132,7 @@ final class MessageDetailsRepository { else if (groupStatus == GroupReceiptDatabase.STATUS_UNDELIVERED) return RecipientDeliveryStatus.Status.PENDING; else if (groupStatus == GroupReceiptDatabase.STATUS_UNKNOWN) return RecipientDeliveryStatus.Status.UNKNOWN; else if (groupStatus == GroupReceiptDatabase.STATUS_VIEWED) return RecipientDeliveryStatus.Status.VIEWED; + else if (groupStatus == GroupReceiptDatabase.STATUS_SKIPPED) return RecipientDeliveryStatus.Status.SKIPPED; throw new AssertionError(); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientDeliveryStatus.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientDeliveryStatus.java index 08ac7fb68c..1f2d9e247f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientDeliveryStatus.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientDeliveryStatus.java @@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.recipients.Recipient; final class RecipientDeliveryStatus { enum Status { - UNKNOWN, PENDING, SENT, DELIVERED, READ, VIEWED + UNKNOWN, PENDING, SENT, DELIVERED, READ, VIEWED, SKIPPED, } private final MessageRecord messageRecord; diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientHeader.java b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientHeader.java index fcbe284078..fe9cfaf7d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientHeader.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messagedetails/RecipientHeader.java @@ -11,6 +11,7 @@ enum RecipientHeader { DELIVERED(R.string.message_details_recipient_header__delivered_to), READ(R.string.message_details_recipient_header__read_by), NOT_SENT(R.string.message_details_recipient_header__not_sent), + SKIPPED(R.string.message_details_recipient_header__skipped), VIEWED(R.string.message_details_recipient_header__viewed); private final int headerText; diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index b554b2a361..b806d414a2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -117,6 +117,7 @@ public class RecipientUtil { public static List getEligibleForSending(@NonNull List recipients) { return Stream.of(recipients) .filter(r -> r.getRegistered() != RegisteredState.NOT_REGISTERED) + .filter(r -> !r.isBlocked()) .toList(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java index 7aea2135fb..4b34aaa63b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/webrtc/SignalCallManager.java @@ -648,7 +648,6 @@ public final class SignalCallManager implements CallManager.Observer, GroupCall. recipients = RecipientUtil.getEligibleForSending((recipients.stream() .map(Recipient::resolve) - .filter(r -> !r.isBlocked()) .collect(Collectors.toList()))); OpaqueMessage opaqueMessage = new OpaqueMessage(message, getUrgencyFromCallUrgency(urgency)); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2eef24b341..2c661df0d2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2304,6 +2304,7 @@ Read by Not sent Viewed by + Skipped Failed to send