Allow deletion of media through preview.

When viewing a media in the media preview, you can delete it by pressing
a delete button on the action bar. It will then ask you to confirm your
choice. If you confirm, it will delete the attachment from the database
and from disk. If it was the only attachment for that message, the
message itself will also be deleted.
This commit is contained in:
Greyson Parrelli
2018-03-13 18:24:42 -07:00
committed by Moxie Marlinspike
parent a8cf5b8efa
commit 0c768a24e4
7 changed files with 161 additions and 27 deletions

View File

@@ -20,6 +20,7 @@ import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
@@ -34,6 +35,7 @@ import android.support.v4.content.Loader;
import android.support.v4.util.Pair;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -46,9 +48,13 @@ import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.components.MediaView;
import org.thoughtcrime.securesms.components.viewpager.ExtendedOnPageChangedListener;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MediaDatabase.MediaRecord;
import org.thoughtcrime.securesms.database.loaders.PagingMediaLoader;
import org.thoughtcrime.securesms.mms.GlideApp;
@@ -251,6 +257,48 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
}
}
@SuppressLint("StaticFieldLeak")
private void deleteMedia() {
MediaItem mediaItem = getCurrentMediaItem();
if (mediaItem == null || mediaItem.attachment == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIconAttribute(R.attr.dialog_alert_icon);
builder.setTitle(R.string.MediaPreviewActivity_media_delete_confirmation_title);
builder.setMessage(R.string.MediaPreviewActivity_media_delete_confirmation_message);
builder.setCancelable(true);
builder.setPositiveButton(R.string.delete, (dialogInterface, which) -> {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
if (mediaItem.attachment == null) {
return null;
}
Context context = MediaPreviewActivity.this.getApplicationContext();
AttachmentId attachmentId = mediaItem.attachment.getAttachmentId();
long mmsId = mediaItem.attachment.getMmsId();
int attachmentCount = DatabaseFactory.getAttachmentDatabase(context)
.getAttachmentsForMessage(mmsId)
.size();
if (attachmentCount <= 1) {
DatabaseFactory.getMmsDatabase(context).delete(mmsId);
} else {
DatabaseFactory.getAttachmentDatabase(context).deleteAttachment(attachmentId);
}
return null;
}
}.execute();
finish();
});
builder.setNegativeButton(android.R.string.cancel, null);
builder.show();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
@@ -258,7 +306,11 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
menu.clear();
MenuInflater inflater = this.getMenuInflater();
inflater.inflate(R.menu.media_preview, menu);
if (conversationRecipient == null) menu.findItem(R.id.media_preview__overview).setVisible(false);
if (!isMediaInDb()) {
menu.findItem(R.id.media_preview__overview).setVisible(false);
menu.findItem(R.id.delete).setVisible(false);
}
return true;
}
@@ -271,12 +323,17 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
case R.id.media_preview__overview: showOverview(); return true;
case R.id.media_preview__forward: forward(); return true;
case R.id.save: saveToDisk(); return true;
case R.id.delete: deleteMedia(); return true;
case android.R.id.home: finish(); return true;
}
return false;
}
private boolean isMediaInDb() {
return conversationRecipient != null;
}
private @Nullable MediaItem getCurrentMediaItem() {
MediaItemAdapter adapter = (MediaItemAdapter)mediaPager.getAdapter();
@@ -402,7 +459,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
@Override
public MediaItem getMediaItemFor(int position) {
return new MediaItem(null, uri, mediaType, -1, true);
return new MediaItem(null, null, uri, mediaType, -1, true);
}
@Override
@@ -495,6 +552,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
if (mediaRecord.getAttachment().getDataUri() == null) throw new AssertionError();
return new MediaItem(address != null ? Recipient.from(context, address,true) : null,
mediaRecord.getAttachment(),
mediaRecord.getAttachment().getDataUri(),
mediaRecord.getContentType(),
mediaRecord.getDate(),
@@ -514,18 +572,26 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
}
private static class MediaItem {
private final @Nullable Recipient recipient;
private final @NonNull Uri uri;
private final @NonNull String type;
private final long date;
private final boolean outgoing;
private final @Nullable Recipient recipient;
private final @Nullable DatabaseAttachment attachment;
private final @NonNull Uri uri;
private final @NonNull String type;
private final long date;
private final boolean outgoing;
private MediaItem(@Nullable Recipient recipient, @NonNull Uri uri, @NonNull String type, long date, boolean outgoing) {
this.recipient = recipient;
this.uri = uri;
this.type = type;
this.date = date;
this.outgoing = outgoing;
private MediaItem(@Nullable Recipient recipient,
@Nullable DatabaseAttachment attachment,
@NonNull Uri uri,
@NonNull String type,
long date,
boolean outgoing)
{
this.recipient = recipient;
this.attachment = attachment;
this.uri = uri;
this.type = type;
this.date = date;
this.outgoing = outgoing;
}
}
@@ -533,5 +599,4 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
MediaItem getMediaItemFor(int position);
void pause(int position);
}
}