mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-27 20:24:32 +01:00
Add pre-alpha receive support for remote delete.
This commit is contained in:
@@ -110,6 +110,7 @@ import org.thoughtcrime.securesms.stickers.StickerPackPreviewActivity;
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.HtmlUtil;
|
||||
import org.thoughtcrime.securesms.util.RemoteDeleteUtil;
|
||||
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@@ -602,6 +603,14 @@ public class ConversationFragment extends Fragment
|
||||
}
|
||||
|
||||
private void handleDeleteMessages(final Set<MessageRecord> messageRecords) {
|
||||
if (FeatureFlags.remoteDelete()) {
|
||||
buildRemoteDeleteConfirmationDialog(messageRecords).show();
|
||||
} else {
|
||||
buildLegacyDeleteConfirmationDialog(messageRecords).show();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog.Builder buildLegacyDeleteConfirmationDialog(Set<MessageRecord> messageRecords) {
|
||||
int messagesCount = messageRecords.size();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
@@ -610,40 +619,87 @@ public class ConversationFragment extends Fragment
|
||||
builder.setMessage(getActivity().getResources().getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messagesCount, messagesCount));
|
||||
builder.setCancelable(true);
|
||||
|
||||
builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
new ProgressDialogAsyncTask<MessageRecord, Void, Void>(getActivity(),
|
||||
R.string.ConversationFragment_deleting,
|
||||
R.string.ConversationFragment_deleting_messages)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(MessageRecord... messageRecords) {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
boolean threadDeleted;
|
||||
builder.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||
new ProgressDialogAsyncTask<Void, Void, Void>(getActivity(),
|
||||
R.string.ConversationFragment_deleting,
|
||||
R.string.ConversationFragment_deleting_messages)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
boolean threadDeleted;
|
||||
|
||||
if (messageRecord.isMms()) {
|
||||
threadDeleted = DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
threadDeleted = DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
|
||||
if (threadDeleted) {
|
||||
threadId = -1;
|
||||
listener.setThreadId(threadId);
|
||||
}
|
||||
if (messageRecord.isMms()) {
|
||||
threadDeleted = DatabaseFactory.getMmsDatabase(getActivity()).delete(messageRecord.getId());
|
||||
} else {
|
||||
threadDeleted = DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
|
||||
return null;
|
||||
if (threadDeleted) {
|
||||
threadId = -1;
|
||||
listener.setThreadId(threadId);
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, messageRecords.toArray(new MessageRecord[messageRecords.size()]));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
});
|
||||
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.show();
|
||||
return builder;
|
||||
}
|
||||
|
||||
private AlertDialog.Builder buildRemoteDeleteConfirmationDialog(Set<MessageRecord> messageRecords) {
|
||||
Context context = requireActivity();
|
||||
int messagesCount = messageRecords.size();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
builder.setTitle(getActivity().getResources().getQuantityString(R.plurals.ConversationFragment_delete_selected_messages, messagesCount, messagesCount));
|
||||
builder.setCancelable(true);
|
||||
|
||||
builder.setPositiveButton(R.string.ConversationFragment_delete_for_me, (dialog, which) -> {
|
||||
new ProgressDialogAsyncTask<Void, Void, Void>(getActivity(),
|
||||
R.string.ConversationFragment_deleting,
|
||||
R.string.ConversationFragment_deleting_messages)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids) {
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
boolean threadDeleted;
|
||||
|
||||
if (messageRecord.isMms()) {
|
||||
threadDeleted = DatabaseFactory.getMmsDatabase(context).delete(messageRecord.getId());
|
||||
} else {
|
||||
threadDeleted = DatabaseFactory.getSmsDatabase(context).deleteMessage(messageRecord.getId());
|
||||
}
|
||||
|
||||
if (threadDeleted) {
|
||||
threadId = -1;
|
||||
listener.setThreadId(threadId);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
});
|
||||
|
||||
if (RemoteDeleteUtil.isValidSend(messageRecords, System.currentTimeMillis())) {
|
||||
builder.setNeutralButton(R.string.ConversationFragment_delete_for_everyone, (dialog, which) -> {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
for (MessageRecord message : messageRecords) {
|
||||
MessageSender.sendRemoteDelete(context, message.getId(), message.isMms());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
private void handleDisplayDetails(MessageRecord message) {
|
||||
Intent intent = new Intent(getActivity(), MessageDetailsActivity.class);
|
||||
intent.putExtra(MessageDetailsActivity.MESSAGE_ID_EXTRA, message.getId());
|
||||
@@ -1086,6 +1142,7 @@ public class ConversationFragment extends Fragment
|
||||
if (actionMode != null) return;
|
||||
|
||||
if (messageRecord.isSecure() &&
|
||||
!messageRecord.isRemoteDelete() &&
|
||||
!messageRecord.isUpdate() &&
|
||||
!recipient.get().isBlocked() &&
|
||||
!messageRequestViewModel.shouldShowMessageRequest() &&
|
||||
|
||||
@@ -36,6 +36,8 @@ import android.text.style.BackgroundColorSpan;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ClickableSpan;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.AttributeSet;
|
||||
@@ -519,7 +521,14 @@ public class ConversationItem extends LinearLayout implements BindableConversati
|
||||
bodyText.setFocusable(false);
|
||||
bodyText.setTextSize(TypedValue.COMPLEX_UNIT_SP, TextSecurePreferences.getMessageBodyTextSize(context));
|
||||
|
||||
if (isCaptionlessMms(messageRecord)) {
|
||||
if (messageRecord.isRemoteDelete()) {
|
||||
String deletedMessage = context.getString(R.string.ConversationItem_this_message_was_deleted);
|
||||
SpannableString italics = new SpannableString(deletedMessage);
|
||||
italics.setSpan(new RelativeSizeSpan(0.9f), 0, deletedMessage.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
italics.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, deletedMessage.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||
|
||||
bodyText.setText(italics);
|
||||
} else if (isCaptionlessMms(messageRecord)) {
|
||||
bodyText.setVisibility(View.GONE);
|
||||
} else {
|
||||
Spannable styledText = linkifyMessageBody(messageRecord.getDisplayBody(getContext()), batchSelected.isEmpty());
|
||||
|
||||
@@ -432,6 +432,7 @@ public final class ConversationReactionOverlay extends RelativeLayout {
|
||||
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());
|
||||
toolbar.getMenu().findItem(R.id.action_reply).setVisible(menuState.shouldShowReplyAction());
|
||||
}
|
||||
|
||||
private boolean handleToolbarItemClicked(@NonNull MenuItem menuItem) {
|
||||
|
||||
@@ -59,6 +59,7 @@ final class MenuState {
|
||||
boolean hasText = false;
|
||||
boolean sharedContact = false;
|
||||
boolean viewOnce = false;
|
||||
boolean remoteDelete = false;
|
||||
|
||||
for (MessageRecord messageRecord : messageRecords) {
|
||||
if (isActionMessage(messageRecord))
|
||||
@@ -77,6 +78,10 @@ final class MenuState {
|
||||
if (messageRecord.isViewOnce()) {
|
||||
viewOnce = true;
|
||||
}
|
||||
|
||||
if (messageRecord.isRemoteDelete()) {
|
||||
remoteDelete = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (messageRecords.size() > 1) {
|
||||
@@ -89,26 +94,27 @@ final class MenuState {
|
||||
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)
|
||||
.shouldShowSaveAttachmentAction(!actionMessage &&
|
||||
!viewOnce &&
|
||||
messageRecord.isMms() &&
|
||||
!messageRecord.isMmsNotification() &&
|
||||
((MediaMmsMessageRecord)messageRecord).containsMediaSlide() &&
|
||||
((MediaMmsMessageRecord)messageRecord).getSlideDeck().getStickerSlide() == null)
|
||||
.shouldShowForwardAction(!actionMessage && !sharedContact && !viewOnce && !remoteDelete)
|
||||
.shouldShowDetailsAction(!actionMessage)
|
||||
.shouldShowReplyAction(canReplyToMessage(actionMessage, messageRecord, shouldShowMessageRequest));
|
||||
}
|
||||
|
||||
return builder.shouldShowCopyAction(!actionMessage && hasText)
|
||||
return builder.shouldShowCopyAction(!actionMessage && !remoteDelete && hasText)
|
||||
.build();
|
||||
}
|
||||
|
||||
static boolean canReplyToMessage(boolean actionMessage, @NonNull MessageRecord messageRecord, boolean isDisplayingMessageRequest) {
|
||||
return !actionMessage &&
|
||||
!messageRecord.isPending() &&
|
||||
!messageRecord.isFailed() &&
|
||||
!isDisplayingMessageRequest &&
|
||||
return !actionMessage &&
|
||||
!messageRecord.isRemoteDelete() &&
|
||||
!messageRecord.isPending() &&
|
||||
!messageRecord.isFailed() &&
|
||||
!isDisplayingMessageRequest &&
|
||||
messageRecord.isSecure();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user