Prevent child clickable in message selection state.

This commit is contained in:
Sagar
2025-04-09 20:28:15 +05:30
committed by Michelle Tang
parent 0227af199b
commit f0f6b80f43
3 changed files with 119 additions and 24 deletions

View File

@@ -91,6 +91,8 @@ public final class ConversationUpdateItem extends FrameLayout
private final RecipientObserverManager groupObserver = new RecipientObserverManager(presentOnChange);
private final GroupDataManager groupData = new GroupDataManager();
private final PassthroughClickListener passthroughClickListener = new PassthroughClickListener();
public ConversationUpdateItem(Context context) {
super(context);
}
@@ -427,6 +429,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onGroupMigrationLearnMoreClicked(conversationMessage.getMessageRecord().getGroupV1MigrationMembershipChanges());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isChatSessionRefresh() &&
@@ -437,6 +441,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onChatSessionRefreshLearnMoreClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isIdentityUpdate()) {
@@ -445,6 +451,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onSafetyNumberLearnMoreClicked(conversationMessage.getMessageRecord().getFromRecipient());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isGroupCall()) {
@@ -473,6 +481,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onJoinGroupCallClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else {
@@ -485,6 +495,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onInviteFriendsToGroupClicked(conversationRecipient.requireGroupId().requireV2());
} else {
passthroughClickListener.onClick(v);
}
});
} else if ((conversationMessage.getMessageRecord().isMissedAudioCall() || conversationMessage.getMessageRecord().isMissedVideoCall()) && EnableCallNotificationSettingsDialog.shouldShow(getContext())) {
@@ -493,6 +505,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (eventListener != null) {
eventListener.onEnableCallNotificationsClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isInMemoryMessageRecord() && ((InMemoryMessageRecord) conversationMessage.getMessageRecord()).showActionButton()) {
@@ -502,6 +516,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (eventListener != null) {
eventListener.onInMemoryMessageClicked(inMemoryMessageRecord);
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isGroupV2DescriptionUpdate()) {
@@ -510,6 +526,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (eventListener != null) {
eventListener.onViewGroupDescriptionChange(conversationRecipient.getGroupId().orElse(null), conversationMessage.getMessageRecord().getGroupV2DescriptionUpdate(), isMessageRequestAccepted);
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isBadDecryptType() &&
@@ -520,6 +538,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onBadDecryptLearnMoreClicked(conversationMessage.getMessageRecord().getFromRecipient().getId());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isChangeNumber() && conversationMessage.getMessageRecord().getFromRecipient().isSystemContact()) {
@@ -528,6 +548,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onChangeNumberUpdateContact(conversationMessage.getMessageRecord().getFromRecipient());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (shouldShowBlockRequestAction(conversationMessage.getMessageRecord())) {
@@ -536,6 +558,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onBlockJoinRequest(conversationMessage.getMessageRecord().getFromRecipient());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isReleaseChannelDonationRequest()) {
@@ -543,6 +567,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onDonateClicked();
} else {
passthroughClickListener.onClick(v);
}
});
@@ -552,6 +578,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onInviteToSignalClicked();
} else {
passthroughClickListener.onClick(v);
}
});
@@ -562,6 +590,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onActivatePaymentsClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isPaymentsActivated() && !conversationMessage.getMessageRecord().isOutgoing()) {
@@ -570,6 +600,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onSendPaymentClicked(conversationMessage.getMessageRecord().getFromRecipient().getId());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isReportedSpam()) {
@@ -578,6 +610,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onReportSpamLearnMoreClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isProfileChange() && !conversationMessage.getMessageRecord().getFromRecipient().isSelf()) {
@@ -586,6 +620,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onChangeProfileNameUpdateContact(conversationMessage.getMessageRecord().getFromRecipient());
} else {
passthroughClickListener.onClick(v);
}
});
} else if (conversationMessage.getMessageRecord().isMessageRequestAccepted()) {
@@ -594,6 +630,8 @@ public final class ConversationUpdateItem extends FrameLayout
actionButton.setOnClickListener(v -> {
if (batchSelected.isEmpty() && eventListener != null) {
eventListener.onMessageRequestAcceptOptionsClicked();
} else {
passthroughClickListener.onClick(v);
}
});
} else {
@@ -723,6 +761,21 @@ public final class ConversationUpdateItem extends FrameLayout
}
}
private class PassthroughClickListener implements View.OnLongClickListener, View.OnClickListener {
@Override
public boolean onLongClick(View v) {
performLongClick();
return true;
}
@Override
public void onClick(View v) {
performClick();
}
}
private class InternalClickListener implements View.OnClickListener {
@Nullable private final View.OnClickListener parent;

View File

@@ -72,7 +72,11 @@ class V2ConversationItemMediaViewHolder<Model : MappingModel<Model>>(
val quoteView = binding.quoteStub.get()
quoteView.setOnClickListener {
conversationContext.clickListener.onQuoteClicked(record)
if (conversationContext.selectedItems.isEmpty()) {
conversationContext.clickListener.onQuoteClicked(record)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
binding.quoteStub.visibility = View.VISIBLE

View File

@@ -145,28 +145,30 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.root.onDispatchTouchEventListener = dispatchTouchEventListener
binding.reactions.setOnClickListener {
conversationContext.clickListener
.onReactionClicked(
Multiselect.getParts(conversationMessage).asSingle().singlePart,
conversationMessage.messageRecord.id,
conversationMessage.messageRecord.isMms
)
}
binding.body.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }
binding.root.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }
binding.root.setOnClickListener { onBubbleClicked() }
val passthroughClickListener = PassthroughClickListener()
binding.body.setOnClickListener {
if (conversationContext.selectedItems.isEmpty()) {
passthroughClickListener.onClick(it)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
binding.body.setOnLongClickListener(passthroughClickListener)
binding.root.setOnClickListener {
if (conversationContext.selectedItems.isEmpty()) {
onBubbleClicked()
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
binding.root.setOnLongClickListener {
conversationContext.clickListener.onItemLongClick(binding.root, getMultiselectPartForLatestTouch())
true
}
val passthroughClickListener = PassthroughClickListener()
binding.body.setOnClickListener(passthroughClickListener)
binding.body.setOnLongClickListener(passthroughClickListener)
binding.body.isFocusable = false
binding.body.setTextSize(TypedValue.COMPLEX_UNIT_SP, SignalStore.settings.messageFontSize.toFloat())
binding.body.movementMethod = LongClickMovementMethod.getInstance(context)
@@ -181,7 +183,13 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.bodyWrapper.layoutTransition = bodyBubbleLayoutTransition
binding.footerBackground.background = footerDrawable
binding.footerDate.setOnClickListener(passthroughClickListener)
binding.footerDate.setOnClickListener {
if (conversationContext.selectedItems.isEmpty()) {
passthroughClickListener.onClick(it)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
binding.footerDate.setOnLongClickListener(passthroughClickListener)
}
@@ -465,8 +473,12 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
private val recipientId: RecipientId
) : ClickableSpan() {
override fun onClick(widget: View) {
VibrateUtil.vibrateTick(context)
conversationContext.clickListener.onGroupMemberClicked(recipientId, conversationMessage.threadRecipient.requireGroupId())
if (conversationContext.selectedItems.isEmpty()) {
VibrateUtil.vibrateTick(context)
conversationContext.clickListener.onGroupMemberClicked(recipientId, conversationMessage.threadRecipient.requireGroupId())
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
override fun updateDrawState(ds: TextPaint) = Unit
@@ -480,6 +492,8 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
conversationMessage.messageRecord.id,
conversationMessage.messageRecord.isMms
)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
@@ -561,10 +575,14 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.senderPhoto.setAvatar(conversationContext.requestManager, sender, false)
binding.senderBadge.setBadgeFromRecipient(sender, conversationContext.requestManager)
binding.senderPhoto.setOnClickListener {
conversationContext.clickListener.onGroupMemberClicked(
conversationMessage.messageRecord.fromRecipient.id,
conversationMessage.threadRecipient.requireGroupId()
)
if (conversationContext.selectedItems.isEmpty()) {
conversationContext.clickListener.onGroupMemberClicked(
conversationMessage.messageRecord.fromRecipient.id,
conversationMessage.threadRecipient.requireGroupId()
)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
} else {
binding.senderName.visible = false
@@ -613,6 +631,18 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
} else {
binding.reactions.setReactions(conversationMessage.messageRecord.reactions)
binding.root.addOnMeasureListener(reactionMeasureListener)
binding.reactions.setOnClickListener {
if (conversationContext.selectedItems.isEmpty()) {
conversationContext.clickListener
.onReactionClicked(
Multiselect.getParts(conversationMessage).asSingle().singlePart,
conversationMessage.messageRecord.id,
conversationMessage.messageRecord.isMms
)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
}
}
@@ -659,7 +689,11 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
binding.footerDate.setText(errorMessage)
binding.footerDate.setOnClickListener {
conversationContext.clickListener.onMessageWithErrorClicked(record)
if (conversationContext.selectedItems.isEmpty()) {
conversationContext.clickListener.onMessageWithErrorClicked(record)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
} else if (record.isRateLimited) {
binding.footerDate.setText(R.string.ConversationItem_send_paused)
@@ -677,7 +711,11 @@ open class V2ConversationItemTextOnlyViewHolder<Model : MappingModel<Model>>(
}
binding.footerDate.setOnClickListener {
conversationContext.clickListener.onEditedIndicatorClicked(conversationMessage)
if (conversationContext.selectedItems.isEmpty()) {
conversationContext.clickListener.onEditedIndicatorClicked(conversationMessage)
} else {
conversationContext.clickListener.onItemClick(getMultiselectPartForLatestTouch())
}
}
}