From 91a119393c87d9e84a2bc0a00468b96fd5d0c97d Mon Sep 17 00:00:00 2001 From: FeuRenard Date: Fri, 6 Apr 2018 15:01:05 +0200 Subject: [PATCH] Allow batch saving in media overview --- res/menu/media_overview_context.xml | 5 ++ res/values/strings.xml | 2 + .../securesms/MediaOverviewActivity.java | 53 +++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/res/menu/media_overview_context.xml b/res/menu/media_overview_context.xml index b3486221c3..d9f6b7d580 100644 --- a/res/menu/media_overview_context.xml +++ b/res/menu/media_overview_context.xml @@ -1,5 +1,10 @@ + + No Delete Please wait... + Save New message @@ -395,6 +396,7 @@ Deleting messages... Documents Select all + Collecting attachments... Signal call in progress diff --git a/src/org/thoughtcrime/securesms/MediaOverviewActivity.java b/src/org/thoughtcrime/securesms/MediaOverviewActivity.java index cda67fa16f..ace8539e29 100644 --- a/src/org/thoughtcrime/securesms/MediaOverviewActivity.java +++ b/src/org/thoughtcrime/securesms/MediaOverviewActivity.java @@ -16,6 +16,7 @@ */ package org.thoughtcrime.securesms; +import android.Manifest; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; @@ -46,6 +47,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.TextView; +import android.widget.Toast; import com.codewaves.stickyheadergrid.StickyHeaderGridLayoutManager; @@ -56,16 +58,20 @@ import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader; import org.thoughtcrime.securesms.database.loaders.BucketedThreadMediaLoader.BucketedThreadMedia; import org.thoughtcrime.securesms.database.loaders.ThreadMediaLoader; import org.thoughtcrime.securesms.mms.GlideApp; +import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.AttachmentUtil; import org.thoughtcrime.securesms.util.DynamicLanguage; import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme; import org.thoughtcrime.securesms.util.DynamicTheme; +import org.thoughtcrime.securesms.util.SaveAttachmentTask; import org.thoughtcrime.securesms.util.StickyHeaderDecoration; import org.thoughtcrime.securesms.util.ViewUtil; import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask; import java.util.Collection; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; /** @@ -317,6 +323,50 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity { } } + @SuppressWarnings("CodeBlock2Expr") + @SuppressLint({"InlinedApi","StaticFieldLeak"}) + private void handleSaveMedia(@NonNull Collection mediaRecords) { + final Context context = getContext(); + SaveAttachmentTask.showWarningDialog(context, (dialogInterface, which) -> { + Permissions.with(this) + .request(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE) + .ifNecessary() + .withPermanentDenialDialog(getString(R.string.MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied)) + .onAnyDenied(() -> Toast.makeText(getContext(), R.string.MediaPreviewActivity_unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show()) + .onAllGranted(() -> { + new ProgressDialogAsyncTask>(context, + R.string.MediaOverviewActivity_collecting_attachments, + R.string.please_wait) { + @Override + protected List doInBackground(Void... params) { + List attachments = new LinkedList<>(); + + for (MediaDatabase.MediaRecord mediaRecord : mediaRecords) { + if (mediaRecord.getAttachment().getDataUri() != null) { + attachments.add(new SaveAttachmentTask.Attachment(mediaRecord.getAttachment().getDataUri(), + mediaRecord.getContentType(), + mediaRecord.getDate(), + mediaRecord.getAttachment().getFileName())); + } + } + + return attachments; + } + + @Override + protected void onPostExecute(List attachments) { + super.onPostExecute(attachments); + SaveAttachmentTask saveTask = new SaveAttachmentTask(context, + attachments.size()); + saveTask.executeOnExecutor(THREAD_POOL_EXECUTOR, + attachments.toArray(new SaveAttachmentTask.Attachment[attachments.size()])); + } + }.execute(); + }) + .execute(); + }, mediaRecords.size()); + } + @SuppressLint("StaticFieldLeak") private void handleDeleteMedia(@NonNull Collection mediaRecords) { int recordCount = mediaRecords.size(); @@ -402,6 +452,9 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity { @Override public boolean onActionItemClicked(ActionMode mode, MenuItem menuItem) { switch (menuItem.getItemId()) { + case R.id.save: + handleSaveMedia(getListAdapter().getSelectedMedia()); + return true; case R.id.delete: handleDeleteMedia(getListAdapter().getSelectedMedia()); exitMultiSelect();