Skip to content

Commit

Permalink
Integrate contact hiding with message requests.
Browse files Browse the repository at this point in the history
  • Loading branch information
clark-signal authored and greyson-signal committed Apr 11, 2023
1 parent 74877b8 commit 48360d0
Show file tree
Hide file tree
Showing 15 changed files with 107 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void onCreate(Bundle bundle, boolean ready) {
ContactsManagementViewModel.Factory factory = new ContactsManagementViewModel.Factory(repository);

contactLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> {
if (activityResult.getResultCode() == RESULT_OK) {
if (activityResult.getResultCode() != RESULT_CANCELED) {
handleManualRefresh();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ data class ConversationData(

data class MessageRequestData @JvmOverloads constructor(
val isMessageRequestAccepted: Boolean,
val isHidden: Boolean,
private val groupsInCommon: Boolean = false,
val isGroup: Boolean = false
) {

fun includeWarningUpdateMessage(): Boolean {
return !isMessageRequestAccepted && !groupsInCommon
return !isMessageRequestAccepted && !groupsInCommon && !isHidden
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public int size() {
long startTime = System.currentTimeMillis();
int size = getSizeInternal() +
(messageRequestData.includeWarningUpdateMessage() ? 1 : 0) +
(messageRequestData.isHidden() ? 1 : 0) +
(showUniversalExpireTimerUpdate ? 1 : 0);

Log.d(TAG, "[size(), thread " + threadId + "] " + (System.currentTimeMillis() - startTime) + " ms");
Expand Down Expand Up @@ -124,6 +125,10 @@ private int getSizeInternal() {
records.add(new InMemoryMessageRecord.NoGroupsInCommon(threadId, messageRequestData.isGroup()));
}

if (messageRequestData.isHidden() && (start + length >= size())) {
records.add(new InMemoryMessageRecord.RemovedContactHidden(threadId));
}

if (showUniversalExpireTimerUpdate) {
records.add(new InMemoryMessageRecord.UniversalExpireTimerUpdate(threadId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ boolean canShowAsBubble(long threadId) {
long lastScrolled = metadata.getLastScrolled();
int lastScrolledPosition = 0;
boolean isMessageRequestAccepted = RecipientUtil.isMessageRequestAccepted(context, threadId);
ConversationData.MessageRequestData messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted);
boolean isConversationHidden = RecipientUtil.isRecipientHidden(threadId);
ConversationData.MessageRequestData messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted, isConversationHidden);
boolean showUniversalExpireTimerUpdate = false;

if (lastSeen > 0) {
Expand Down Expand Up @@ -98,7 +99,7 @@ boolean canShowAsBubble(long threadId) {
} else if (conversationRecipient.hasGroupsInCommon()) {
recipientIsKnownOrHasGroupsInCommon = true;
}
messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted, recipientIsKnownOrHasGroupsInCommon, isGroup);
messageRequestData = new ConversationData.MessageRequestData(isMessageRequestAccepted, isConversationHidden, recipientIsKnownOrHasGroupsInCommon, isGroup);
}

if (SignalStore.settings().getUniversalExpireTimer() != 0 &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,11 @@ private void onRecipientChanged(@NonNull Recipient recipient) {
int defaultTint = ContextCompat.getColor(context, R.color.signal_text_secondary);

if (!thread.isMessageRequestAccepted()) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_message_request), defaultTint);
if (thread.isRecipientHidden()) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_hidden_recipient), defaultTint);
} else {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_message_request), defaultTint);
}
} else if (MessageTypes.isGroupUpdate(thread.getType())) {
if (thread.getRecipient().isPushV2Group()) {
return emphasisAdded(context, MessageRecord.getGv2ChangeDescription(context, thread.getBody(), null), defaultTint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
private fun getExtrasFor(record: MessageRecord, body: ThreadBody): Extra? {
val threadRecipient = if (record.isOutgoing) record.recipient else getRecipientForThreadId(record.threadId)
val messageRequestAccepted = RecipientUtil.isMessageRequestAccepted(record.threadId, threadRecipient)
val isHidden = threadRecipient?.isHidden ?: false
val individualRecipientId = record.individualRecipient.id

if (!messageRequestAccepted && threadRecipient != null) {
Expand All @@ -1609,7 +1610,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
}
}
} else {
return Extra.forMessageRequest(individualRecipientId)
return Extra.forMessageRequest(individualRecipientId, isHidden)
}
}

Expand Down Expand Up @@ -1772,7 +1773,8 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
groupAddedBy = jsonObject.getString("groupAddedBy"),
individualRecipientId = jsonObject.getString("individualRecipientId")!!,
bodyRanges = jsonObject.getString("bodyRanges"),
isScheduled = jsonObject.getBoolean("isScheduled")
isScheduled = jsonObject.getBoolean("isScheduled"),
isRecipientHidden = jsonObject.getBoolean("isRecipientHidden")
)
} catch (exception: Exception) {
null
Expand Down Expand Up @@ -1855,7 +1857,10 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
val bodyRanges: String? = null,
@field:JsonProperty
@param:JsonProperty("isScheduled")
val isScheduled: Boolean = false
val isScheduled: Boolean = false,
@field:JsonProperty
@param:JsonProperty("isRecipientHidden")
val isRecipientHidden: Boolean = false
) {

fun getIndividualRecipientId(): String {
Expand All @@ -1879,8 +1884,8 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
return Extra(isRemoteDelete = true, individualRecipientId = individualRecipient.serialize())
}

fun forMessageRequest(individualRecipient: RecipientId): Extra {
return Extra(isMessageRequestAccepted = false, individualRecipientId = individualRecipient.serialize())
fun forMessageRequest(individualRecipient: RecipientId, isHidden: Boolean = false): Extra {
return Extra(isMessageRequestAccepted = false, individualRecipientId = individualRecipient.serialize(), isRecipientHidden = isHidden)
}

fun forGroupMessageRequest(recipientId: RecipientId, individualRecipient: RecipientId): Extra {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class InMemoryMessageRecord extends MessageRecord {
private static final int NO_GROUPS_IN_COMMON_ID = -1;
private static final int UNIVERSAL_EXPIRE_TIMER_ID = -2;
private static final int FORCE_BUBBLE_ID = -3;
private static final int HIDDEN_CONTACT_WARNING_ID = -4;

private InMemoryMessageRecord(long id,
String body,
Expand Down Expand Up @@ -118,6 +119,29 @@ public boolean isGroup() {
}
}

public static final class RemovedContactHidden extends InMemoryMessageRecord {

public RemovedContactHidden(long threadId) {
super(HIDDEN_CONTACT_WARNING_ID, "", Recipient.UNKNOWN, threadId, 0);
}

@Override
public @Nullable UpdateDescription getUpdateDisplayBody(@NonNull Context context, @Nullable Consumer<RecipientId> recipientClickHandler) {
return UpdateDescription.staticDescription(context.getString(R.string.ConversationUpdateItem_hidden_contact_message_to_add_back),
R.drawable.symbol_info_compact_16);
}

@Override
public boolean isUpdate() {
return true;
}

@Override
public boolean showActionButton() {
return false;
}
}

/**
* Show temporary update message about setting the disappearing messages timer upon first message
* send.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,11 @@ public boolean isMessageRequestAccepted() {
else return true;
}

public boolean isRecipientHidden() {
if (extra != null) return extra.isRecipientHidden();
else return true;
}

public boolean isPinned() {
return isPinned;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ void getGroupInfo(@NonNull RecipientId recipientId, @NonNull Consumer<GroupInfo>
} else {
if (RecipientUtil.isMessageRequestAccepted(context, threadId)) {
return MessageRequestState.NONE;
} else if (RecipientUtil.isRecipientHidden(threadId)) {
return MessageRequestState.INDIVIDUAL_HIDDEN;
} else {
return MessageRequestState.INDIVIDUAL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,8 @@ public enum MessageRequestState {
GROUP_V2_ADD,

/** A message request is needed for an individual */
INDIVIDUAL
INDIVIDUAL,

/** A message request is needed for an individual since they have been hidden */
INDIVIDUAL_HIDDEN
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ public void setMessageData(@NonNull MessageRequestViewModel.MessageData messageD
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_accept);
break;
case INDIVIDUAL_HIDDEN:
question.setText(HtmlCompat.fromHtml(getContext().getString(R.string.MessageRequestBottomView_do_you_want_to_let_s_message_you_you_removed_them_before,
HtmlUtil.bold(recipient.getShortDisplayName(getContext()))), 0));
setActiveInactiveGroups(normalButtons, blockedButtons, gv1MigrationButtons);
accept.setText(R.string.MessageRequestBottomView_accept);
break;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public class Recipient {
private final String profileAvatar;
private final ProfileAvatarFileDetails profileAvatarFileDetails;
private final boolean profileSharing;
private final boolean isHidden;
private final long lastProfileFetch;
private final String notificationChannel;
private final UnidentifiedAccessMode unidentifiedAccessMode;
Expand Down Expand Up @@ -412,6 +413,7 @@ public static boolean isSelfSet() {
this.profileAvatar = null;
this.profileAvatarFileDetails = ProfileAvatarFileDetails.NO_DETAILS;
this.profileSharing = false;
this.isHidden = false;
this.lastProfileFetch = 0;
this.notificationChannel = null;
this.unidentifiedAccessMode = UnidentifiedAccessMode.DISABLED;
Expand Down Expand Up @@ -466,6 +468,7 @@ public Recipient(@NonNull RecipientId id, @NonNull RecipientDetails details, boo
this.profileAvatar = details.profileAvatar;
this.profileAvatarFileDetails = details.profileAvatarFileDetails;
this.profileSharing = details.profileSharing;
this.isHidden = details.isHidden;
this.lastProfileFetch = details.lastProfileFetch;
this.notificationChannel = details.notificationChannel;
this.unidentifiedAccessMode = details.unidentifiedAccessMode;
Expand Down Expand Up @@ -833,6 +836,10 @@ public boolean isProfileSharing() {
return profileSharing;
}

public boolean isHidden() {
return isHidden;
}

public long getLastProfileFetchTime() {
return lastProfileFetch;
}
Expand Down Expand Up @@ -1290,6 +1297,7 @@ public boolean hasSameContent(@NonNull Recipient other) {
expireMessages == other.expireMessages &&
Objects.equals(profileAvatarFileDetails, other.profileAvatarFileDetails) &&
profileSharing == other.profileSharing &&
isHidden == other.isHidden &&
forceSmsSelection == other.forceSmsSelection &&
Objects.equals(serviceId, other.serviceId) &&
Objects.equals(username, other.username) &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ public class RecipientDetails {
final String profileAvatar;
final ProfileAvatarFileDetails profileAvatarFileDetails;
final boolean profileSharing;
final boolean isHidden;
final long lastProfileFetch;
final boolean systemContact;
final boolean isSelf;
Expand Down Expand Up @@ -122,6 +123,7 @@ public RecipientDetails(@Nullable String groupName,
this.profileAvatar = record.getProfileAvatar();
this.profileAvatarFileDetails = record.getProfileAvatarFileDetails();
this.profileSharing = record.isProfileSharing();
this.isHidden = record.isHidden();
this.lastProfileFetch = record.getLastProfileFetch();
this.systemContact = systemContact;
this.isSelf = isSelf;
Expand Down Expand Up @@ -176,6 +178,7 @@ private RecipientDetails() {
this.profileAvatar = null;
this.profileAvatarFileDetails = ProfileAvatarFileDetails.NO_DETAILS;
this.profileSharing = false;
this.isHidden = false;
this.lastProfileFetch = 0;
this.systemContact = true;
this.isSelf = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,22 @@ public static void unblock(@NonNull Recipient recipient) {
StorageSyncHelper.scheduleSyncForDataChange();
}

@WorkerThread
public static boolean isRecipientHidden(long threadId) {
if (threadId < 0) {
return false;
}

ThreadTable threadTable = SignalDatabase.threads();
Recipient threadRecipient = threadTable.getRecipientForThreadId(threadId);

if (threadRecipient == null) {
return false;
}

return threadRecipient.isHidden();
}

/**
* If true, the new message request UI does not need to be shown, and it's safe to send read
* receipts.
Expand Down Expand Up @@ -281,7 +297,8 @@ public static boolean isLegacyProfileSharingAccepted(@NonNull Recipient threadRe
threadRecipient.isProfileSharing() ||
threadRecipient.isSystemContact() ||
!threadRecipient.isRegistered() ||
threadRecipient.isForceSmsSelection();
threadRecipient.isForceSmsSelection() ||
threadRecipient.isHidden();
}

/**
Expand Down Expand Up @@ -331,9 +348,11 @@ public static boolean isMessageRequestAccepted(@Nullable Long threadId, @Nullabl
threadRecipient.isSystemContact() ||
threadRecipient.isForceSmsSelection() ||
!threadRecipient.isRegistered() ||
hasSentMessageInThread(threadId) ||
noSecureMessagesAndNoCallsInThread(threadId) ||
isPreMessageRequestThread(threadId);
(!threadRecipient.isHidden() && (
hasSentMessageInThread(threadId) ||
noSecureMessagesAndNoCallsInThread(threadId) ||
isPreMessageRequestThread(threadId))
);
}

@WorkerThread
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,8 @@
<string name="MessageRequestBottomView_delete">Delete</string>
<string name="MessageRequestBottomView_block">Block</string>
<string name="MessageRequestBottomView_unblock">Unblock</string>
<!-- Text explaining a message request from someone you've removed before -->
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_you_removed_them_before">Let %1$s message you and share your name and photo with them? You have removed this person in the past.</string>
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_they_wont_know_youve_seen_their_messages_until_you_accept">Let %1$s message you and share your name and photo with them? They won\'t know you\'ve seen their message until you accept.</string>
<!-- Shown in message request flow. Describes what will happen if you unblock a Signal user -->
<string name="MessageRequestBottomView_do_you_want_to_let_s_message_you_wont_receive_any_messages_until_you_unblock_them">Let %1$s message you and share your name and photo with them? You won\'t receive any messages until you unblock them.</string>
Expand Down Expand Up @@ -1992,6 +1994,8 @@
<string name="ThreadRecord_message_could_not_be_processed">Message could not be processed</string>
<string name="ThreadRecord_delivery_issue">Delivery issue</string>
<string name="ThreadRecord_message_request">Message Request</string>
<!-- Thread preview for a recipient that has been hidden -->
<string name="ThreadRecord_hidden_recipient">You have hidden this person, message them again to add them back to your list.</string>
<string name="ThreadRecord_photo">Photo</string>
<string name="ThreadRecord_gif">GIF</string>
<string name="ThreadRecord_voice_message">Voice Message</string>
Expand Down Expand Up @@ -2387,7 +2391,8 @@
<string name="ConversationUpdateItem_send_payment">Send payment</string>
<!-- Update item button text to activate payments -->
<string name="ConversationUpdateItem_activate_payments">Activate payments</string>

<!-- Update item alerting the user they hid this person and that they can message them to unhide them -->
<string name="ConversationUpdateItem_hidden_contact_message_to_add_back">You have removed this person, messaging them again will add them back to your list.</string>

<!-- audio_view -->
<string name="audio_view__play_pause_accessibility_description">Play … Pause</string>
Expand Down

0 comments on commit 48360d0

Please sign in to comment.