mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-24 13:08:46 +00:00
Prevent child clickable in message selection state.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user