Copy action should display if message body is not empty.

Fixes #9491
This commit is contained in:
Alex Hart 2020-03-27 11:18:02 -03:00 committed by GitHub
parent 10bfc8a753
commit d8fa46c558
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 186 additions and 85 deletions

View file

@ -103,7 +103,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity;
import org.thoughtcrime.securesms.revealable.ViewOnceUtil;
import org.thoughtcrime.securesms.sharing.ShareActivity;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
import org.thoughtcrime.securesms.stickers.StickerLocator;
@ -206,7 +205,7 @@ public class ConversationFragment extends Fragment
new ConversationItemSwipeCallback(
messageRecord -> actionMode == null &&
canReplyToMessage(isActionMessage(messageRecord), messageRecord, messageRequestViewModel.shouldShowMessageRequest()),
MenuState.canReplyToMessage(MenuState.isActionMessage(messageRecord), messageRecord, messageRequestViewModel.shouldShowMessageRequest()),
this::handleReplyMessage
).attachToRecyclerView(list);
@ -504,78 +503,22 @@ public class ConversationFragment extends Fragment
});
}
private void setCorrectMenuVisibility(Menu menu) {
private void setCorrectMenuVisibility(@NonNull Menu menu) {
Set<MessageRecord> messageRecords = getListAdapter().getSelectedItems();
boolean actionMessage = false;
boolean hasText = false;
boolean sharedContact = false;
boolean viewOnce = false;
if (actionMode != null && messageRecords.size() == 0) {
actionMode.finish();
return;
}
for (MessageRecord messageRecord : messageRecords) {
if (isActionMessage(messageRecord))
{
actionMessage = true;
}
MenuState menuState = MenuState.getMenuState(messageRecords, messageRequestViewModel.shouldShowMessageRequest());
if (messageRecord.getBody().length() > 0) {
hasText = true;
}
if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getSharedContacts().isEmpty()) {
sharedContact = true;
}
if (messageRecord.isViewOnce()) {
viewOnce = true;
}
}
if (messageRecords.size() > 1) {
menu.findItem(R.id.menu_context_forward).setVisible(false);
menu.findItem(R.id.menu_context_reply).setVisible(false);
menu.findItem(R.id.menu_context_details).setVisible(false);
menu.findItem(R.id.menu_context_save_attachment).setVisible(false);
menu.findItem(R.id.menu_context_resend).setVisible(false);
} else {
MessageRecord messageRecord = messageRecords.iterator().next();
menu.findItem(R.id.menu_context_resend).setVisible(messageRecord.isFailed());
menu.findItem(R.id.menu_context_save_attachment).setVisible(!actionMessage &&
!viewOnce &&
messageRecord.isMms() &&
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null);
menu.findItem(R.id.menu_context_forward).setVisible(!actionMessage && !sharedContact && !viewOnce);
menu.findItem(R.id.menu_context_details).setVisible(!actionMessage);
menu.findItem(R.id.menu_context_reply).setVisible(canReplyToMessage(actionMessage, messageRecord, messageRequestViewModel.shouldShowMessageRequest()));
}
menu.findItem(R.id.menu_context_copy).setVisible(!actionMessage && hasText);
}
private static boolean canReplyToMessage(boolean actionMessage, MessageRecord messageRecord, boolean isDisplayingMessageRequest) {
return !actionMessage &&
!messageRecord.isPending() &&
!messageRecord.isFailed() &&
!isDisplayingMessageRequest &&
messageRecord.isSecure();
}
private static boolean isActionMessage(MessageRecord messageRecord) {
return messageRecord.isGroupAction() ||
messageRecord.isCallLog() ||
messageRecord.isJoined() ||
messageRecord.isExpirationTimerUpdate() ||
messageRecord.isEndSession() ||
messageRecord.isIdentityUpdate() ||
messageRecord.isIdentityVerified() ||
messageRecord.isIdentityDefault();
menu.findItem(R.id.menu_context_forward).setVisible(menuState.shouldShowForwardAction());
menu.findItem(R.id.menu_context_reply).setVisible(menuState.shouldShowReplyAction());
menu.findItem(R.id.menu_context_details).setVisible(menuState.shouldShowDetailsAction());
menu.findItem(R.id.menu_context_save_attachment).setVisible(menuState.shouldShowSaveAttachmentAction());
menu.findItem(R.id.menu_context_resend).setVisible(menuState.shouldShowResendAction());
menu.findItem(R.id.menu_context_copy).setVisible(menuState.shouldShowCopyAction());
}
private ConversationAdapter getListAdapter() {

View file

@ -33,11 +33,11 @@ import org.thoughtcrime.securesms.components.MaskView;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.ReactionRecord;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.MessageRecordUtil;
import org.thoughtcrime.securesms.util.ThemeUtil;
import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.util.ViewUtil;
import java.util.Collections;
import java.util.List;
public final class ConversationReactionOverlay extends RelativeLayout {
@ -427,25 +427,11 @@ public final class ConversationReactionOverlay extends RelativeLayout {
}
private void setupToolbarMenuItems() {
toolbar.getMenu().findItem(R.id.action_copy).setVisible(shouldShowCopy());
toolbar.getMenu().findItem(R.id.action_download).setVisible(shouldShowDownload());
toolbar.getMenu().findItem(R.id.action_forward).setVisible(shouldShowForward());
}
MenuState menuState = MenuState.getMenuState(Collections.singleton(messageRecord), false);
private boolean shouldShowCopy() {
return !MessageRecordUtil.hasSticker(messageRecord) &&
!MessageRecordUtil.isMediaMessage(messageRecord) &&
!MessageRecordUtil.hasSharedContact(messageRecord);
}
private boolean shouldShowDownload() {
return MessageRecordUtil.isMediaMessage(messageRecord) ||
MessageRecordUtil.hasLocation(messageRecord);
}
private boolean shouldShowForward() {
return !MessageRecordUtil.hasSharedContact(messageRecord);
toolbar.getMenu().findItem(R.id.action_copy).setVisible(menuState.shouldShowCopyAction());
toolbar.getMenu().findItem(R.id.action_download).setVisible(menuState.shouldShowSaveAttachmentAction());
toolbar.getMenu().findItem(R.id.action_forward).setVisible(menuState.shouldShowForwardAction());
}
private boolean handleToolbarItemClicked(@NonNull MenuItem menuItem) {

View file

@ -0,0 +1,170 @@
package org.thoughtcrime.securesms.conversation;
import androidx.annotation.NonNull;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import java.util.Set;
final class MenuState {
private final boolean forward;
private final boolean reply;
private final boolean details;
private final boolean saveAttachment;
private final boolean resend;
private final boolean copy;
private MenuState(@NonNull Builder builder) {
forward = builder.forward;
reply = builder.reply;
details = builder.details;
saveAttachment = builder.saveAttachment;
resend = builder.resend;
copy = builder.copy;
}
boolean shouldShowForwardAction() {
return forward;
}
boolean shouldShowReplyAction() {
return reply;
}
boolean shouldShowDetailsAction() {
return details;
}
boolean shouldShowSaveAttachmentAction() {
return saveAttachment;
}
boolean shouldShowResendAction() {
return resend;
}
boolean shouldShowCopyAction() {
return copy;
}
static MenuState getMenuState(@NonNull Set<MessageRecord> messageRecords,
boolean shouldShowMessageRequest)
{
Builder builder = new Builder();
boolean actionMessage = false;
boolean hasText = false;
boolean sharedContact = false;
boolean viewOnce = false;
for (MessageRecord messageRecord : messageRecords) {
if (isActionMessage(messageRecord))
{
actionMessage = true;
}
if (messageRecord.getBody().length() > 0) {
hasText = true;
}
if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getSharedContacts().isEmpty()) {
sharedContact = true;
}
if (messageRecord.isViewOnce()) {
viewOnce = true;
}
}
if (messageRecords.size() > 1) {
builder.shouldShowForwardAction(false)
.shouldShowReplyAction(false)
.shouldShowDetailsAction(false)
.shouldShowSaveAttachmentAction(false)
.shouldShowResendAction(false);
} else {
MessageRecord messageRecord = messageRecords.iterator().next();
builder.shouldShowResendAction(messageRecord.isFailed())
.shouldShowSaveAttachmentAction(!actionMessage &&
!viewOnce &&
messageRecord.isMms() &&
!messageRecord.isMmsNotification() &&
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
.shouldShowForwardAction(!actionMessage && !sharedContact && !viewOnce)
.shouldShowDetailsAction(!actionMessage)
.shouldShowReplyAction(canReplyToMessage(actionMessage, messageRecord, shouldShowMessageRequest));
}
return builder.shouldShowCopyAction(!actionMessage && hasText)
.build();
}
static boolean canReplyToMessage(boolean actionMessage, @NonNull MessageRecord messageRecord, boolean isDisplayingMessageRequest) {
return !actionMessage &&
!messageRecord.isPending() &&
!messageRecord.isFailed() &&
!isDisplayingMessageRequest &&
messageRecord.isSecure();
}
static boolean isActionMessage(@NonNull MessageRecord messageRecord) {
return messageRecord.isGroupAction() ||
messageRecord.isCallLog() ||
messageRecord.isJoined() ||
messageRecord.isExpirationTimerUpdate() ||
messageRecord.isEndSession() ||
messageRecord.isIdentityUpdate() ||
messageRecord.isIdentityVerified() ||
messageRecord.isIdentityDefault();
}
private final static class Builder {
private boolean forward;
private boolean reply;
private boolean details;
private boolean saveAttachment;
private boolean resend;
private boolean copy;
@NonNull Builder shouldShowForwardAction(boolean forward) {
this.forward = forward;
return this;
}
@NonNull Builder shouldShowReplyAction(boolean reply) {
this.reply = reply;
return this;
}
@NonNull Builder shouldShowDetailsAction(boolean details) {
this.details = details;
return this;
}
@NonNull Builder shouldShowSaveAttachmentAction(boolean saveAttachment) {
this.saveAttachment = saveAttachment;
return this;
}
@NonNull Builder shouldShowResendAction(boolean resend) {
this.resend = resend;
return this;
}
@NonNull Builder shouldShowCopyAction(boolean copy) {
this.copy = copy;
return this;
}
@NonNull
MenuState build() {
return new MenuState(this);
}
}
}

View file

@ -5,6 +5,8 @@
android:layout_height="?attr/actionBarSize"
android:background="@color/action_mode_status_bar"
android:theme="@style/TextSecure.DarkActionBar.Conversation"
app:contentInsetStart="0dp"
app:contentInsetStartWithNavigation="48sp"
app:menu="@menu/conversation_reactions_long_press_menu"
app:navigationIcon="@drawable/ic_x_conversation">