parent
10bfc8a753
commit
d8fa46c558
4 changed files with 186 additions and 85 deletions
|
@ -103,7 +103,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity;
|
import org.thoughtcrime.securesms.revealable.ViewOnceMessageActivity;
|
||||||
import org.thoughtcrime.securesms.revealable.ViewOnceUtil;
|
import org.thoughtcrime.securesms.revealable.ViewOnceUtil;
|
||||||
import org.thoughtcrime.securesms.sharing.ShareActivity;
|
|
||||||
import org.thoughtcrime.securesms.sms.MessageSender;
|
import org.thoughtcrime.securesms.sms.MessageSender;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||||
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
import org.thoughtcrime.securesms.stickers.StickerLocator;
|
||||||
|
@ -206,7 +205,7 @@ public class ConversationFragment extends Fragment
|
||||||
|
|
||||||
new ConversationItemSwipeCallback(
|
new ConversationItemSwipeCallback(
|
||||||
messageRecord -> actionMode == null &&
|
messageRecord -> actionMode == null &&
|
||||||
canReplyToMessage(isActionMessage(messageRecord), messageRecord, messageRequestViewModel.shouldShowMessageRequest()),
|
MenuState.canReplyToMessage(MenuState.isActionMessage(messageRecord), messageRecord, messageRequestViewModel.shouldShowMessageRequest()),
|
||||||
this::handleReplyMessage
|
this::handleReplyMessage
|
||||||
).attachToRecyclerView(list);
|
).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();
|
Set<MessageRecord> messageRecords = getListAdapter().getSelectedItems();
|
||||||
boolean actionMessage = false;
|
|
||||||
boolean hasText = false;
|
|
||||||
boolean sharedContact = false;
|
|
||||||
boolean viewOnce = false;
|
|
||||||
|
|
||||||
if (actionMode != null && messageRecords.size() == 0) {
|
if (actionMode != null && messageRecords.size() == 0) {
|
||||||
actionMode.finish();
|
actionMode.finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MessageRecord messageRecord : messageRecords) {
|
MenuState menuState = MenuState.getMenuState(messageRecords, messageRequestViewModel.shouldShowMessageRequest());
|
||||||
if (isActionMessage(messageRecord))
|
|
||||||
{
|
|
||||||
actionMessage = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (messageRecord.getBody().length() > 0) {
|
menu.findItem(R.id.menu_context_forward).setVisible(menuState.shouldShowForwardAction());
|
||||||
hasText = true;
|
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());
|
||||||
if (messageRecord.isMms() && !((MmsMessageRecord) messageRecord).getSharedContacts().isEmpty()) {
|
menu.findItem(R.id.menu_context_resend).setVisible(menuState.shouldShowResendAction());
|
||||||
sharedContact = true;
|
menu.findItem(R.id.menu_context_copy).setVisible(menuState.shouldShowCopyAction());
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConversationAdapter getListAdapter() {
|
private ConversationAdapter getListAdapter() {
|
||||||
|
|
|
@ -33,11 +33,11 @@ import org.thoughtcrime.securesms.components.MaskView;
|
||||||
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
import org.thoughtcrime.securesms.database.model.MessageRecord;
|
||||||
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
import org.thoughtcrime.securesms.database.model.ReactionRecord;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.util.MessageRecordUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public final class ConversationReactionOverlay extends RelativeLayout {
|
public final class ConversationReactionOverlay extends RelativeLayout {
|
||||||
|
@ -427,25 +427,11 @@ public final class ConversationReactionOverlay extends RelativeLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupToolbarMenuItems() {
|
private void setupToolbarMenuItems() {
|
||||||
toolbar.getMenu().findItem(R.id.action_copy).setVisible(shouldShowCopy());
|
MenuState menuState = MenuState.getMenuState(Collections.singleton(messageRecord), false);
|
||||||
toolbar.getMenu().findItem(R.id.action_download).setVisible(shouldShowDownload());
|
|
||||||
toolbar.getMenu().findItem(R.id.action_forward).setVisible(shouldShowForward());
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldShowCopy() {
|
toolbar.getMenu().findItem(R.id.action_copy).setVisible(menuState.shouldShowCopyAction());
|
||||||
return !MessageRecordUtil.hasSticker(messageRecord) &&
|
toolbar.getMenu().findItem(R.id.action_download).setVisible(menuState.shouldShowSaveAttachmentAction());
|
||||||
!MessageRecordUtil.isMediaMessage(messageRecord) &&
|
toolbar.getMenu().findItem(R.id.action_forward).setVisible(menuState.shouldShowForwardAction());
|
||||||
!MessageRecordUtil.hasSharedContact(messageRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldShowDownload() {
|
|
||||||
return MessageRecordUtil.isMediaMessage(messageRecord) ||
|
|
||||||
MessageRecordUtil.hasLocation(messageRecord);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private boolean shouldShowForward() {
|
|
||||||
return !MessageRecordUtil.hasSharedContact(messageRecord);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleToolbarItemClicked(@NonNull MenuItem menuItem) {
|
private boolean handleToolbarItemClicked(@NonNull MenuItem menuItem) {
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:background="@color/action_mode_status_bar"
|
android:background="@color/action_mode_status_bar"
|
||||||
android:theme="@style/TextSecure.DarkActionBar.Conversation"
|
android:theme="@style/TextSecure.DarkActionBar.Conversation"
|
||||||
|
app:contentInsetStart="0dp"
|
||||||
|
app:contentInsetStartWithNavigation="48sp"
|
||||||
app:menu="@menu/conversation_reactions_long_press_menu"
|
app:menu="@menu/conversation_reactions_long_press_menu"
|
||||||
app:navigationIcon="@drawable/ic_x_conversation">
|
app:navigationIcon="@drawable/ic_x_conversation">
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue